blob: 348e9a0ef0199203cd59aaeaa78d60eacdc30762 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
load("@rules_java//java:defs.bzl", "java_library")
load("@rules_cc//cc:defs.bzl", "cc_library")
load("pex_rules", "pex_library")
standard_proto_path = "heron/proto"
def _genproto_impl(ctx):
proto_src_deps = [src.proto_src for src in ctx.attr.deps]
inputs, outputs, arguments = [ctx.file.src] + proto_src_deps, [], ["--proto_path=."]
for src in proto_src_deps:
if src.path.startswith(standard_proto_path):
arguments.append("--proto_path=" + standard_proto_path)
break
if ctx.attr.gen_cc:
outputs += [ctx.outputs.cc_hdr, ctx.outputs.cc_src]
arguments.append("--cpp_out=" + ctx.configuration.genfiles_dir.path)
if ctx.attr.gen_java:
if ctx.outputs.java_src.path.endswith(".srcjar"):
srcjar = ctx.actions.declare_file(ctx.outputs.java_src.basename[:-6] + "jar")
else:
srcjar = ctx.outputs.java_src
outputs.append(srcjar)
arguments.append("--java_out=" + srcjar.path)
if ctx.attr.gen_py:
outputs.append(ctx.outputs.py_src)
arguments.append("--python_out=" + ctx.configuration.genfiles_dir.path)
ctx.actions.run(
mnemonic = "GenProto",
inputs = inputs,
outputs = outputs,
arguments = arguments + [ctx.file.src.path],
executable = ctx.executable._protoc,
)
# This is required because protoc only understands .jar extensions, but Bazel
# requires source JAR files end in .srcjar.
if ctx.attr.gen_java and srcjar != ctx.outputs.java_src:
ctx.actions.run(
mnemonic = "FixProtoSrcJar",
inputs = [srcjar],
outputs = [ctx.outputs.java_src],
arguments = [srcjar.path, ctx.outputs.java_src.path],
command = "cp $1 $2",
)
# Fixup the resulting outputs to keep the source-only .jar out of the result.
outputs.append(ctx.outputs.java_src)
outputs = [e for e in outputs if e != srcjar]
return struct(
files = set(outputs),
proto_src = ctx.file.src,
)
_genproto_attrs = {
"src": attr.label(
allow_files = [".proto"],
allow_single_file = True,
),
"deps": attr.label_list(
allow_files = False,
providers = ["proto_src"],
),
"_protoc": attr.label(
default = Label("//third_party/protobuf:protoc"),
executable = True,
),
"gen_cc": attr.bool(),
"gen_java": attr.bool(),
"gen_py": attr.bool(),
}
def _genproto_outputs(attrs):
outputs = {}
if attrs.gen_cc:
outputs.update(
{
"cc_hdr": "%{src}.pb.h",
"cc_src": "%{src}.pb.cc",
},
)
if attrs.gen_java:
outputs.update(
{
"java_src": "%{src}.srcjar",
},
)
if attrs.gen_py:
outputs.update(
{
"py_src": "%{src}_pb2.py",
},
)
return outputs
genproto = rule(
_genproto_impl,
attrs = _genproto_attrs,
output_to_genfiles = True,
outputs = _genproto_outputs,
)
def proto_library(
name,
src = None,
deps = [],
visibility = None,
gen_java = False,
gen_cc = False,
gen_py = False):
if not src:
if name.endswith("_proto"):
src = name[:-6] + ".proto"
else:
src = name + ".proto"
proto_pkg = genproto(
name = name,
src = src,
deps = deps,
gen_java = gen_java,
gen_cc = gen_cc,
gen_py = gen_py,
)
# TODO(shahms): These should probably not be separate libraries, but
# allowing upstream *_library and *_binary targets to depend on the
# proto_library() directly is a challenge. We'd also need a different
# workaround for the non-generated any.pb.{h,cc} from the upstream protocol
# buffer library.
if gen_java:
java_deps = ["@com_google_protobuf//:protobuf_java"]
for dep in deps:
java_deps.append(dep + "_java")
java_library(
name = name + "_java",
srcs = [proto_pkg.label()],
deps = java_deps,
visibility = visibility,
)
if gen_cc:
cc_deps = ["//third_party/protobuf:protobuf-cxx"]
for dep in deps:
cc_deps.append(dep + "_cc")
cc_library(
name = name + "_cc",
visibility = visibility,
hdrs = [proto_pkg.label()],
srcs = [proto_pkg.label()],
defines = ["GOOGLE_PROTOBUF_NO_RTTI"],
deps = cc_deps,
)
if gen_py:
py_deps = []
for dep in deps:
py_deps.append(dep + "_py")
pex_library(
name = name + "_py",
visibility = visibility,
srcs = [proto_pkg.label()],
deps = py_deps,
)