aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Adam Cozzette <acozzette@gmail.com>2018-07-02 15:08:12 -0700
committerGravatar GitHub <noreply@github.com>2018-07-02 15:08:12 -0700
commit2c30fa71e7af67ef42a3c71651ee5baedfb2fbfe (patch)
tree65a6d02ffda0b50f8f9536c82647a227a3f10eb1
parent59e04d80cca9b86a97190df0cbab2d93125537fb (diff)
parent55962db9b78d0751e861e43660bde1f82eb911e7 (diff)
Merge pull request #3981 from fahhem/patch-3
Handle srcs in generated files by cd'ing in and out
-rw-r--r--BUILD29
-rw-r--r--protobuf.bzl110
2 files changed, 107 insertions, 32 deletions
diff --git a/BUILD b/BUILD
index ce3bd034..7f7ec759 100644
--- a/BUILD
+++ b/BUILD
@@ -940,3 +940,32 @@ objc_library(
non_arc_srcs = OBJC_SRCS,
visibility = ["//visibility:public"],
)
+
+################################################################################
+# Test generated proto support
+################################################################################
+
+genrule(
+ name = "generated_protos",
+ srcs = ["src/google/protobuf/unittest_import.proto"],
+ outs = ["unittest_gen.proto"],
+ cmd = "cat $(SRCS) | sed 's|google/|src/google/|' > $(OUTS)"
+)
+
+proto_library(
+ name = "generated_protos_proto",
+ srcs = [
+ "unittest_gen.proto",
+ "src/google/protobuf/unittest_import_public.proto",
+ ],
+)
+
+py_proto_library(
+ name = "generated_protos_py",
+ srcs = [
+ "unittest_gen.proto",
+ "src/google/protobuf/unittest_import_public.proto",
+ ],
+ default_runtime = "",
+ protoc = ":protoc",
+)
diff --git a/protobuf.bzl b/protobuf.bzl
index 8bbd0564..67d61d7b 100644
--- a/protobuf.bzl
+++ b/protobuf.bzl
@@ -74,7 +74,7 @@ def _proto_gen_impl(ctx):
deps = []
deps += ctx.files.srcs
source_dir = _SourceDir(ctx)
- gen_dir = _GenDir(ctx)
+ gen_dir = _GenDir(ctx).rstrip('/')
if source_dir:
import_flags = ["-I" + source_dir, "-I" + gen_dir]
else:
@@ -84,37 +84,83 @@ def _proto_gen_impl(ctx):
import_flags += dep.proto.import_flags
deps += dep.proto.deps
- args = []
- if ctx.attr.gen_cc:
- args += ["--cpp_out=" + gen_dir]
- if ctx.attr.gen_py:
- 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=inputs,
- outputs=ctx.outputs.outs,
- arguments=args + import_flags + [s.path for s in srcs],
- executable=ctx.executable.protoc,
- mnemonic="ProtoCompile",
- use_default_shell_env=True,
- )
+ if not ctx.attr.gen_cc and not ctx.attr.gen_py and not ctx.executable.plugin:
+ return struct(
+ proto=struct(
+ srcs=srcs,
+ import_flags=import_flags,
+ deps=deps,
+ ),
+ )
+
+ for src in srcs:
+ args = []
+
+ in_gen_dir = src.root.path == gen_dir
+ if in_gen_dir:
+ import_flags_real = []
+ for f in depset(import_flags):
+ path = f.replace('-I', '')
+ import_flags_real.append('-I$(realpath -s %s)' % path)
+
+ outs = []
+ use_grpc_plugin = (ctx.attr.plugin_language == "grpc" and ctx.attr.plugin)
+ path_tpl = "$(realpath %s)" if in_gen_dir else "%s"
+ if ctx.attr.gen_cc:
+ args += [("--cpp_out=" + path_tpl) % gen_dir]
+ outs.extend(_CcOuts([src.basename], use_grpc_plugin=use_grpc_plugin))
+ if ctx.attr.gen_py:
+ args += [("--python_out=" + path_tpl) % gen_dir]
+ outs.extend(_PyOuts([src.basename], use_grpc_plugin=use_grpc_plugin))
+
+ outs = [ctx.actions.declare_file(out, sibling=src) for out in outs]
+ inputs = [src] + 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 = "." if in_gen_dir else gen_dir
+
+ if ctx.attr.plugin_options:
+ outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir
+ args += [("--plugin=protoc-gen-%s=" + path_tpl) % (lang, plugin.path)]
+ args += ["--%s_out=%s" % (lang, outdir)]
+ inputs += [plugin]
+
+ if not in_gen_dir:
+ ctx.action(
+ inputs=inputs,
+ outputs=outs,
+ arguments=args + import_flags + [src.path],
+ executable=ctx.executable.protoc,
+ mnemonic="ProtoCompile",
+ use_default_shell_env=True,
+ )
+ else:
+ for out in outs:
+ orig_command = " ".join(
+ ["$(realpath %s)" % ctx.executable.protoc.path] + args +
+ import_flags_real + ["-I.", src.basename])
+ command = ";".join([
+ 'CMD="%s"' % orig_command,
+ "cd %s" % src.dirname,
+ "${CMD}",
+ "cd -",
+ ])
+ generated_out = '/'.join([gen_dir, out.basename])
+ if generated_out != out.path:
+ command += ";mv %s %s" % (generated_out, out.path)
+ ctx.action(
+ inputs=inputs + [ctx.executable.protoc],
+ outputs=[out],
+ command=command,
+ mnemonic="ProtoCompile",
+ use_default_shell_env=True,
+ )
return struct(
proto=struct(