Эх сурвалжийг харах

Update bazel and build for javalite branch

Jisi Liu 8 жил өмнө
parent
commit
84bc5fc41e
2 өөрчлөгдсөн 142 нэмэгдсэн , 42 устгасан
  1. 40 12
      BUILD
  2. 102 30
      protobuf.bzl

+ 40 - 12
BUILD

@@ -2,6 +2,8 @@
 
 licenses(["notice"])
 
+exports_files(["LICENSE"])
+
 ################################################################################
 # Protobuf Runtime Library
 ################################################################################
@@ -12,7 +14,7 @@ COPTS = [
     "-Wwrite-strings",
     "-Woverloaded-virtual",
     "-Wno-sign-compare",
-    "-Wno-error=unused-function",
+    "-Wno-unused-function",
 ]
 
 config_setting(
@@ -25,11 +27,11 @@ config_setting(
 # Android builds do not need to link in a separate pthread library.
 LINK_OPTS = select({
     ":android": [],
-    "//conditions:default": ["-lpthread"],
+    "//conditions:default": ["-lpthread", "-lm"],
 })
 
 load(
-    "protobuf",
+    ":protobuf.bzl",
     "cc_proto_library",
     "py_proto_library",
     "internal_copied_filegroup",
@@ -179,6 +181,17 @@ cc_library(
     deps = [":protobuf_lite"],
 )
 
+# This provides just the header files for use in projects that need to build
+# shared libraries for dynamic loading. This target is available until Bazel
+# adds native support for such use cases.
+# TODO(keveman): Remove this target once the support gets added to Bazel.
+cc_library(
+    name = "protobuf_headers",
+    hdrs = glob(["src/**/*.h"]),
+    includes = ["src/"],
+    visibility = ["//visibility:public"],
+)
+
 objc_library(
     name = "protobuf_objc",
     hdrs = ["objectivec/GPBProtocolBuffers.h"],
@@ -541,12 +554,12 @@ java_library(
     srcs = glob([
         "java/util/src/main/java/com/google/protobuf/util/*.java",
     ]),
+    visibility = ["//visibility:public"],
     deps = [
         "protobuf_java",
         "//external:gson",
         "//external:guava",
     ],
-    visibility = ["//visibility:public"],
 )
 
 ################################################################################
@@ -567,12 +580,12 @@ py_library(
             "python/google/protobuf/internal/test_util.py",
         ],
     ),
-    srcs_version = "PY2AND3",
     imports = ["python"],
+    srcs_version = "PY2AND3",
 )
 
 cc_binary(
-    name = "internal/_api_implementation.so",
+    name = "python/google/protobuf/internal/_api_implementation.so",
     srcs = ["python/google/protobuf/internal/api_implementation.cc"],
     copts = COPTS + [
         "-DPYTHON_PROTO2_CPP_IMPL_V2",
@@ -586,7 +599,7 @@ cc_binary(
 )
 
 cc_binary(
-    name = "pyext/_message.so",
+    name = "python/google/protobuf/pyext/_message.so",
     srcs = glob([
         "python/google/protobuf/pyext/*.cc",
         "python/google/protobuf/pyext/*.h",
@@ -633,8 +646,8 @@ config_setting(
 internal_copied_filegroup(
     name = "protos_python",
     srcs = WELL_KNOWN_PROTOS,
-    strip_prefix = "src",
     dest = "python",
+    strip_prefix = "src",
 )
 
 # TODO(dzc): Remove this once py_proto_library can have labels in srcs, in
@@ -648,15 +661,15 @@ py_proto_library(
     data = select({
         "//conditions:default": [],
         ":use_fast_cpp_protos": [
-            ":internal/_api_implementation.so",
-            ":pyext/_message.so",
+            ":python/google/protobuf/internal/_api_implementation.so",
+            ":python/google/protobuf/pyext/_message.so",
         ],
     }),
     default_runtime = "",
     protoc = ":protoc",
     py_libs = [
         ":python_srcs",
-        "//external:six"
+        "//external:six",
     ],
     srcs_version = "PY2AND3",
     visibility = ["//visibility:public"],
@@ -670,13 +683,14 @@ py_proto_library(
 internal_copied_filegroup(
     name = "protos_python_test",
     srcs = LITE_TEST_PROTOS + TEST_PROTOS,
-    strip_prefix = "src",
     dest = "python",
+    strip_prefix = "src",
 )
 
 # TODO(dzc): Remove this once py_proto_library can have labels in srcs, in
 # which case we can simply add :protos_python_test in srcs.
 COPIED_LITE_TEST_PROTOS = ["python/" + s for s in RELATIVE_LITE_TEST_PROTOS]
+
 COPIED_TEST_PROTOS = ["python/" + s for s in RELATIVE_TEST_PROTOS]
 
 py_proto_library(
@@ -744,3 +758,17 @@ internal_protobuf_py_tests(
     ],
     deps = [":python_tests"],
 )
+
+proto_lang_toolchain(
+    name = "cc_toolchain",
+    command_line = "--cpp_out=$(OUT)",
+    runtime = ":protobuf",
+    visibility = ["//visibility:public"],
+)
+
+proto_lang_toolchain(
+    name = "java_toolchain",
+    command_line = "--java_out=$(OUT)",
+    runtime = ":protobuf_java",
+    visibility = ["//visibility:public"],
+)

+ 102 - 30
protobuf.bzl

@@ -1,12 +1,27 @@
-# -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED
-
 def _GetPath(ctx, path):
   if ctx.label.workspace_root:
     return ctx.label.workspace_root + '/' + path
   else:
     return path
 
+def _IsNewExternal(ctx):
+  # Bazel 0.4.4 and older have genfiles paths that look like:
+  #   bazel-out/local-fastbuild/genfiles/external/repo/foo
+  # After the exec root rearrangement, they look like:
+  #   ../repo/bazel-out/local-fastbuild/genfiles/foo
+  return ctx.label.workspace_root.startswith("../")
+
 def _GenDir(ctx):
+  if _IsNewExternal(ctx):
+    # We are using the fact that Bazel 0.4.4+ provides repository-relative paths
+    # for ctx.genfiles_dir.
+    return ctx.genfiles_dir.path + (
+        "/" + ctx.attr.includes[0] if ctx.attr.includes and ctx.attr.includes[0] else "")
+  # This means that we're either in the old version OR the new version in the local repo.
+  # Either way, appending the source path to the genfiles dir works.
+  return ctx.var["GENDIR"] + "/" + _SourceDir(ctx)
+
+def _SourceDir(ctx):
   if not ctx.attr.includes:
     return ctx.label.workspace_root
   if not ctx.attr.includes[0]:
@@ -15,14 +30,21 @@ def _GenDir(ctx):
     return _GetPath(ctx, ctx.attr.includes[0])
   return _GetPath(ctx, ctx.label.package + '/' + ctx.attr.includes[0])
 
-def _CcOuts(srcs, use_grpc_plugin=False):
-  ret = [s[:-len(".proto")] + ".pb.h" for s in srcs] + \
-        [s[:-len(".proto")] + ".pb.cc" for s in srcs]
+def _CcHdrs(srcs, use_grpc_plugin=False):
+  ret = [s[:-len(".proto")] + ".pb.h" for s in srcs]
   if use_grpc_plugin:
-    ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs] + \
-           [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs]
+    ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs]
   return ret
 
+def _CcSrcs(srcs, use_grpc_plugin=False):
+  ret = [s[:-len(".proto")] + ".pb.cc" for s in srcs]
+  if use_grpc_plugin:
+    ret += [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs]
+  return ret
+
+def _CcOuts(srcs, use_grpc_plugin=False):
+  return _CcHdrs(srcs, use_grpc_plugin) + _CcSrcs(srcs, use_grpc_plugin)
+
 def _PyOuts(srcs):
   return [s[:-len(".proto")] + "_pb2.py" for s in srcs]
 
@@ -46,9 +68,10 @@ def _proto_gen_impl(ctx):
   srcs = ctx.files.srcs
   deps = []
   deps += ctx.files.srcs
+  source_dir = _SourceDir(ctx)
   gen_dir = _GenDir(ctx)
-  if gen_dir:
-    import_flags = ["-I" + gen_dir, "-I" + ctx.var["GENDIR"] + "/" + gen_dir]
+  if source_dir:
+    import_flags = ["-I" + source_dir, "-I" + gen_dir]
   else:
     import_flags = ["-I."]
 
@@ -58,20 +81,33 @@ def _proto_gen_impl(ctx):
 
   args = []
   if ctx.attr.gen_cc:
-    args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
+    args += ["--cpp_out=" + gen_dir]
   if ctx.attr.gen_py:
-    args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
-
-  if ctx.executable.grpc_cpp_plugin:
-    args += ["--plugin=protoc-gen-grpc=" + ctx.executable.grpc_cpp_plugin.path]
-    args += ["--grpc_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
+    args += ["--python_out=" + gen_dir]
+
+  inputs = srcs + deps
+  if ctx.executable.plugin:
+    plugin = ctx.executable.plugin
+    lang = ctx.attr.plugin_language
+    if not lang and plugin.basename.startswith('protoc-gen-'):
+      lang = plugin.basename[len('protoc-gen-'):]
+    if not lang:
+      fail("cannot infer the target language of plugin", "plugin_language")
+
+    outdir = gen_dir
+    if ctx.attr.plugin_options:
+      outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir
+    args += ["--plugin=protoc-gen-%s=%s" % (lang, plugin.path)]
+    args += ["--%s_out=%s" % (lang, outdir)]
+    inputs += [plugin]
 
   if args:
     ctx.action(
-        inputs=srcs + deps,
+        inputs=inputs,
         outputs=ctx.outputs.outs,
         arguments=args + import_flags + [s.path for s in srcs],
         executable=ctx.executable.protoc,
+        mnemonic="ProtoCompile",
     )
 
   return struct(
@@ -82,7 +118,7 @@ def _proto_gen_impl(ctx):
       ),
   )
 
-_proto_gen = rule(
+proto_gen = rule(
     attrs = {
         "srcs": attr.label_list(allow_files = True),
         "deps": attr.label_list(providers = ["proto"]),
@@ -93,11 +129,13 @@ _proto_gen = rule(
             single_file = True,
             mandatory = True,
         ),
-        "grpc_cpp_plugin": attr.label(
+        "plugin": attr.label(
             cfg = "host",
+            allow_files = True,
             executable = True,
-            single_file = True,
         ),
+        "plugin_language": attr.string(),
+        "plugin_options": attr.string_list(),
         "gen_cc": attr.bool(),
         "gen_py": attr.bool(),
         "outs": attr.output_list(),
@@ -105,6 +143,26 @@ _proto_gen = rule(
     output_to_genfiles = True,
     implementation = _proto_gen_impl,
 )
+"""Generates codes from Protocol Buffers definitions.
+
+This rule helps you to implement Skylark macros specific to the target
+language. You should prefer more specific `cc_proto_library `,
+`py_proto_library` and others unless you are adding such wrapper macros.
+
+Args:
+  srcs: Protocol Buffers definition files (.proto) to run the protocol compiler
+    against.
+  deps: a list of dependency labels; must be other proto libraries.
+  includes: a list of include paths to .proto files.
+  protoc: the label of the protocol compiler to generate the sources.
+  plugin: the label of the protocol compiler plugin to be passed to the protocol
+    compiler.
+  plugin_language: the language of the generated sources
+  plugin_options: a list of options to be passed to the plugin
+  gen_cc: generates C++ sources in addition to the ones from the plugin.
+  gen_py: generates Python sources in addition to the ones from the plugin.
+  outs: a list of labels of the expected outputs from the protocol compiler.
+"""
 
 def cc_proto_library(
         name,
@@ -150,7 +208,7 @@ def cc_proto_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(
+    proto_gen(
         name=name + "_genproto",
         srcs=srcs,
         deps=[s + "_genproto" for s in deps],
@@ -168,15 +226,18 @@ def cc_proto_library(
   if use_grpc_plugin:
     grpc_cpp_plugin = "//external:grpc_cpp_plugin"
 
-  outs = _CcOuts(srcs, use_grpc_plugin)
+  gen_srcs = _CcSrcs(srcs, use_grpc_plugin)
+  gen_hdrs = _CcHdrs(srcs, use_grpc_plugin)
+  outs = gen_srcs + gen_hdrs
 
-  _proto_gen(
+  proto_gen(
       name=name + "_genproto",
       srcs=srcs,
       deps=[s + "_genproto" for s in deps],
       includes=includes,
       protoc=protoc,
-      grpc_cpp_plugin=grpc_cpp_plugin,
+      plugin=grpc_cpp_plugin,
+      plugin_language="grpc",
       gen_cc=1,
       outs=outs,
       visibility=["//visibility:public"],
@@ -189,12 +250,12 @@ def cc_proto_library(
 
   native.cc_library(
       name=name,
-      srcs=outs,
+      srcs=gen_srcs,
+      hdrs=gen_hdrs,
       deps=cc_libs + deps,
       includes=includes,
       **kargs)
 
-
 def internal_gen_well_known_protos_java(srcs):
   """Bazel rule to generate the gen_well_known_protos_java genrule
 
@@ -202,10 +263,11 @@ def internal_gen_well_known_protos_java(srcs):
     srcs: the well known protos
   """
   root = Label("%s//protobuf_java" % (REPOSITORY_NAME)).workspace_root
+  pkg = PACKAGE_NAME + "/" if PACKAGE_NAME else ""
   if root == "":
-    include = " -Isrc "
+    include = " -I%ssrc " % pkg
   else:
-    include = " -I%s/src " % root
+    include = " -I%s/%ssrc " % (root, pkg)
   native.genrule(
     name = "gen_well_known_protos_java",
     srcs = srcs,
@@ -218,7 +280,6 @@ def internal_gen_well_known_protos_java(srcs):
     tools = [":protoc"],
   )
 
-
 def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs):
   """Macro to copy files to a different directory and then create a filegroup.
 
@@ -248,7 +309,6 @@ def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs):
       srcs = outs,
       **kwargs)
 
-
 def py_proto_library(
         name,
         srcs=[],
@@ -258,6 +318,7 @@ def py_proto_library(
         include=None,
         default_runtime="//:protobuf_python",
         protoc="//:protoc",
+        use_grpc_plugin=False,
         **kargs):
   """Bazel rule to create a Python protobuf library from proto source files
 
@@ -277,6 +338,8 @@ def py_proto_library(
     default_runtime: the implicitly default runtime which will be depended on by
         the generated py_library target.
     protoc: the label of the protocol compiler to generate the sources.
+    use_grpc_plugin: a flag to indicate whether to call the Python C++ plugin
+        when processing the proto files.
     **kargs: other keyword arguments that are passed to cc_library.
 
   """
@@ -286,7 +349,14 @@ def py_proto_library(
   if include != None:
     includes = [include]
 
-  _proto_gen(
+  grpc_python_plugin = None
+  if use_grpc_plugin:
+    grpc_python_plugin = "//external:grpc_python_plugin"
+    # Note: Generated grpc code depends on Python grpc module. This dependency
+    # is not explicitly listed in py_libs. Instead, host system is assumed to
+    # have grpc installed.
+
+  proto_gen(
       name=name + "_genproto",
       srcs=srcs,
       deps=[s + "_genproto" for s in deps],
@@ -295,6 +365,8 @@ def py_proto_library(
       gen_py=1,
       outs=outs,
       visibility=["//visibility:public"],
+      plugin=grpc_python_plugin,
+      plugin_language="grpc"
   )
 
   if default_runtime and not default_runtime in py_libs + deps: