blob: 12d3edb947565e462290fea0436f3a9b9396b888 [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(
Vladimir Moskvaa86e6d82016-09-09 13:21:35 +0200193 cfg = "host",
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(
Vladimir Moskvaa86e6d82016-09-09 13:21:35 +0200199 cfg = "host",
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))
331 args.add("--java_out", srcjar)
332
333 descriptors = depset(
334 transitive = [dep.transitive_descriptor_sets for dep in deps],
Paul Yangcecba292018-12-14 16:05:03 -0800335 )
Yannicf0cb9cd2020-02-13 22:04:14 +0100336 args.add_joined(
337 "--descriptor_set_in",
338 descriptors,
339 join_with = ctx.configuration.host_path_separator,
340 )
341
342 for dep in deps:
343 if "." == dep.proto_source_root:
344 args.add_all([src.path for src in dep.direct_sources])
345 else:
346 source_root = dep.proto_source_root
347 offset = len(source_root) + 1 # + '/'.
348 args.add_all([src.path[offset:] for src in dep.direct_sources])
349
350 ctx.actions.run(
351 executable = ctx.executable._protoc,
352 inputs = descriptors,
353 outputs = [srcjar],
354 arguments = [args],
Adam Yi88f3ef72020-07-29 16:49:52 +1000355 use_default_shell_env = True,
Yannicf0cb9cd2020-02-13 22:04:14 +0100356 )
357
358 return [
359 DefaultInfo(
360 files = depset([srcjar]),
361 ),
362 ]
363
364internal_gen_well_known_protos_java = rule(
365 implementation = _internal_gen_well_known_protos_java_impl,
366 attrs = {
367 "deps": attr.label_list(
368 mandatory = True,
369 providers = [ProtoInfo],
370 ),
371 "_protoc": attr.label(
372 executable = True,
373 cfg = "host",
374 default = "@com_google_protobuf//:protoc",
375 ),
376 },
377)
Steven Parkesea188662016-02-25 07:53:19 -0800378
David Z. Chen02cd45c2016-05-20 16:49:04 -0700379def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs):
Paul Yangcecba292018-12-14 16:05:03 -0800380 """Macro to copy files to a different directory and then create a filegroup.
David Z. Chen02cd45c2016-05-20 16:49:04 -0700381
Paul Yangcecba292018-12-14 16:05:03 -0800382 This is used by the //:protobuf_python py_proto_library target to work around
383 an issue caused by Python source files that are part of the same Python
384 package being in separate directories.
David Z. Chen02cd45c2016-05-20 16:49:04 -0700385
Paul Yangcecba292018-12-14 16:05:03 -0800386 Args:
387 srcs: The source files to copy and add to the filegroup.
388 strip_prefix: Path to the root of the files to copy.
389 dest: The directory to copy the source files into.
390 **kwargs: extra arguments that will be passesd to the filegroup.
391 """
392 outs = [_RelativeOutputPath(s, strip_prefix, dest) for s in srcs]
David Z. Chen02cd45c2016-05-20 16:49:04 -0700393
Paul Yangcecba292018-12-14 16:05:03 -0800394 native.genrule(
395 name = name + "_genrule",
396 srcs = srcs,
397 outs = outs,
398 cmd = " && ".join(
399 ["cp $(location %s) $(location %s)" %
400 (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs],
401 ),
402 )
David Z. Chen02cd45c2016-05-20 16:49:04 -0700403
Paul Yangcecba292018-12-14 16:05:03 -0800404 native.filegroup(
405 name = name,
406 srcs = outs,
407 **kwargs
408 )
David Z. Chen02cd45c2016-05-20 16:49:04 -0700409
Jisi Liu993fb702015-10-19 17:19:49 -0700410def py_proto_library(
411 name,
Paul Yangcecba292018-12-14 16:05:03 -0800412 srcs = [],
413 deps = [],
414 py_libs = [],
415 py_extra_srcs = [],
416 include = None,
417 default_runtime = "@com_google_protobuf//:protobuf_python",
418 protoc = "@com_google_protobuf//:protoc",
419 use_grpc_plugin = False,
Jisi Liu993fb702015-10-19 17:19:49 -0700420 **kargs):
Paul Yangcecba292018-12-14 16:05:03 -0800421 """Bazel rule to create a Python protobuf library from proto source files
Jisi Liu7b948cc2015-10-19 17:56:27 -0700422
Paul Yangcecba292018-12-14 16:05:03 -0800423 NOTE: the rule is only an internal workaround to generate protos. The
424 interface may change and the rule may be removed when bazel has introduced
425 the native rule.
Jisi Liud4bef7d2015-11-02 12:24:32 -0800426
Paul Yangcecba292018-12-14 16:05:03 -0800427 Args:
428 name: the name of the py_proto_library.
429 srcs: the .proto files of the py_proto_library.
430 deps: a list of dependency labels; must be py_proto_library.
431 py_libs: a list of other py_library targets depended by the generated
432 py_library.
433 py_extra_srcs: extra source files that will be added to the output
434 py_library. This attribute is used for internal bootstrapping.
435 include: a string indicating the include path of the .proto files.
436 default_runtime: the implicitly default runtime which will be depended on by
437 the generated py_library target.
438 protoc: the label of the protocol compiler to generate the sources.
439 use_grpc_plugin: a flag to indicate whether to call the Python C++ plugin
440 when processing the proto files.
Leo12236c62020-05-04 11:23:44 +0900441 **kargs: other keyword arguments that are passed to py_library.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700442
Paul Yangcecba292018-12-14 16:05:03 -0800443 """
444 outs = _PyOuts(srcs, use_grpc_plugin)
Jisi Liu53a56be2015-10-20 15:18:20 -0700445
Paul Yangcecba292018-12-14 16:05:03 -0800446 includes = []
447 if include != None:
448 includes = [include]
Jisi Liu53a56be2015-10-20 15:18:20 -0700449
Paul Yangcecba292018-12-14 16:05:03 -0800450 grpc_python_plugin = None
451 if use_grpc_plugin:
452 grpc_python_plugin = "//external:grpc_python_plugin"
453 # Note: Generated grpc code depends on Python grpc module. This dependency
454 # is not explicitly listed in py_libs. Instead, host system is assumed to
455 # have grpc installed.
Wiktor Tomczak0fa31b22016-11-22 20:18:46 +0100456
Paul Yangcecba292018-12-14 16:05:03 -0800457 proto_gen(
458 name = name + "_genproto",
459 srcs = srcs,
460 deps = [s + "_genproto" for s in deps],
461 includes = includes,
462 protoc = protoc,
463 gen_py = 1,
464 outs = outs,
465 visibility = ["//visibility:public"],
466 plugin = grpc_python_plugin,
467 plugin_language = "grpc",
468 )
Jisi Liu993fb702015-10-19 17:19:49 -0700469
Paul Yangcecba292018-12-14 16:05:03 -0800470 if default_runtime and not default_runtime in py_libs + deps:
471 py_libs = py_libs + [default_runtime]
Yannic Bonenbergerd2d6ff52019-08-06 21:12:06 +0200472 py_library(
Paul Yangcecba292018-12-14 16:05:03 -0800473 name = name,
474 srcs = outs + py_extra_srcs,
475 deps = py_libs + deps,
476 imports = includes,
477 **kargs
478 )
Jisi Liu993fb702015-10-19 17:19:49 -0700479
480def internal_protobuf_py_tests(
Paul Yangcecba292018-12-14 16:05:03 -0800481 name,
482 modules = [],
483 **kargs):
484 """Bazel rules to create batch tests for protobuf internal.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700485
Paul Yangcecba292018-12-14 16:05:03 -0800486 Args:
487 name: the name of the rule.
488 modules: a list of modules for tests. The macro will create a py_test for
489 each of the parameter with the source "google/protobuf/%s.py"
490 kargs: extra parameters that will be passed into the py_test.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700491
Paul Yangcecba292018-12-14 16:05:03 -0800492 """
493 for m in modules:
494 s = "python/google/protobuf/internal/%s.py" % m
Yannic Bonenbergerd2d6ff52019-08-06 21:12:06 +0200495 py_test(
Paul Yangcecba292018-12-14 16:05:03 -0800496 name = "py_%s" % m,
497 srcs = [s],
498 main = s,
499 **kargs
500 )
Fahrzin Hemmati35119e32017-11-28 14:24:53 -0800501
502def check_protobuf_required_bazel_version():
Paul Yangcecba292018-12-14 16:05:03 -0800503 """For WORKSPACE files, to check the installed version of bazel.
Fahrzin Hemmati35119e32017-11-28 14:24:53 -0800504
Paul Yangcecba292018-12-14 16:05:03 -0800505 This ensures bazel supports our approach to proto_library() depending on a
506 copied filegroup. (Fixed in bazel 0.5.4)
507 """
508 versions.check(minimum_bazel_version = "0.5.4")