From 84bc5fc41ee81fd8421a807ee725ec08fc85a475 Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Thu, 9 Mar 2017 12:29:42 -0800 Subject: Update bazel and build for javalite branch --- BUILD | 52 +++++++++++++++++------ protobuf.bzl | 132 +++++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 142 insertions(+), 42 deletions(-) diff --git a/BUILD b/BUILD index 0941d8c4..913cc364 100644 --- a/BUILD +++ b/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"], +) diff --git a/protobuf.bzl b/protobuf.bzl index 0e8c2e23..73c396d5 100644 --- a/protobuf.bzl +++ b/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: -- cgit v1.2.3