blob: 9716128121573afe74b5e25b77e7748e20c97600 [file] [log] [blame]
Roger Chen7492b562018-10-29 21:58:47 -07001load("@bazel_skylib//lib:versions.bzl", "versions")
Yannic Bonenbergerd2d6ff52019-08-06 21:12:06 +02002load("@rules_cc//cc:defs.bzl", "cc_library")
Yannic Bonenberger723a85f2020-02-15 13:26:56 +01003load("@rules_proto//proto:defs.bzl", "ProtoInfo")
Yannic Bonenbergerd2d6ff52019-08-06 21:12:06 +02004load("@rules_python//python:defs.bzl", "py_library", "py_test")
Jingwen Chenb2a19082018-01-12 18:42:22 -05005
Damien Martin-Guillerez76547e52016-01-15 14:01:37 +01006def _GetPath(ctx, path):
Paul Yangcecba292018-12-14 16:05:03 -08007 if ctx.label.workspace_root:
8 return ctx.label.workspace_root + "/" + path
9 else:
10 return path
Damien Martin-Guillerez76547e52016-01-15 14:01:37 +010011
Kristina Chodorow4e7ecde2017-01-25 14:10:56 -050012def _IsNewExternal(ctx):
Paul Yangcecba292018-12-14 16:05:03 -080013 # Bazel 0.4.4 and older have genfiles paths that look like:
14 # bazel-out/local-fastbuild/genfiles/external/repo/foo
15 # After the exec root rearrangement, they look like:
16 # ../repo/bazel-out/local-fastbuild/genfiles/foo
17 return ctx.label.workspace_root.startswith("../")
Kristina Chodorow4e7ecde2017-01-25 14:10:56 -050018
Jisi Liu993fb702015-10-19 17:19:49 -070019def _GenDir(ctx):
Paul Yangcecba292018-12-14 16:05:03 -080020 if _IsNewExternal(ctx):
21 # We are using the fact that Bazel 0.4.4+ provides repository-relative paths
22 # for ctx.genfiles_dir.
23 return ctx.genfiles_dir.path + (
24 "/" + ctx.attr.includes[0] if ctx.attr.includes and ctx.attr.includes[0] else ""
Fahrzin Hemmatid1403e52018-03-16 13:23:34 -070025 )
Jisi Liu39362b32015-10-14 17:12:11 -070026
Paul Yangcecba292018-12-14 16:05:03 -080027 # This means that we're either in the old version OR the new version in the local repo.
28 # Either way, appending the source path to the genfiles dir works.
29 return ctx.var["GENDIR"] + "/" + _SourceDir(ctx)
30
31def _SourceDir(ctx):
32 if not ctx.attr.includes:
33 return ctx.label.workspace_root
34 if not ctx.attr.includes[0]:
35 return _GetPath(ctx, ctx.label.package)
36 if not ctx.label.package:
37 return _GetPath(ctx, ctx.attr.includes[0])
38 return _GetPath(ctx, ctx.label.package + "/" + ctx.attr.includes[0])
39
40def _CcHdrs(srcs, use_grpc_plugin = False):
41 ret = [s[:-len(".proto")] + ".pb.h" for s in srcs]
42 if use_grpc_plugin:
43 ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs]
44 return ret
45
46def _CcSrcs(srcs, use_grpc_plugin = False):
47 ret = [s[:-len(".proto")] + ".pb.cc" for s in srcs]
48 if use_grpc_plugin:
49 ret += [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs]
50 return ret
51
52def _CcOuts(srcs, use_grpc_plugin = False):
53 return _CcHdrs(srcs, use_grpc_plugin) + _CcSrcs(srcs, use_grpc_plugin)
54
55def _PyOuts(srcs, use_grpc_plugin = False):
56 ret = [s[:-len(".proto")] + "_pb2.py" for s in srcs]
57 if use_grpc_plugin:
58 ret += [s[:-len(".proto")] + "_pb2_grpc.py" for s in srcs]
59 return ret
60
61def _RelativeOutputPath(path, include, dest = ""):
62 if include == None:
63 return path
64
65 if not path.startswith(include):
66 fail("Include path %s isn't part of the path %s." % (include, path))
67
68 if include and include[-1] != "/":
69 include = include + "/"
70 if dest and dest[-1] != "/":
71 dest = dest + "/"
72
73 path = path[len(include):]
74 return dest + path
75
76def _proto_gen_impl(ctx):
77 """General implementation for generating protos"""
78 srcs = ctx.files.srcs
Harvey Tuch7cf3f7a2020-01-24 13:47:15 -050079 deps = depset(direct=ctx.files.srcs)
Paul Yangcecba292018-12-14 16:05:03 -080080 source_dir = _SourceDir(ctx)
81 gen_dir = _GenDir(ctx).rstrip("/")
82 if source_dir:
Harvey Tuch7cf3f7a2020-01-24 13:47:15 -050083 import_flags = depset(direct=["-I" + source_dir, "-I" + gen_dir])
Paul Yangcecba292018-12-14 16:05:03 -080084 else:
Harvey Tuch7cf3f7a2020-01-24 13:47:15 -050085 import_flags = depset(direct=["-I."])
Paul Yangcecba292018-12-14 16:05:03 -080086
87 for dep in ctx.attr.deps:
Harvey Tuche492e5a2020-05-26 14:27:56 -040088 if type(dep.proto.import_flags) == "list":
89 import_flags = depset(transitive=[import_flags], direct=dep.proto.import_flags)
90 else:
91 import_flags = depset(transitive=[import_flags, dep.proto.import_flags])
92 if type(dep.proto.deps) == "list":
93 deps = depset(transitive=[deps], direct=dep.proto.deps)
94 else:
95 deps = depset(transitive=[deps, dep.proto.deps])
Paul Yangcecba292018-12-14 16:05:03 -080096
97 if not ctx.attr.gen_cc and not ctx.attr.gen_py and not ctx.executable.plugin:
98 return struct(
99 proto = struct(
100 srcs = srcs,
101 import_flags = import_flags,
102 deps = deps,
103 ),
104 )
105
106 for src in srcs:
107 args = []
108
109 in_gen_dir = src.root.path == gen_dir
110 if in_gen_dir:
111 import_flags_real = []
Harvey Tuch7cf3f7a2020-01-24 13:47:15 -0500112 for f in import_flags.to_list():
Paul Yangcecba292018-12-14 16:05:03 -0800113 path = f.replace("-I", "")
114 import_flags_real.append("-I$(realpath -s %s)" % path)
115
116 outs = []
117 use_grpc_plugin = (ctx.attr.plugin_language == "grpc" and ctx.attr.plugin)
118 path_tpl = "$(realpath %s)" if in_gen_dir else "%s"
119 if ctx.attr.gen_cc:
120 args += [("--cpp_out=" + path_tpl) % gen_dir]
121 outs.extend(_CcOuts([src.basename], use_grpc_plugin = use_grpc_plugin))
122 if ctx.attr.gen_py:
123 args += [("--python_out=" + path_tpl) % gen_dir]
124 outs.extend(_PyOuts([src.basename], use_grpc_plugin = use_grpc_plugin))
125
126 outs = [ctx.actions.declare_file(out, sibling = src) for out in outs]
Harvey Tuch7cf3f7a2020-01-24 13:47:15 -0500127 inputs = [src] + deps.to_list()
Benjamin Peterson6153f802019-06-03 08:56:33 -0700128 tools = [ctx.executable.protoc]
Paul Yangcecba292018-12-14 16:05:03 -0800129 if ctx.executable.plugin:
130 plugin = ctx.executable.plugin
131 lang = ctx.attr.plugin_language
132 if not lang and plugin.basename.startswith("protoc-gen-"):
133 lang = plugin.basename[len("protoc-gen-"):]
134 if not lang:
135 fail("cannot infer the target language of plugin", "plugin_language")
136
137 outdir = "." if in_gen_dir else gen_dir
138
139 if ctx.attr.plugin_options:
140 outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir
141 args += [("--plugin=protoc-gen-%s=" + path_tpl) % (lang, plugin.path)]
142 args += ["--%s_out=%s" % (lang, outdir)]
Benjamin Peterson6153f802019-06-03 08:56:33 -0700143 tools.append(plugin)
Paul Yangcecba292018-12-14 16:05:03 -0800144
145 if not in_gen_dir:
146 ctx.actions.run(
147 inputs = inputs,
Benjamin Peterson6153f802019-06-03 08:56:33 -0700148 tools = tools,
Paul Yangcecba292018-12-14 16:05:03 -0800149 outputs = outs,
Harvey Tuch7cf3f7a2020-01-24 13:47:15 -0500150 arguments = args + import_flags.to_list() + [src.path],
Paul Yangcecba292018-12-14 16:05:03 -0800151 executable = ctx.executable.protoc,
152 mnemonic = "ProtoCompile",
153 use_default_shell_env = True,
154 )
155 else:
156 for out in outs:
157 orig_command = " ".join(
158 ["$(realpath %s)" % ctx.executable.protoc.path] + args +
159 import_flags_real + ["-I.", src.basename],
160 )
161 command = ";".join([
162 'CMD="%s"' % orig_command,
163 "cd %s" % src.dirname,
164 "${CMD}",
165 "cd -",
166 ])
167 generated_out = "/".join([gen_dir, out.basename])
168 if generated_out != out.path:
169 command += ";mv %s %s" % (generated_out, out.path)
170 ctx.actions.run_shell(
Keith Smileyca3ead72019-05-21 17:31:34 -0700171 inputs = inputs,
Paul Yangcecba292018-12-14 16:05:03 -0800172 outputs = [out],
173 command = command,
174 mnemonic = "ProtoCompile",
Benjamin Peterson6153f802019-06-03 08:56:33 -0700175 tools = tools,
Paul Yangcecba292018-12-14 16:05:03 -0800176 use_default_shell_env = True,
177 )
178
179 return struct(
180 proto = struct(
181 srcs = srcs,
182 import_flags = import_flags,
183 deps = deps,
184 ),
185 )
Jisi Liu39362b32015-10-14 17:12:11 -0700186
Yuki Yugui Sonoda5977fb02016-06-01 16:23:15 +0900187proto_gen = rule(
Jisi Liu39362b32015-10-14 17:12:11 -0700188 attrs = {
Jisi Liuee8131a2015-10-14 17:20:05 -0700189 "srcs": attr.label_list(allow_files = True),
190 "deps": attr.label_list(providers = ["proto"]),
Jisi Liu53a56be2015-10-20 15:18:20 -0700191 "includes": attr.string_list(),
Jisi Liuee8131a2015-10-14 17:20:05 -0700192 "protoc": attr.label(
Charles Mitaf1fe79d2021-05-19 20:11:13 +0200193 cfg = "exec",
Jisi Liuee8131a2015-10-14 17:20:05 -0700194 executable = True,
James Juddd5f0dac2018-08-14 21:55:35 -0600195 allow_single_file = True,
Jisi Liuee8131a2015-10-14 17:20:05 -0700196 mandatory = True,
197 ),
Yuki Yugui Sonoda5977fb02016-06-01 16:23:15 +0900198 "plugin": attr.label(
Charles Mitaf1fe79d2021-05-19 20:11:13 +0200199 cfg = "exec",
Yuki Yugui Sonoda5977fb02016-06-01 16:23:15 +0900200 allow_files = True,
Manjunath Kudlurf0966a72016-02-22 14:30:43 -0800201 executable = True,
Manjunath Kudlurf0966a72016-02-22 14:30:43 -0800202 ),
Yuki Yugui Sonoda5977fb02016-06-01 16:23:15 +0900203 "plugin_language": attr.string(),
204 "plugin_options": attr.string_list(),
Jisi Liuee8131a2015-10-14 17:20:05 -0700205 "gen_cc": attr.bool(),
206 "gen_py": attr.bool(),
207 "outs": attr.output_list(),
208 },
209 output_to_genfiles = True,
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700210 implementation = _proto_gen_impl,
Jisi Liu39362b32015-10-14 17:12:11 -0700211)
Yuki Yugui Sonoda5977fb02016-06-01 16:23:15 +0900212"""Generates codes from Protocol Buffers definitions.
213
214This rule helps you to implement Skylark macros specific to the target
215language. You should prefer more specific `cc_proto_library `,
216`py_proto_library` and others unless you are adding such wrapper macros.
217
218Args:
219 srcs: Protocol Buffers definition files (.proto) to run the protocol compiler
220 against.
221 deps: a list of dependency labels; must be other proto libraries.
222 includes: a list of include paths to .proto files.
223 protoc: the label of the protocol compiler to generate the sources.
224 plugin: the label of the protocol compiler plugin to be passed to the protocol
225 compiler.
226 plugin_language: the language of the generated sources
227 plugin_options: a list of options to be passed to the plugin
Kristina Chodorow4e7ecde2017-01-25 14:10:56 -0500228 gen_cc: generates C++ sources in addition to the ones from the plugin.
Yuki Yugui Sonoda5977fb02016-06-01 16:23:15 +0900229 gen_py: generates Python sources in addition to the ones from the plugin.
230 outs: a list of labels of the expected outputs from the protocol compiler.
231"""
Jisi Liu39362b32015-10-14 17:12:11 -0700232
Yannic Bonenberger723a85f2020-02-15 13:26:56 +0100233def _adapt_proto_library_impl(ctx):
234 deps = [dep[ProtoInfo] for dep in ctx.attr.deps]
235
236 srcs = [src for dep in deps for src in dep.direct_sources]
237 return struct(
238 proto = struct(
239 srcs = srcs,
240 import_flags = ["-I{}".format(path) for dep in deps for path in dep.transitive_proto_path.to_list()],
241 deps = srcs,
242 ),
243 )
244
245adapt_proto_library = rule(
246 implementation = _adapt_proto_library_impl,
247 attrs = {
248 "deps": attr.label_list(
249 mandatory = True,
250 providers = [ProtoInfo],
251 ),
252 },
253 doc = "Adapts `proto_library` from `@rules_proto` to be used with `{cc,py}_proto_library` from this file.",
254)
255
Jisi Liu39362b32015-10-14 17:12:11 -0700256def cc_proto_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700257 name,
Paul Yangcecba292018-12-14 16:05:03 -0800258 srcs = [],
259 deps = [],
260 cc_libs = [],
261 include = None,
262 protoc = "@com_google_protobuf//:protoc",
Paul Yangcecba292018-12-14 16:05:03 -0800263 use_grpc_plugin = False,
264 default_runtime = "@com_google_protobuf//:protobuf",
Jisi Liu125a91b2015-10-14 17:37:39 -0700265 **kargs):
Paul Yangcecba292018-12-14 16:05:03 -0800266 """Bazel rule to create a C++ protobuf library from proto source files
Jisi Liu3101e732015-10-16 12:46:26 -0700267
Paul Yangcecba292018-12-14 16:05:03 -0800268 NOTE: the rule is only an internal workaround to generate protos. The
269 interface may change and the rule may be removed when bazel has introduced
270 the native rule.
Jisi Liud4bef7d2015-11-02 12:24:32 -0800271
Paul Yangcecba292018-12-14 16:05:03 -0800272 Args:
273 name: the name of the cc_proto_library.
274 srcs: the .proto files of the cc_proto_library.
275 deps: a list of dependency labels; must be cc_proto_library.
276 cc_libs: a list of other cc_library targets depended by the generated
277 cc_library.
278 include: a string indicating the include path of the .proto files.
279 protoc: the label of the protocol compiler to generate the sources.
Paul Yangcecba292018-12-14 16:05:03 -0800280 use_grpc_plugin: a flag to indicate whether to call the grpc C++ plugin
281 when processing the proto files.
282 default_runtime: the implicitly default runtime which will be depended on by
283 the generated cc_library target.
284 **kargs: other keyword arguments that are passed to cc_library.
Paul Yangcecba292018-12-14 16:05:03 -0800285 """
Jisi Liu39362b32015-10-14 17:12:11 -0700286
Paul Yangcecba292018-12-14 16:05:03 -0800287 includes = []
288 if include != None:
289 includes = [include]
Jisi Liu53a56be2015-10-20 15:18:20 -0700290
Paul Yangcecba292018-12-14 16:05:03 -0800291 grpc_cpp_plugin = None
292 if use_grpc_plugin:
293 grpc_cpp_plugin = "//external:grpc_cpp_plugin"
294
295 gen_srcs = _CcSrcs(srcs, use_grpc_plugin)
296 gen_hdrs = _CcHdrs(srcs, use_grpc_plugin)
297 outs = gen_srcs + gen_hdrs
298
Yuki Yugui Sonoda5977fb02016-06-01 16:23:15 +0900299 proto_gen(
Paul Yangcecba292018-12-14 16:05:03 -0800300 name = name + "_genproto",
301 srcs = srcs,
302 deps = [s + "_genproto" for s in deps],
303 includes = includes,
304 protoc = protoc,
305 plugin = grpc_cpp_plugin,
306 plugin_language = "grpc",
307 gen_cc = 1,
308 outs = outs,
309 visibility = ["//visibility:public"],
Jisi Liu39362b32015-10-14 17:12:11 -0700310 )
Paul Yangcecba292018-12-14 16:05:03 -0800311
312 if default_runtime and not default_runtime in cc_libs:
313 cc_libs = cc_libs + [default_runtime]
314 if use_grpc_plugin:
315 cc_libs = cc_libs + ["//external:grpc_lib"]
Yannic Bonenbergerbf0c69e2019-07-26 13:14:19 +0200316 cc_library(
Paul Yangcecba292018-12-14 16:05:03 -0800317 name = name,
318 srcs = gen_srcs,
319 hdrs = gen_hdrs,
320 deps = cc_libs + deps,
321 includes = includes,
322 **kargs
323 )
Jisi Liu993fb702015-10-19 17:19:49 -0700324
Yannicf0cb9cd2020-02-13 22:04:14 +0100325def _internal_gen_well_known_protos_java_impl(ctx):
326 args = ctx.actions.args()
Steven Parkesea188662016-02-25 07:53:19 -0800327
Yannicf0cb9cd2020-02-13 22:04:14 +0100328 deps = [d[ProtoInfo] for d in ctx.attr.deps]
329
330 srcjar = ctx.actions.declare_file("{}.srcjar".format(ctx.attr.name))
Derek Perezbc45f922021-04-20 11:36:32 -0700331 if ctx.attr.javalite:
332 java_out = "lite:%s" % srcjar.path
333 else:
334 java_out = srcjar
335
336 args.add("--java_out", java_out)
Yannicf0cb9cd2020-02-13 22:04:14 +0100337
338 descriptors = depset(
339 transitive = [dep.transitive_descriptor_sets for dep in deps],
Paul Yangcecba292018-12-14 16:05:03 -0800340 )
Yannicf0cb9cd2020-02-13 22:04:14 +0100341 args.add_joined(
342 "--descriptor_set_in",
343 descriptors,
344 join_with = ctx.configuration.host_path_separator,
345 )
346
347 for dep in deps:
348 if "." == dep.proto_source_root:
349 args.add_all([src.path for src in dep.direct_sources])
350 else:
351 source_root = dep.proto_source_root
352 offset = len(source_root) + 1 # + '/'.
353 args.add_all([src.path[offset:] for src in dep.direct_sources])
354
355 ctx.actions.run(
356 executable = ctx.executable._protoc,
357 inputs = descriptors,
358 outputs = [srcjar],
359 arguments = [args],
Adam Yi88f3ef72020-07-29 16:49:52 +1000360 use_default_shell_env = True,
Yannicf0cb9cd2020-02-13 22:04:14 +0100361 )
362
363 return [
364 DefaultInfo(
365 files = depset([srcjar]),
366 ),
367 ]
368
369internal_gen_well_known_protos_java = rule(
370 implementation = _internal_gen_well_known_protos_java_impl,
371 attrs = {
372 "deps": attr.label_list(
373 mandatory = True,
374 providers = [ProtoInfo],
375 ),
Derek Perezbc45f922021-04-20 11:36:32 -0700376 "javalite": attr.bool(
377 default = False,
378 ),
Yannicf0cb9cd2020-02-13 22:04:14 +0100379 "_protoc": attr.label(
380 executable = True,
Charles Mitaf1fe79d2021-05-19 20:11:13 +0200381 cfg = "exec",
Yannicf0cb9cd2020-02-13 22:04:14 +0100382 default = "@com_google_protobuf//:protoc",
383 ),
384 },
385)
Steven Parkesea188662016-02-25 07:53:19 -0800386
David Z. Chen02cd45c2016-05-20 16:49:04 -0700387def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs):
Paul Yangcecba292018-12-14 16:05:03 -0800388 """Macro to copy files to a different directory and then create a filegroup.
David Z. Chen02cd45c2016-05-20 16:49:04 -0700389
Paul Yangcecba292018-12-14 16:05:03 -0800390 This is used by the //:protobuf_python py_proto_library target to work around
391 an issue caused by Python source files that are part of the same Python
392 package being in separate directories.
David Z. Chen02cd45c2016-05-20 16:49:04 -0700393
Paul Yangcecba292018-12-14 16:05:03 -0800394 Args:
395 srcs: The source files to copy and add to the filegroup.
396 strip_prefix: Path to the root of the files to copy.
397 dest: The directory to copy the source files into.
398 **kwargs: extra arguments that will be passesd to the filegroup.
399 """
400 outs = [_RelativeOutputPath(s, strip_prefix, dest) for s in srcs]
David Z. Chen02cd45c2016-05-20 16:49:04 -0700401
Paul Yangcecba292018-12-14 16:05:03 -0800402 native.genrule(
403 name = name + "_genrule",
404 srcs = srcs,
405 outs = outs,
406 cmd = " && ".join(
407 ["cp $(location %s) $(location %s)" %
408 (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs],
409 ),
410 )
David Z. Chen02cd45c2016-05-20 16:49:04 -0700411
Paul Yangcecba292018-12-14 16:05:03 -0800412 native.filegroup(
413 name = name,
414 srcs = outs,
415 **kwargs
416 )
David Z. Chen02cd45c2016-05-20 16:49:04 -0700417
Jisi Liu993fb702015-10-19 17:19:49 -0700418def py_proto_library(
419 name,
Paul Yangcecba292018-12-14 16:05:03 -0800420 srcs = [],
421 deps = [],
422 py_libs = [],
423 py_extra_srcs = [],
424 include = None,
425 default_runtime = "@com_google_protobuf//:protobuf_python",
426 protoc = "@com_google_protobuf//:protoc",
427 use_grpc_plugin = False,
Jisi Liu993fb702015-10-19 17:19:49 -0700428 **kargs):
Paul Yangcecba292018-12-14 16:05:03 -0800429 """Bazel rule to create a Python protobuf library from proto source files
Jisi Liu7b948cc2015-10-19 17:56:27 -0700430
Paul Yangcecba292018-12-14 16:05:03 -0800431 NOTE: the rule is only an internal workaround to generate protos. The
432 interface may change and the rule may be removed when bazel has introduced
433 the native rule.
Jisi Liud4bef7d2015-11-02 12:24:32 -0800434
Paul Yangcecba292018-12-14 16:05:03 -0800435 Args:
436 name: the name of the py_proto_library.
437 srcs: the .proto files of the py_proto_library.
438 deps: a list of dependency labels; must be py_proto_library.
439 py_libs: a list of other py_library targets depended by the generated
440 py_library.
441 py_extra_srcs: extra source files that will be added to the output
442 py_library. This attribute is used for internal bootstrapping.
443 include: a string indicating the include path of the .proto files.
444 default_runtime: the implicitly default runtime which will be depended on by
445 the generated py_library target.
446 protoc: the label of the protocol compiler to generate the sources.
447 use_grpc_plugin: a flag to indicate whether to call the Python C++ plugin
448 when processing the proto files.
Leo12236c62020-05-04 11:23:44 +0900449 **kargs: other keyword arguments that are passed to py_library.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700450
Paul Yangcecba292018-12-14 16:05:03 -0800451 """
452 outs = _PyOuts(srcs, use_grpc_plugin)
Jisi Liu53a56be2015-10-20 15:18:20 -0700453
Paul Yangcecba292018-12-14 16:05:03 -0800454 includes = []
455 if include != None:
456 includes = [include]
Jisi Liu53a56be2015-10-20 15:18:20 -0700457
Paul Yangcecba292018-12-14 16:05:03 -0800458 grpc_python_plugin = None
459 if use_grpc_plugin:
460 grpc_python_plugin = "//external:grpc_python_plugin"
461 # Note: Generated grpc code depends on Python grpc module. This dependency
462 # is not explicitly listed in py_libs. Instead, host system is assumed to
463 # have grpc installed.
Wiktor Tomczak0fa31b22016-11-22 20:18:46 +0100464
Paul Yangcecba292018-12-14 16:05:03 -0800465 proto_gen(
466 name = name + "_genproto",
467 srcs = srcs,
468 deps = [s + "_genproto" for s in deps],
469 includes = includes,
470 protoc = protoc,
471 gen_py = 1,
472 outs = outs,
473 visibility = ["//visibility:public"],
474 plugin = grpc_python_plugin,
475 plugin_language = "grpc",
476 )
Jisi Liu993fb702015-10-19 17:19:49 -0700477
Paul Yangcecba292018-12-14 16:05:03 -0800478 if default_runtime and not default_runtime in py_libs + deps:
479 py_libs = py_libs + [default_runtime]
Yannic Bonenbergerd2d6ff52019-08-06 21:12:06 +0200480 py_library(
Paul Yangcecba292018-12-14 16:05:03 -0800481 name = name,
482 srcs = outs + py_extra_srcs,
483 deps = py_libs + deps,
484 imports = includes,
485 **kargs
486 )
Jisi Liu993fb702015-10-19 17:19:49 -0700487
488def internal_protobuf_py_tests(
Paul Yangcecba292018-12-14 16:05:03 -0800489 name,
490 modules = [],
491 **kargs):
492 """Bazel rules to create batch tests for protobuf internal.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700493
Paul Yangcecba292018-12-14 16:05:03 -0800494 Args:
495 name: the name of the rule.
496 modules: a list of modules for tests. The macro will create a py_test for
497 each of the parameter with the source "google/protobuf/%s.py"
498 kargs: extra parameters that will be passed into the py_test.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700499
Paul Yangcecba292018-12-14 16:05:03 -0800500 """
501 for m in modules:
502 s = "python/google/protobuf/internal/%s.py" % m
Yannic Bonenbergerd2d6ff52019-08-06 21:12:06 +0200503 py_test(
Paul Yangcecba292018-12-14 16:05:03 -0800504 name = "py_%s" % m,
505 srcs = [s],
506 main = s,
507 **kargs
508 )
Fahrzin Hemmati35119e32017-11-28 14:24:53 -0800509
510def check_protobuf_required_bazel_version():
Paul Yangcecba292018-12-14 16:05:03 -0800511 """For WORKSPACE files, to check the installed version of bazel.
Fahrzin Hemmati35119e32017-11-28 14:24:53 -0800512
Paul Yangcecba292018-12-14 16:05:03 -0800513 This ensures bazel supports our approach to proto_library() depending on a
514 copied filegroup. (Fixed in bazel 0.5.4)
515 """
516 versions.check(minimum_bazel_version = "0.5.4")