diff options
-rw-r--r-- | BUILD | 49 | ||||
-rw-r--r-- | protobuf.bzl | 127 |
2 files changed, 151 insertions, 25 deletions
@@ -18,6 +18,8 @@ COPTS = [ # Bazel should provide portable link_opts for pthread. LINK_OPTS = ["-lpthread"] +load("protobuf", "cc_proto_library") + cc_library( name = "protobuf_lite", srcs = [ @@ -140,6 +142,14 @@ WELL_KNOWN_PROTOS = [ "google/protobuf/wrappers.proto", ] +cc_proto_library( + name = "cc_wkt_protos", + srcs = ["src/" + s for s in WELL_KNOWN_PROTOS], + internal_bootstrap_hack = 1, + include = "src", + cc_libs = [":protobuf"], +) + ################################################################################ # Protocol Buffers Compiler ################################################################################ @@ -258,23 +268,22 @@ cc_binary( ################################################################################ genrule( name = "generate_java_descriptor_proto", - tools = [":protoc"], - srcs = [ "src/google/protobuf/descriptor.proto", ], - outs = [ "com/google/protobuf/DescriptorProtos.java" ], + srcs = ["src/google/protobuf/descriptor.proto"], + outs = ["com/google/protobuf/DescriptorProtos.java"], cmd = "$(location :protoc) --java_out=$(@D)/../../.. $<", + tools = [":protoc"], ) java_library( name = "java_proto", - visibility = ["//visibility:public"], srcs = glob([ - "java/src/main/java/com/google/protobuf/*.java" + "java/src/main/java/com/google/protobuf/*.java", ]) + [ - ":generate_java_descriptor_proto", - ] + ":generate_java_descriptor_proto", + ], + visibility = ["//visibility:public"], ) - ################################################################################ # Tests ################################################################################ @@ -328,22 +337,11 @@ TEST_PROTOS = [ "google/protobuf/util/json_format_proto3.proto", ] -PROTOS = LITE_TEST_PROTOS + TEST_PROTOS - -INPUTS = PROTOS + WELL_KNOWN_PROTOS - -OUTPUTS = ["src/" + x[:-5] + "pb.h" for x in PROTOS] + \ - ["src/" + x[:-5] + "pb.cc" for x in PROTOS] - -genrule( - name = "gen_test_protos", - srcs = ["src/" + x for x in INPUTS], - outs = OUTPUTS, - cmd = - "$(location :protoc) --cpp_out=$(@D)/src" + - "".join([" -I" + x + "=$(location src/" + x + ")" for x in INPUTS]) + - "".join([" $(location src/" + x + ")" for x in PROTOS]), - tools = [":protoc"], +cc_proto_library( + name = "cc_test_protos", + srcs = ["src/" + s for s in (LITE_TEST_PROTOS + TEST_PROTOS)], + include = "src", + deps = [":cc_wkt_protos"], ) COMMON_TEST_SRCS = [ @@ -372,7 +370,7 @@ cc_binary( cc_test( name = "protobuf_test", - srcs = OUTPUTS + COMMON_TEST_SRCS + [ + srcs = COMMON_TEST_SRCS + [ # AUTOGEN(test_srcs) "src/google/protobuf/any_test.cc", "src/google/protobuf/arena_unittest.cc", @@ -449,6 +447,7 @@ cc_test( deps = [ ":protobuf", ":protoc_lib", + ":cc_test_protos", "//external:gtest_main", ], ) diff --git a/protobuf.bzl b/protobuf.bzl new file mode 100644 index 00000000..79dabd02 --- /dev/null +++ b/protobuf.bzl @@ -0,0 +1,127 @@ +# -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED + +def _gen_dir(ctx): + if not ctx.attr.include: + return ctx.label.package + if not ctx.label.package: + return ctx.attr.include + return ctx.label.package + '/' + ctx.attr.include + +def _cc_outs(srcs): + return [s[:-len(".proto")] + ".pb.h" for s in srcs] + \ + [s[:-len(".proto")] + ".pb.cc" for s in srcs] + +def _py_outs(srcs): + return [s[:-len(".proto")] + "_pb2.py" for s in srcs] + +def _proto_gen_impl(ctx): + """General implementation for generating protos""" + srcs = ctx.files.srcs + deps = [] + deps += ctx.files.srcs + gen_dir = _gen_dir(ctx) + import_flags = ["-I" + gen_dir] + for dep in ctx.attr.deps: + import_flags += dep.proto.import_flags + deps += dep.proto.deps + + args = [] + if ctx.attr.gen_cc: + args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir] + if ctx.attr.gen_py: + args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir] + + if args: + ctx.action( + inputs=srcs + deps, + outputs=ctx.outputs.outs, + arguments=args + import_flags + [s.path for s in srcs], + executable=ctx.executable.protoc, + ) + + return struct( + proto=struct( + srcs=srcs, + import_flags=import_flags, + deps=deps, + ), + ) + +_proto_gen = rule( + attrs = { + "srcs": attr.label_list(allow_files = True), + "deps": attr.label_list(providers = ["proto"]), + "include": attr.string(), + "protoc": attr.label( + executable = True, + single_file = True, + mandatory = True, + ), + "gen_cc": attr.bool(), + "gen_py": attr.bool(), + "outs": attr.output_list(), + }, + output_to_genfiles = True, + implementation = _proto_gen_impl, +) + +def cc_proto_library( + name, + srcs=[], + deps=[], + cc_libs=[], + include="", + protoc=":protoc", + internal_bootstrap_hack=False, + **kargs): + """Bazel rule to create a C++ protobuf library from proto source files + + Args: + name: the name of the cc_proto_library. + srcs: the .proto files of the cc_proto_library. + deps: a list of dependency labels; must be cc_proto_library. + cc_libs: a list of other cc_library targets depended by the generated + cc_library. + include: a string indicating the include path of the .proto files. + protoc: the label of the protocol compiler to generate the sources. + internal_bootstrap_hack: a flag indicate the cc_proto_library is used only + for bootstraping. When it is set to True, no files will be generated. + The rule will simply be a provider for .proto files, so that other + cc_proto_library can depend on it. + **kargs: other keyword arguments that are passed to cc_library. + + """ + + if internal_bootstrap_hack: + # For pre-checked-in generated files, we add the internal_bootstrap_hack + # which will skip the codegen action. + _proto_gen( + name=name + "_genproto", + srcs=srcs, + deps=[s + "_genproto" for s in deps], + include=include, + protoc=protoc, + ) + # An empty cc_library to make rule dependency consistent. + native.cc_library( + name=name, + **kargs) + return + + outs = _cc_outs(srcs) + _proto_gen( + name=name + "_genproto", + srcs=srcs, + deps=[s + "_genproto" for s in deps], + include=include, + protoc=protoc, + gen_cc=1, + outs=outs, + ) + + native.cc_library( + name=name, + srcs=outs, + deps=cc_libs + deps, + includes=[include], + **kargs) |