blob: fbcae0b3242f81dfc9cb58ce090714dafa36935b [file] [log] [blame]
Jisi Liu39362b32015-10-14 17:12:11 -07001# -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED
2
Damien Martin-Guillerez76547e52016-01-15 14:01:37 +01003def _GetPath(ctx, path):
4 if ctx.label.workspace_root:
5 return ctx.label.workspace_root + '/' + path
6 else:
7 return path
8
Jisi Liu993fb702015-10-19 17:19:49 -07009def _GenDir(ctx):
Jisi Liu53a56be2015-10-20 15:18:20 -070010 if not ctx.attr.includes:
Damien Martin-Guillerez76547e52016-01-15 14:01:37 +010011 return ctx.label.workspace_root
Jisi Liu53a56be2015-10-20 15:18:20 -070012 if not ctx.attr.includes[0]:
Damien Martin-Guillerez76547e52016-01-15 14:01:37 +010013 return _GetPath(ctx, ctx.label.package)
Jisi Liu39362b32015-10-14 17:12:11 -070014 if not ctx.label.package:
Damien Martin-Guillerez76547e52016-01-15 14:01:37 +010015 return _GetPath(ctx, ctx.attr.includes[0])
16 return _GetPath(ctx, ctx.label.package + '/' + ctx.attr.includes[0])
Jisi Liu39362b32015-10-14 17:12:11 -070017
Manjunath Kudlurf5c73632016-02-25 08:50:50 -080018def _CcOuts(srcs, use_grpc_plugin=False):
19 ret = [s[:-len(".proto")] + ".pb.h" for s in srcs] + \
20 [s[:-len(".proto")] + ".pb.cc" for s in srcs]
21 if use_grpc_plugin:
22 ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs] + \
23 [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs]
24 return ret
Jisi Liu39362b32015-10-14 17:12:11 -070025
Jisi Liu993fb702015-10-19 17:19:49 -070026def _PyOuts(srcs):
Jisi Liu125a91b2015-10-14 17:37:39 -070027 return [s[:-len(".proto")] + "_pb2.py" for s in srcs]
Jisi Liu39362b32015-10-14 17:12:11 -070028
Jisi Liu993fb702015-10-19 17:19:49 -070029def _RelativeOutputPath(path, include):
30 if include == None:
31 return path
32
33 if not path.startswith(include):
34 fail("Include path %s isn't part of the path %s." % (include, path))
35
36 if include and include[-1] != '/':
37 include = include + '/'
38
39 path = path[len(include):]
40
41 if not path.startswith(PACKAGE_NAME):
42 fail("The package %s is not within the path %s" % (PACKAGE_NAME, path))
43
44 if not PACKAGE_NAME:
45 return path
46
47 return path[len(PACKAGE_NAME)+1:]
48
Jisi Liu9c7d9c02015-10-15 10:51:32 -070049def _proto_gen_impl(ctx):
50 """General implementation for generating protos"""
Jisi Liu39362b32015-10-14 17:12:11 -070051 srcs = ctx.files.srcs
52 deps = []
53 deps += ctx.files.srcs
Jisi Liu993fb702015-10-19 17:19:49 -070054 gen_dir = _GenDir(ctx)
Jisi Liu53a56be2015-10-20 15:18:20 -070055 if gen_dir:
56 import_flags = ["-I" + gen_dir]
57 else:
58 import_flags = ["-I."]
59
Jisi Liu39362b32015-10-14 17:12:11 -070060 for dep in ctx.attr.deps:
61 import_flags += dep.proto.import_flags
62 deps += dep.proto.deps
63
64 args = []
65 if ctx.attr.gen_cc:
66 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
67 if ctx.attr.gen_py:
68 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
69
Manjunath Kudlurf0966a72016-02-22 14:30:43 -080070 if ctx.executable.grpc_cpp_plugin:
71 args += ["--plugin=protoc-gen-grpc=" + ctx.executable.grpc_cpp_plugin.path]
72 args += ["--grpc_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
73
Jisi Liu39362b32015-10-14 17:12:11 -070074 if args:
75 ctx.action(
Jisi Liu125a91b2015-10-14 17:37:39 -070076 inputs=srcs + deps,
Jisi Liu39362b32015-10-14 17:12:11 -070077 outputs=ctx.outputs.outs,
Jisi Liu125a91b2015-10-14 17:37:39 -070078 arguments=args + import_flags + [s.path for s in srcs],
Jisi Liu9c7d9c02015-10-15 10:51:32 -070079 executable=ctx.executable.protoc,
Jisi Liu39362b32015-10-14 17:12:11 -070080 )
81
82 return struct(
83 proto=struct(
Jisi Liu125a91b2015-10-14 17:37:39 -070084 srcs=srcs,
85 import_flags=import_flags,
86 deps=deps,
87 ),
88 )
Jisi Liu39362b32015-10-14 17:12:11 -070089
Jisi Liu9c7d9c02015-10-15 10:51:32 -070090_proto_gen = rule(
Jisi Liu39362b32015-10-14 17:12:11 -070091 attrs = {
Jisi Liuee8131a2015-10-14 17:20:05 -070092 "srcs": attr.label_list(allow_files = True),
93 "deps": attr.label_list(providers = ["proto"]),
Jisi Liu53a56be2015-10-20 15:18:20 -070094 "includes": attr.string_list(),
Jisi Liuee8131a2015-10-14 17:20:05 -070095 "protoc": attr.label(
Andrew Harp38f131f2015-11-03 16:39:32 -050096 cfg = HOST_CFG,
Jisi Liuee8131a2015-10-14 17:20:05 -070097 executable = True,
98 single_file = True,
99 mandatory = True,
100 ),
Manjunath Kudlurf0966a72016-02-22 14:30:43 -0800101 "grpc_cpp_plugin": attr.label(
102 cfg = HOST_CFG,
103 executable = True,
104 single_file = True,
105 ),
Jisi Liuee8131a2015-10-14 17:20:05 -0700106 "gen_cc": attr.bool(),
107 "gen_py": attr.bool(),
108 "outs": attr.output_list(),
109 },
110 output_to_genfiles = True,
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700111 implementation = _proto_gen_impl,
Jisi Liu39362b32015-10-14 17:12:11 -0700112)
113
114def cc_proto_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700115 name,
116 srcs=[],
Jisi Liu125a91b2015-10-14 17:37:39 -0700117 deps=[],
Jisi Liud8701b52015-10-16 11:44:21 -0700118 cc_libs=[],
Jisi Liu6dac0822015-10-19 14:41:00 -0700119 include=None,
David Z. Chen985c9682016-02-11 18:11:10 -0800120 protoc="//:protoc",
Jisi Liu3101e732015-10-16 12:46:26 -0700121 internal_bootstrap_hack=False,
Manjunath Kudlurf0966a72016-02-22 14:30:43 -0800122 use_grpc_plugin=False,
David Z. Chen985c9682016-02-11 18:11:10 -0800123 default_runtime="//:protobuf",
Jisi Liu125a91b2015-10-14 17:37:39 -0700124 **kargs):
Jisi Liu3101e732015-10-16 12:46:26 -0700125 """Bazel rule to create a C++ protobuf library from proto source files
126
Jisi Liud4bef7d2015-11-02 12:24:32 -0800127 NOTE: the rule is only an internal workaround to generate protos. The
128 interface may change and the rule may be removed when bazel has introduced
129 the native rule.
130
Jisi Liu3101e732015-10-16 12:46:26 -0700131 Args:
132 name: the name of the cc_proto_library.
133 srcs: the .proto files of the cc_proto_library.
134 deps: a list of dependency labels; must be cc_proto_library.
135 cc_libs: a list of other cc_library targets depended by the generated
136 cc_library.
137 include: a string indicating the include path of the .proto files.
138 protoc: the label of the protocol compiler to generate the sources.
139 internal_bootstrap_hack: a flag indicate the cc_proto_library is used only
140 for bootstraping. When it is set to True, no files will be generated.
141 The rule will simply be a provider for .proto files, so that other
142 cc_proto_library can depend on it.
Manjunath Kudlurf0966a72016-02-22 14:30:43 -0800143 use_grpc_plugin: a flag to indicate whether to call the grpc C++ plugin
144 when processing the proto files.
Jisi Liube92ffb2015-10-27 15:11:38 -0700145 default_runtime: the implicitly default runtime which will be depended on by
146 the generated cc_library target.
Jisi Liu3101e732015-10-16 12:46:26 -0700147 **kargs: other keyword arguments that are passed to cc_library.
148
149 """
Jisi Liu39362b32015-10-14 17:12:11 -0700150
Jisi Liu53a56be2015-10-20 15:18:20 -0700151 includes = []
152 if include != None:
153 includes = [include]
154
Jisi Liu39362b32015-10-14 17:12:11 -0700155 if internal_bootstrap_hack:
156 # For pre-checked-in generated files, we add the internal_bootstrap_hack
157 # which will skip the codegen action.
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700158 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700159 name=name + "_genproto",
160 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700161 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700162 includes=includes,
Jisi Liu125a91b2015-10-14 17:37:39 -0700163 protoc=protoc,
Martin Maly8e0c9a32015-12-04 17:44:58 -0800164 visibility=["//visibility:public"],
Jisi Liu39362b32015-10-14 17:12:11 -0700165 )
166 # An empty cc_library to make rule dependency consistent.
167 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700168 name=name,
Jisi Liud8701b52015-10-16 11:44:21 -0700169 **kargs)
Jisi Liu39362b32015-10-14 17:12:11 -0700170 return
171
Manjunath Kudlurf0966a72016-02-22 14:30:43 -0800172 grpc_cpp_plugin = None
173 if use_grpc_plugin:
174 grpc_cpp_plugin = "//external:grpc_cpp_plugin"
175
Manjunath Kudlurf5c73632016-02-25 08:50:50 -0800176 outs = _CcOuts(srcs, use_grpc_plugin)
177
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700178 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700179 name=name + "_genproto",
180 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700181 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700182 includes=includes,
Jisi Liu125a91b2015-10-14 17:37:39 -0700183 protoc=protoc,
Manjunath Kudlurf0966a72016-02-22 14:30:43 -0800184 grpc_cpp_plugin=grpc_cpp_plugin,
Jisi Liu125a91b2015-10-14 17:37:39 -0700185 gen_cc=1,
186 outs=outs,
Martin Maly8e0c9a32015-12-04 17:44:58 -0800187 visibility=["//visibility:public"],
Jisi Liu39362b32015-10-14 17:12:11 -0700188 )
189
Jisi Liube92ffb2015-10-27 15:11:38 -0700190 if default_runtime and not default_runtime in cc_libs:
191 cc_libs += [default_runtime]
Manjunath Kudlurf5c73632016-02-25 08:50:50 -0800192 if use_grpc_plugin:
193 cc_libs += ["//external:grpc_lib"]
Jisi Liu6dac0822015-10-19 14:41:00 -0700194
Jisi Liu39362b32015-10-14 17:12:11 -0700195 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700196 name=name,
197 srcs=outs,
Jisi Liud8701b52015-10-16 11:44:21 -0700198 deps=cc_libs + deps,
Jisi Liu6dac0822015-10-19 14:41:00 -0700199 includes=includes,
Jisi Liud8701b52015-10-16 11:44:21 -0700200 **kargs)
Jisi Liu993fb702015-10-19 17:19:49 -0700201
Steven Parkesea188662016-02-25 07:53:19 -0800202
203def internal_gen_well_known_protos_java(srcs):
204 """Bazel rule to generate the gen_well_known_protos_java genrule
205
206 Args:
207 srcs: the well known protos
208 """
209 root = Label("%s//protobuf_java" % (REPOSITORY_NAME)).workspace_root
210 if root == "":
211 include = " -Isrc "
212 else:
213 include = " -I%s/src " % root
214 native.genrule(
215 name = "gen_well_known_protos_java",
216 srcs = srcs,
217 outs = [
218 "wellknown.srcjar",
219 ],
220 cmd = "$(location :protoc) --java_out=$(@D)/wellknown.jar" +
221 " %s $(SRCS) " % include +
222 " && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar",
223 tools = [":protoc"],
224 )
225
226
Jisi Liu993fb702015-10-19 17:19:49 -0700227def py_proto_library(
228 name,
229 srcs=[],
230 deps=[],
231 py_libs=[],
232 py_extra_srcs=[],
233 include=None,
David Z. Chen985c9682016-02-11 18:11:10 -0800234 default_runtime="//:protobuf_python",
235 protoc="//:protoc",
Jisi Liu993fb702015-10-19 17:19:49 -0700236 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700237 """Bazel rule to create a Python protobuf library from proto source files
238
Jisi Liud4bef7d2015-11-02 12:24:32 -0800239 NOTE: the rule is only an internal workaround to generate protos. The
240 interface may change and the rule may be removed when bazel has introduced
241 the native rule.
242
Jisi Liu7b948cc2015-10-19 17:56:27 -0700243 Args:
244 name: the name of the py_proto_library.
245 srcs: the .proto files of the py_proto_library.
246 deps: a list of dependency labels; must be py_proto_library.
247 py_libs: a list of other py_library targets depended by the generated
248 py_library.
249 py_extra_srcs: extra source files that will be added to the output
250 py_library. This attribute is used for internal bootstrapping.
251 include: a string indicating the include path of the .proto files.
Jisi Liube92ffb2015-10-27 15:11:38 -0700252 default_runtime: the implicitly default runtime which will be depended on by
253 the generated py_library target.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700254 protoc: the label of the protocol compiler to generate the sources.
255 **kargs: other keyword arguments that are passed to cc_library.
256
257 """
Jisi Liu993fb702015-10-19 17:19:49 -0700258 outs = _PyOuts(srcs)
Jisi Liu53a56be2015-10-20 15:18:20 -0700259
260 includes = []
261 if include != None:
262 includes = [include]
263
Jisi Liu993fb702015-10-19 17:19:49 -0700264 _proto_gen(
265 name=name + "_genproto",
266 srcs=srcs,
267 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700268 includes=includes,
Jisi Liu993fb702015-10-19 17:19:49 -0700269 protoc=protoc,
270 gen_py=1,
271 outs=outs,
Martin Maly8e0c9a32015-12-04 17:44:58 -0800272 visibility=["//visibility:public"],
Jisi Liu993fb702015-10-19 17:19:49 -0700273 )
274
Jisi Liube92ffb2015-10-27 15:11:38 -0700275 if default_runtime and not default_runtime in py_libs + deps:
276 py_libs += [default_runtime]
277
Jisi Liu993fb702015-10-19 17:19:49 -0700278 native.py_library(
279 name=name,
Jisi Liua33fa8e2015-10-20 15:30:44 -0700280 srcs=outs+py_extra_srcs,
281 deps=py_libs+deps,
David Z. Chen985c9682016-02-11 18:11:10 -0800282 imports=includes,
Jisi Liu993fb702015-10-19 17:19:49 -0700283 **kargs)
284
285def internal_protobuf_py_tests(
286 name,
287 modules=[],
288 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700289 """Bazel rules to create batch tests for protobuf internal.
290
291 Args:
292 name: the name of the rule.
293 modules: a list of modules for tests. The macro will create a py_test for
294 each of the parameter with the source "google/protobuf/%s.py"
295 kargs: extra parameters that will be passed into the py_test.
296
297 """
Jisi Liu993fb702015-10-19 17:19:49 -0700298 for m in modules:
David Z. Chen985c9682016-02-11 18:11:10 -0800299 s = "python/google/protobuf/internal/%s.py" % m
Jisi Liu993fb702015-10-19 17:19:49 -0700300 native.py_test(
301 name="py_%s" % m,
Jisi Liu7b948cc2015-10-19 17:56:27 -0700302 srcs=[s],
303 main=s,
Jisi Liu993fb702015-10-19 17:19:49 -0700304 **kargs)