فهرست منبع

Extract protoc action into .bzl for cc.

This is needed to support python bazel build.
Jisi Liu 10 سال پیش
والد
کامیت
39362b35b2
2فایلهای تغییر یافته به همراه131 افزوده شده و 25 حذف شده
  1. 24 25
      BUILD
  2. 107 0
      protobuf.bzl

+ 24 - 25
BUILD

@@ -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,
+    prefix = "src",
+    deps = ":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)],
+    prefix = "src",
+    proto_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",
     ],
 )

+ 107 - 0
protobuf.bzl

@@ -0,0 +1,107 @@
+# -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED
+
+
+def _gen_dir(ctx):
+  if not ctx.attr.prefix:
+    return ctx.label.package
+  if not ctx.label.package:
+    return ctx.attr.prefix
+  return ctx.label.package + '/' + ctx.attr.prefix
+
+def CcOuts(srcs):
+  return [s[:-len(".proto")] +  ".pb.h" for s in srcs] + \
+         [s[:-len(".proto")] +  ".pb.cc" for s in srcs]
+
+def PyOuts(srcs):
+  return [s[:-len(".proto")] +  "_pb2.py" for s in srcs]
+
+def _proto_srcs_impl(ctx):
+  """General implementation for calculating proto srcs"""
+  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_srcs = rule(
+    implementation = _proto_srcs_impl,
+    output_to_genfiles = True,
+    attrs = {
+      "srcs": attr.label_list(allow_files=True),
+      "deps": attr.label_list(providers=["proto"]),
+      "prefix": attr.string(),
+      "protoc": attr.label(executable=True, single_file=True, mandatory=True),
+      "gen_cc": attr.bool(),
+      "gen_py": attr.bool(),
+      "outs": attr.output_list()
+    }
+)
+
+def cc_proto_library(
+    name,
+    srcs=[],
+    protoc=":protoc",
+    internal_bootstrap_hack=False,
+    prefix="",
+    proto_deps=[],
+    deps=[],
+    **kargs):
+
+  if internal_bootstrap_hack:
+    # For pre-checked-in generated files, we add the internal_bootstrap_hack
+    # which will skip the codegen action.
+    _proto_srcs(
+        name = name + "_genproto",
+        srcs = srcs,
+        deps = [s + "_genproto" for s in proto_deps],
+        prefix = prefix,
+        protoc = protoc,
+    )
+    # An empty cc_library to make rule dependency consistent.
+    native.cc_library(
+        name = name,
+        **kargs)
+    return
+
+  outs = CcOuts(srcs)
+  _proto_srcs(
+      name = name + "_genproto",
+      srcs = srcs,
+      deps = [s + "_genproto" for s in proto_deps],
+      prefix = prefix,
+      protoc = protoc,
+      gen_cc = 1,
+      outs = outs,
+  )
+
+  native.cc_library(
+      name = name,
+      srcs = outs,
+      deps = deps + proto_deps,
+      includes = [prefix],
+      **kargs)