OLD | NEW |
| 1 # -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED |
| 2 |
1 def _GetPath(ctx, path): | 3 def _GetPath(ctx, path): |
2 if ctx.label.workspace_root: | 4 if ctx.label.workspace_root: |
3 return ctx.label.workspace_root + '/' + path | 5 return ctx.label.workspace_root + '/' + path |
4 else: | 6 else: |
5 return path | 7 return path |
6 | 8 |
7 def _GenDir(ctx): | 9 def _GenDir(ctx): |
8 if not ctx.attr.includes: | 10 if not ctx.attr.includes: |
9 return ctx.label.workspace_root | 11 return ctx.label.workspace_root |
10 if not ctx.attr.includes[0]: | 12 if not ctx.attr.includes[0]: |
11 return _GetPath(ctx, ctx.label.package) | 13 return _GetPath(ctx, ctx.label.package) |
12 if not ctx.label.package: | 14 if not ctx.label.package: |
13 return _GetPath(ctx, ctx.attr.includes[0]) | 15 return _GetPath(ctx, ctx.attr.includes[0]) |
14 return _GetPath(ctx, ctx.label.package + '/' + ctx.attr.includes[0]) | 16 return _GetPath(ctx, ctx.label.package + '/' + ctx.attr.includes[0]) |
15 | 17 |
16 def _CcHdrs(srcs, use_grpc_plugin=False): | 18 def _CcOuts(srcs, use_grpc_plugin=False): |
17 ret = [s[:-len(".proto")] + ".pb.h" for s in srcs] | 19 ret = [s[:-len(".proto")] + ".pb.h" for s in srcs] + \ |
| 20 [s[:-len(".proto")] + ".pb.cc" for s in srcs] |
18 if use_grpc_plugin: | 21 if use_grpc_plugin: |
19 ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs] | 22 ret += [s[:-len(".proto")] + ".grpc.pb.h" for s in srcs] + \ |
| 23 [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs] |
20 return ret | 24 return ret |
21 | 25 |
22 def _CcSrcs(srcs, use_grpc_plugin=False): | |
23 ret = [s[:-len(".proto")] + ".pb.cc" for s in srcs] | |
24 if use_grpc_plugin: | |
25 ret += [s[:-len(".proto")] + ".grpc.pb.cc" for s in srcs] | |
26 return ret | |
27 | |
28 def _CcOuts(srcs, use_grpc_plugin=False): | |
29 return _CcHdrs(srcs, use_grpc_plugin) + _CcSrcs(srcs, use_grpc_plugin) | |
30 | |
31 def _PyOuts(srcs): | 26 def _PyOuts(srcs): |
32 return [s[:-len(".proto")] + "_pb2.py" for s in srcs] | 27 return [s[:-len(".proto")] + "_pb2.py" for s in srcs] |
33 | 28 |
34 def _RelativeOutputPath(path, include, dest=""): | 29 def _RelativeOutputPath(path, include): |
35 if include == None: | 30 if include == None: |
36 return path | 31 return path |
37 | 32 |
38 if not path.startswith(include): | 33 if not path.startswith(include): |
39 fail("Include path %s isn't part of the path %s." % (include, path)) | 34 fail("Include path %s isn't part of the path %s." % (include, path)) |
40 | 35 |
41 if include and include[-1] != '/': | 36 if include and include[-1] != '/': |
42 include = include + '/' | 37 include = include + '/' |
43 if dest and dest[-1] != '/': | |
44 dest = dest + '/' | |
45 | 38 |
46 path = path[len(include):] | 39 path = path[len(include):] |
47 return dest + path | 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 | 48 |
49 def _proto_gen_impl(ctx): | 49 def _proto_gen_impl(ctx): |
50 """General implementation for generating protos""" | 50 """General implementation for generating protos""" |
51 srcs = ctx.files.srcs | 51 srcs = ctx.files.srcs |
52 deps = [] | 52 deps = [] |
53 deps += ctx.files.srcs | 53 deps += ctx.files.srcs |
54 gen_dir = _GenDir(ctx) | 54 gen_dir = _GenDir(ctx) |
55 if gen_dir: | 55 if gen_dir: |
56 import_flags = ["-I" + gen_dir, "-I" + ctx.var["GENDIR"] + "/" + gen_dir] | 56 import_flags = ["-I" + gen_dir] |
57 else: | 57 else: |
58 import_flags = ["-I."] | 58 import_flags = ["-I."] |
59 | 59 |
60 for dep in ctx.attr.deps: | 60 for dep in ctx.attr.deps: |
61 import_flags += dep.proto.import_flags | 61 import_flags += dep.proto.import_flags |
62 deps += dep.proto.deps | 62 deps += dep.proto.deps |
63 | 63 |
64 args = [] | 64 args = [] |
65 if ctx.attr.gen_cc: | 65 if ctx.attr.gen_cc: |
66 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir] | 66 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir] |
67 if ctx.attr.gen_py: | 67 if ctx.attr.gen_py: |
68 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir] | 68 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir] |
69 | 69 |
70 inputs = srcs + deps | 70 if ctx.executable.grpc_cpp_plugin: |
71 if ctx.executable.plugin: | 71 args += ["--plugin=protoc-gen-grpc=" + ctx.executable.grpc_cpp_plugin.path] |
72 plugin = ctx.executable.plugin | 72 args += ["--grpc_out=" + ctx.var["GENDIR"] + "/" + gen_dir] |
73 lang = ctx.attr.plugin_language | |
74 if not lang and plugin.basename.startswith('protoc-gen-'): | |
75 lang = plugin.basename[len('protoc-gen-'):] | |
76 if not lang: | |
77 fail("cannot infer the target language of plugin", "plugin_language") | |
78 | |
79 outdir = ctx.var["GENDIR"] + "/" + gen_dir | |
80 if ctx.attr.plugin_options: | |
81 outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir | |
82 args += ["--plugin=protoc-gen-%s=%s" % (lang, plugin.path)] | |
83 args += ["--%s_out=%s" % (lang, outdir)] | |
84 inputs += [plugin] | |
85 | 73 |
86 if args: | 74 if args: |
87 ctx.action( | 75 ctx.action( |
88 inputs=inputs, | 76 inputs=srcs + deps, |
89 outputs=ctx.outputs.outs, | 77 outputs=ctx.outputs.outs, |
90 arguments=args + import_flags + [s.path for s in srcs], | 78 arguments=args + import_flags + [s.path for s in srcs], |
91 executable=ctx.executable.protoc, | 79 executable=ctx.executable.protoc, |
92 mnemonic="ProtoCompile", | |
93 ) | 80 ) |
94 | 81 |
95 return struct( | 82 return struct( |
96 proto=struct( | 83 proto=struct( |
97 srcs=srcs, | 84 srcs=srcs, |
98 import_flags=import_flags, | 85 import_flags=import_flags, |
99 deps=deps, | 86 deps=deps, |
100 ), | 87 ), |
101 ) | 88 ) |
102 | 89 |
103 proto_gen = rule( | 90 _proto_gen = rule( |
104 attrs = { | 91 attrs = { |
105 "srcs": attr.label_list(allow_files = True), | 92 "srcs": attr.label_list(allow_files = True), |
106 "deps": attr.label_list(providers = ["proto"]), | 93 "deps": attr.label_list(providers = ["proto"]), |
107 "includes": attr.string_list(), | 94 "includes": attr.string_list(), |
108 "protoc": attr.label( | 95 "protoc": attr.label( |
109 cfg = "host", | 96 cfg = HOST_CFG, |
110 executable = True, | 97 executable = True, |
111 single_file = True, | 98 single_file = True, |
112 mandatory = True, | 99 mandatory = True, |
113 ), | 100 ), |
114 "plugin": attr.label( | 101 "grpc_cpp_plugin": attr.label( |
115 cfg = "host", | 102 cfg = HOST_CFG, |
116 allow_files = True, | |
117 executable = True, | 103 executable = True, |
| 104 single_file = True, |
118 ), | 105 ), |
119 "plugin_language": attr.string(), | |
120 "plugin_options": attr.string_list(), | |
121 "gen_cc": attr.bool(), | 106 "gen_cc": attr.bool(), |
122 "gen_py": attr.bool(), | 107 "gen_py": attr.bool(), |
123 "outs": attr.output_list(), | 108 "outs": attr.output_list(), |
124 }, | 109 }, |
125 output_to_genfiles = True, | 110 output_to_genfiles = True, |
126 implementation = _proto_gen_impl, | 111 implementation = _proto_gen_impl, |
127 ) | 112 ) |
128 """Generates codes from Protocol Buffers definitions. | |
129 | |
130 This rule helps you to implement Skylark macros specific to the target | |
131 language. You should prefer more specific `cc_proto_library `, | |
132 `py_proto_library` and others unless you are adding such wrapper macros. | |
133 | |
134 Args: | |
135 srcs: Protocol Buffers definition files (.proto) to run the protocol compiler | |
136 against. | |
137 deps: a list of dependency labels; must be other proto libraries. | |
138 includes: a list of include paths to .proto files. | |
139 protoc: the label of the protocol compiler to generate the sources. | |
140 plugin: the label of the protocol compiler plugin to be passed to the protocol | |
141 compiler. | |
142 plugin_language: the language of the generated sources | |
143 plugin_options: a list of options to be passed to the plugin | |
144 gen_cc: generates C++ sources in addition to the ones from the plugin. | |
145 gen_py: generates Python sources in addition to the ones from the plugin. | |
146 outs: a list of labels of the expected outputs from the protocol compiler. | |
147 """ | |
148 | 113 |
149 def cc_proto_library( | 114 def cc_proto_library( |
150 name, | 115 name, |
151 srcs=[], | 116 srcs=[], |
152 deps=[], | 117 deps=[], |
153 cc_libs=[], | 118 cc_libs=[], |
154 include=None, | 119 include=None, |
155 protoc="//:protoc", | 120 protoc="//:protoc", |
156 internal_bootstrap_hack=False, | 121 internal_bootstrap_hack=False, |
157 use_grpc_plugin=False, | 122 use_grpc_plugin=False, |
(...skipping 25 matching lines...) Expand all Loading... |
183 | 148 |
184 """ | 149 """ |
185 | 150 |
186 includes = [] | 151 includes = [] |
187 if include != None: | 152 if include != None: |
188 includes = [include] | 153 includes = [include] |
189 | 154 |
190 if internal_bootstrap_hack: | 155 if internal_bootstrap_hack: |
191 # For pre-checked-in generated files, we add the internal_bootstrap_hack | 156 # For pre-checked-in generated files, we add the internal_bootstrap_hack |
192 # which will skip the codegen action. | 157 # which will skip the codegen action. |
193 proto_gen( | 158 _proto_gen( |
194 name=name + "_genproto", | 159 name=name + "_genproto", |
195 srcs=srcs, | 160 srcs=srcs, |
196 deps=[s + "_genproto" for s in deps], | 161 deps=[s + "_genproto" for s in deps], |
197 includes=includes, | 162 includes=includes, |
198 protoc=protoc, | 163 protoc=protoc, |
199 visibility=["//visibility:public"], | 164 visibility=["//visibility:public"], |
200 ) | 165 ) |
201 # An empty cc_library to make rule dependency consistent. | 166 # An empty cc_library to make rule dependency consistent. |
202 native.cc_library( | 167 native.cc_library( |
203 name=name, | 168 name=name, |
204 **kargs) | 169 **kargs) |
205 return | 170 return |
206 | 171 |
207 grpc_cpp_plugin = None | 172 grpc_cpp_plugin = None |
208 if use_grpc_plugin: | 173 if use_grpc_plugin: |
209 grpc_cpp_plugin = "//external:grpc_cpp_plugin" | 174 grpc_cpp_plugin = "//external:grpc_cpp_plugin" |
210 | 175 |
211 gen_srcs = _CcSrcs(srcs, use_grpc_plugin) | 176 outs = _CcOuts(srcs, use_grpc_plugin) |
212 gen_hdrs = _CcHdrs(srcs, use_grpc_plugin) | |
213 outs = gen_srcs + gen_hdrs | |
214 | 177 |
215 proto_gen( | 178 _proto_gen( |
216 name=name + "_genproto", | 179 name=name + "_genproto", |
217 srcs=srcs, | 180 srcs=srcs, |
218 deps=[s + "_genproto" for s in deps], | 181 deps=[s + "_genproto" for s in deps], |
219 includes=includes, | 182 includes=includes, |
220 protoc=protoc, | 183 protoc=protoc, |
221 plugin=grpc_cpp_plugin, | 184 grpc_cpp_plugin=grpc_cpp_plugin, |
222 plugin_language="grpc", | |
223 gen_cc=1, | 185 gen_cc=1, |
224 outs=outs, | 186 outs=outs, |
225 visibility=["//visibility:public"], | 187 visibility=["//visibility:public"], |
226 ) | 188 ) |
227 | 189 |
228 if default_runtime and not default_runtime in cc_libs: | 190 if default_runtime and not default_runtime in cc_libs: |
229 cc_libs += [default_runtime] | 191 cc_libs += [default_runtime] |
230 if use_grpc_plugin: | 192 if use_grpc_plugin: |
231 cc_libs += ["//external:grpc_lib"] | 193 cc_libs += ["//external:grpc_lib"] |
232 | 194 |
233 native.cc_library( | 195 native.cc_library( |
234 name=name, | 196 name=name, |
235 srcs=gen_srcs, | 197 srcs=outs, |
236 hdrs=gen_hdrs, | |
237 deps=cc_libs + deps, | 198 deps=cc_libs + deps, |
238 includes=includes, | 199 includes=includes, |
239 **kargs) | 200 **kargs) |
240 | 201 |
| 202 |
241 def internal_gen_well_known_protos_java(srcs): | 203 def internal_gen_well_known_protos_java(srcs): |
242 """Bazel rule to generate the gen_well_known_protos_java genrule | 204 """Bazel rule to generate the gen_well_known_protos_java genrule |
243 | 205 |
244 Args: | 206 Args: |
245 srcs: the well known protos | 207 srcs: the well known protos |
246 """ | 208 """ |
247 root = Label("%s//protobuf_java" % (REPOSITORY_NAME)).workspace_root | 209 root = Label("%s//protobuf_java" % (REPOSITORY_NAME)).workspace_root |
248 if root == "": | 210 if root == "": |
249 include = " -Isrc " | 211 include = " -Isrc " |
250 else: | 212 else: |
251 include = " -I%s/src " % root | 213 include = " -I%s/src " % root |
252 native.genrule( | 214 native.genrule( |
253 name = "gen_well_known_protos_java", | 215 name = "gen_well_known_protos_java", |
254 srcs = srcs, | 216 srcs = srcs, |
255 outs = [ | 217 outs = [ |
256 "wellknown.srcjar", | 218 "wellknown.srcjar", |
257 ], | 219 ], |
258 cmd = "$(location :protoc) --java_out=$(@D)/wellknown.jar" + | 220 cmd = "$(location :protoc) --java_out=$(@D)/wellknown.jar" + |
259 " %s $(SRCS) " % include + | 221 " %s $(SRCS) " % include + |
260 " && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar", | 222 " && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar", |
261 tools = [":protoc"], | 223 tools = [":protoc"], |
262 ) | 224 ) |
263 | 225 |
264 def internal_copied_filegroup(name, srcs, strip_prefix, dest, **kwargs): | |
265 """Macro to copy files to a different directory and then create a filegroup. | |
266 | |
267 This is used by the //:protobuf_python py_proto_library target to work around | |
268 an issue caused by Python source files that are part of the same Python | |
269 package being in separate directories. | |
270 | |
271 Args: | |
272 srcs: The source files to copy and add to the filegroup. | |
273 strip_prefix: Path to the root of the files to copy. | |
274 dest: The directory to copy the source files into. | |
275 **kwargs: extra arguments that will be passesd to the filegroup. | |
276 """ | |
277 outs = [_RelativeOutputPath(s, strip_prefix, dest) for s in srcs] | |
278 | |
279 native.genrule( | |
280 name = name + "_genrule", | |
281 srcs = srcs, | |
282 outs = outs, | |
283 cmd = " && ".join( | |
284 ["cp $(location %s) $(location %s)" % | |
285 (s, _RelativeOutputPath(s, strip_prefix, dest)) for s in srcs]), | |
286 ) | |
287 | |
288 native.filegroup( | |
289 name = name, | |
290 srcs = outs, | |
291 **kwargs) | |
292 | 226 |
293 def py_proto_library( | 227 def py_proto_library( |
294 name, | 228 name, |
295 srcs=[], | 229 srcs=[], |
296 deps=[], | 230 deps=[], |
297 py_libs=[], | 231 py_libs=[], |
298 py_extra_srcs=[], | 232 py_extra_srcs=[], |
299 include=None, | 233 include=None, |
300 default_runtime="//:protobuf_python", | 234 default_runtime="//:protobuf_python", |
301 protoc="//:protoc", | 235 protoc="//:protoc", |
302 use_grpc_plugin=False, | |
303 **kargs): | 236 **kargs): |
304 """Bazel rule to create a Python protobuf library from proto source files | 237 """Bazel rule to create a Python protobuf library from proto source files |
305 | 238 |
306 NOTE: the rule is only an internal workaround to generate protos. The | 239 NOTE: the rule is only an internal workaround to generate protos. The |
307 interface may change and the rule may be removed when bazel has introduced | 240 interface may change and the rule may be removed when bazel has introduced |
308 the native rule. | 241 the native rule. |
309 | 242 |
310 Args: | 243 Args: |
311 name: the name of the py_proto_library. | 244 name: the name of the py_proto_library. |
312 srcs: the .proto files of the py_proto_library. | 245 srcs: the .proto files of the py_proto_library. |
313 deps: a list of dependency labels; must be py_proto_library. | 246 deps: a list of dependency labels; must be py_proto_library. |
314 py_libs: a list of other py_library targets depended by the generated | 247 py_libs: a list of other py_library targets depended by the generated |
315 py_library. | 248 py_library. |
316 py_extra_srcs: extra source files that will be added to the output | 249 py_extra_srcs: extra source files that will be added to the output |
317 py_library. This attribute is used for internal bootstrapping. | 250 py_library. This attribute is used for internal bootstrapping. |
318 include: a string indicating the include path of the .proto files. | 251 include: a string indicating the include path of the .proto files. |
319 default_runtime: the implicitly default runtime which will be depended on by | 252 default_runtime: the implicitly default runtime which will be depended on by |
320 the generated py_library target. | 253 the generated py_library target. |
321 protoc: the label of the protocol compiler to generate the sources. | 254 protoc: the label of the protocol compiler to generate the sources. |
322 use_grpc_plugin: a flag to indicate whether to call the Python C++ plugin | |
323 when processing the proto files. | |
324 **kargs: other keyword arguments that are passed to cc_library. | 255 **kargs: other keyword arguments that are passed to cc_library. |
325 | 256 |
326 """ | 257 """ |
327 outs = _PyOuts(srcs) | 258 outs = _PyOuts(srcs) |
328 | 259 |
329 includes = [] | 260 includes = [] |
330 if include != None: | 261 if include != None: |
331 includes = [include] | 262 includes = [include] |
332 | 263 |
333 grpc_python_plugin = None | 264 _proto_gen( |
334 if use_grpc_plugin: | |
335 grpc_python_plugin = "//external:grpc_python_plugin" | |
336 # Note: Generated grpc code depends on Python grpc module. This dependency | |
337 # is not explicitly listed in py_libs. Instead, host system is assumed to | |
338 # have grpc installed. | |
339 | |
340 proto_gen( | |
341 name=name + "_genproto", | 265 name=name + "_genproto", |
342 srcs=srcs, | 266 srcs=srcs, |
343 deps=[s + "_genproto" for s in deps], | 267 deps=[s + "_genproto" for s in deps], |
344 includes=includes, | 268 includes=includes, |
345 protoc=protoc, | 269 protoc=protoc, |
346 gen_py=1, | 270 gen_py=1, |
347 outs=outs, | 271 outs=outs, |
348 visibility=["//visibility:public"], | 272 visibility=["//visibility:public"], |
349 plugin=grpc_python_plugin, | |
350 plugin_language="grpc" | |
351 ) | 273 ) |
352 | 274 |
353 if default_runtime and not default_runtime in py_libs + deps: | 275 if default_runtime and not default_runtime in py_libs + deps: |
354 py_libs += [default_runtime] | 276 py_libs += [default_runtime] |
355 | 277 |
356 native.py_library( | 278 native.py_library( |
357 name=name, | 279 name=name, |
358 srcs=outs+py_extra_srcs, | 280 srcs=outs+py_extra_srcs, |
359 deps=py_libs+deps, | 281 deps=py_libs+deps, |
360 imports=includes, | 282 imports=includes, |
(...skipping 12 matching lines...) Expand all Loading... |
373 kargs: extra parameters that will be passed into the py_test. | 295 kargs: extra parameters that will be passed into the py_test. |
374 | 296 |
375 """ | 297 """ |
376 for m in modules: | 298 for m in modules: |
377 s = "python/google/protobuf/internal/%s.py" % m | 299 s = "python/google/protobuf/internal/%s.py" % m |
378 native.py_test( | 300 native.py_test( |
379 name="py_%s" % m, | 301 name="py_%s" % m, |
380 srcs=[s], | 302 srcs=[s], |
381 main=s, | 303 main=s, |
382 **kargs) | 304 **kargs) |
OLD | NEW |