OLD | NEW |
1 # -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED | 1 # -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED |
2 | 2 |
| 3 def _GetPath(ctx, path): |
| 4 if ctx.label.workspace_root: |
| 5 return ctx.label.workspace_root + '/' + path |
| 6 else: |
| 7 return path |
| 8 |
3 def _GenDir(ctx): | 9 def _GenDir(ctx): |
4 if not ctx.attr.includes: | 10 if not ctx.attr.includes: |
5 return "" | 11 return ctx.label.workspace_root |
6 if not ctx.attr.includes[0]: | 12 if not ctx.attr.includes[0]: |
7 return ctx.label.package | 13 return _GetPath(ctx, ctx.label.package) |
8 if not ctx.label.package: | 14 if not ctx.label.package: |
9 return ctx.attr.includes[0] | 15 return _GetPath(ctx, ctx.attr.includes[0]) |
10 return ctx.label.package + '/' + ctx.attr.includes[0] | 16 return _GetPath(ctx, ctx.label.package + '/' + ctx.attr.includes[0]) |
11 | 17 |
12 def _CcOuts(srcs): | 18 def _CcOuts(srcs, use_grpc_plugin=False): |
13 return [s[:-len(".proto")] + ".pb.h" for s in srcs] + \ | 19 ret = [s[:-len(".proto")] + ".pb.h" for s in srcs] + \ |
14 [s[:-len(".proto")] + ".pb.cc" 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 |
15 | 25 |
16 def _PyOuts(srcs): | 26 def _PyOuts(srcs): |
17 return [s[:-len(".proto")] + "_pb2.py" for s in srcs] | 27 return [s[:-len(".proto")] + "_pb2.py" for s in srcs] |
18 | 28 |
19 def _RelativeOutputPath(path, include): | 29 def _RelativeOutputPath(path, include): |
20 if include == None: | 30 if include == None: |
21 return path | 31 return path |
22 | 32 |
23 if not path.startswith(include): | 33 if not path.startswith(include): |
24 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)) |
25 | 35 |
26 if include and include[-1] != '/': | 36 if include and include[-1] != '/': |
27 include = include + '/' | 37 include = include + '/' |
28 | 38 |
29 path = path[len(include):] | 39 path = path[len(include):] |
30 | 40 |
31 if not path.startswith(PACKAGE_NAME): | 41 if not path.startswith(PACKAGE_NAME): |
32 fail("The package %s is not within the path %s" % (PACKAGE_NAME, path)) | 42 fail("The package %s is not within the path %s" % (PACKAGE_NAME, path)) |
33 | 43 |
34 if not PACKAGE_NAME: | 44 if not PACKAGE_NAME: |
35 return path | 45 return path |
36 | 46 |
37 return path[len(PACKAGE_NAME)+1:] | 47 return path[len(PACKAGE_NAME)+1:] |
38 | 48 |
39 | |
40 | |
41 def _proto_gen_impl(ctx): | 49 def _proto_gen_impl(ctx): |
42 """General implementation for generating protos""" | 50 """General implementation for generating protos""" |
43 srcs = ctx.files.srcs | 51 srcs = ctx.files.srcs |
44 deps = [] | 52 deps = [] |
45 deps += ctx.files.srcs | 53 deps += ctx.files.srcs |
46 gen_dir = _GenDir(ctx) | 54 gen_dir = _GenDir(ctx) |
47 if gen_dir: | 55 if gen_dir: |
48 import_flags = ["-I" + gen_dir] | 56 import_flags = ["-I" + gen_dir] |
49 else: | 57 else: |
50 import_flags = ["-I."] | 58 import_flags = ["-I."] |
51 | 59 |
52 for dep in ctx.attr.deps: | 60 for dep in ctx.attr.deps: |
53 import_flags += dep.proto.import_flags | 61 import_flags += dep.proto.import_flags |
54 deps += dep.proto.deps | 62 deps += dep.proto.deps |
55 | 63 |
56 args = [] | 64 args = [] |
57 if ctx.attr.gen_cc: | 65 if ctx.attr.gen_cc: |
58 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir] | 66 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir] |
59 if ctx.attr.gen_py: | 67 if ctx.attr.gen_py: |
60 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir] | 68 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir] |
61 | 69 |
| 70 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 |
62 if args: | 74 if args: |
63 ctx.action( | 75 ctx.action( |
64 inputs=srcs + deps, | 76 inputs=srcs + deps, |
65 outputs=ctx.outputs.outs, | 77 outputs=ctx.outputs.outs, |
66 arguments=args + import_flags + [s.path for s in srcs], | 78 arguments=args + import_flags + [s.path for s in srcs], |
67 executable=ctx.executable.protoc, | 79 executable=ctx.executable.protoc, |
68 ) | 80 ) |
69 | 81 |
70 return struct( | 82 return struct( |
71 proto=struct( | 83 proto=struct( |
72 srcs=srcs, | 84 srcs=srcs, |
73 import_flags=import_flags, | 85 import_flags=import_flags, |
74 deps=deps, | 86 deps=deps, |
75 ), | 87 ), |
76 ) | 88 ) |
77 | 89 |
78 _proto_gen = rule( | 90 _proto_gen = rule( |
79 attrs = { | 91 attrs = { |
80 "srcs": attr.label_list(allow_files = True), | 92 "srcs": attr.label_list(allow_files = True), |
81 "deps": attr.label_list(providers = ["proto"]), | 93 "deps": attr.label_list(providers = ["proto"]), |
82 "includes": attr.string_list(), | 94 "includes": attr.string_list(), |
83 "protoc": attr.label( | 95 "protoc": attr.label( |
84 cfg = HOST_CFG, | 96 cfg = HOST_CFG, |
85 executable = True, | 97 executable = True, |
86 single_file = True, | 98 single_file = True, |
87 mandatory = True, | 99 mandatory = True, |
88 ), | 100 ), |
| 101 "grpc_cpp_plugin": attr.label( |
| 102 cfg = HOST_CFG, |
| 103 executable = True, |
| 104 single_file = True, |
| 105 ), |
89 "gen_cc": attr.bool(), | 106 "gen_cc": attr.bool(), |
90 "gen_py": attr.bool(), | 107 "gen_py": attr.bool(), |
91 "outs": attr.output_list(), | 108 "outs": attr.output_list(), |
92 }, | 109 }, |
93 output_to_genfiles = True, | 110 output_to_genfiles = True, |
94 implementation = _proto_gen_impl, | 111 implementation = _proto_gen_impl, |
95 ) | 112 ) |
96 | 113 |
97 def cc_proto_library( | 114 def cc_proto_library( |
98 name, | 115 name, |
99 srcs=[], | 116 srcs=[], |
100 deps=[], | 117 deps=[], |
101 cc_libs=[], | 118 cc_libs=[], |
102 include=None, | 119 include=None, |
103 protoc="//google/protobuf:protoc", | 120 protoc="//:protoc", |
104 internal_bootstrap_hack=False, | 121 internal_bootstrap_hack=False, |
105 default_runtime="//google/protobuf:protobuf", | 122 use_grpc_plugin=False, |
| 123 default_runtime="//:protobuf", |
106 **kargs): | 124 **kargs): |
107 """Bazel rule to create a C++ protobuf library from proto source files | 125 """Bazel rule to create a C++ protobuf library from proto source files |
108 | 126 |
109 NOTE: the rule is only an internal workaround to generate protos. The | 127 NOTE: the rule is only an internal workaround to generate protos. The |
110 interface may change and the rule may be removed when bazel has introduced | 128 interface may change and the rule may be removed when bazel has introduced |
111 the native rule. | 129 the native rule. |
112 | 130 |
113 Args: | 131 Args: |
114 name: the name of the cc_proto_library. | 132 name: the name of the cc_proto_library. |
115 srcs: the .proto files of the cc_proto_library. | 133 srcs: the .proto files of the cc_proto_library. |
116 deps: a list of dependency labels; must be cc_proto_library. | 134 deps: a list of dependency labels; must be cc_proto_library. |
117 cc_libs: a list of other cc_library targets depended by the generated | 135 cc_libs: a list of other cc_library targets depended by the generated |
118 cc_library. | 136 cc_library. |
119 include: a string indicating the include path of the .proto files. | 137 include: a string indicating the include path of the .proto files. |
120 protoc: the label of the protocol compiler to generate the sources. | 138 protoc: the label of the protocol compiler to generate the sources. |
121 internal_bootstrap_hack: a flag indicate the cc_proto_library is used only | 139 internal_bootstrap_hack: a flag indicate the cc_proto_library is used only |
122 for bootstraping. When it is set to True, no files will be generated. | 140 for bootstraping. When it is set to True, no files will be generated. |
123 The rule will simply be a provider for .proto files, so that other | 141 The rule will simply be a provider for .proto files, so that other |
124 cc_proto_library can depend on it. | 142 cc_proto_library can depend on it. |
| 143 use_grpc_plugin: a flag to indicate whether to call the grpc C++ plugin |
| 144 when processing the proto files. |
125 default_runtime: the implicitly default runtime which will be depended on by | 145 default_runtime: the implicitly default runtime which will be depended on by |
126 the generated cc_library target. | 146 the generated cc_library target. |
127 **kargs: other keyword arguments that are passed to cc_library. | 147 **kargs: other keyword arguments that are passed to cc_library. |
128 | 148 |
129 """ | 149 """ |
130 | 150 |
131 includes = [] | 151 includes = [] |
132 if include != None: | 152 if include != None: |
133 includes = [include] | 153 includes = [include] |
134 | 154 |
135 if internal_bootstrap_hack: | 155 if internal_bootstrap_hack: |
136 # 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 |
137 # which will skip the codegen action. | 157 # which will skip the codegen action. |
138 _proto_gen( | 158 _proto_gen( |
139 name=name + "_genproto", | 159 name=name + "_genproto", |
140 srcs=srcs, | 160 srcs=srcs, |
141 deps=[s + "_genproto" for s in deps], | 161 deps=[s + "_genproto" for s in deps], |
142 includes=includes, | 162 includes=includes, |
143 protoc=protoc, | 163 protoc=protoc, |
144 visibility=["//visibility:public"], | 164 visibility=["//visibility:public"], |
145 ) | 165 ) |
146 # An empty cc_library to make rule dependency consistent. | 166 # An empty cc_library to make rule dependency consistent. |
147 native.cc_library( | 167 native.cc_library( |
148 name=name, | 168 name=name, |
149 **kargs) | 169 **kargs) |
150 return | 170 return |
151 | 171 |
152 outs = _CcOuts(srcs) | 172 grpc_cpp_plugin = None |
| 173 if use_grpc_plugin: |
| 174 grpc_cpp_plugin = "//external:grpc_cpp_plugin" |
| 175 |
| 176 outs = _CcOuts(srcs, use_grpc_plugin) |
| 177 |
153 _proto_gen( | 178 _proto_gen( |
154 name=name + "_genproto", | 179 name=name + "_genproto", |
155 srcs=srcs, | 180 srcs=srcs, |
156 deps=[s + "_genproto" for s in deps], | 181 deps=[s + "_genproto" for s in deps], |
157 includes=includes, | 182 includes=includes, |
158 protoc=protoc, | 183 protoc=protoc, |
| 184 grpc_cpp_plugin=grpc_cpp_plugin, |
159 gen_cc=1, | 185 gen_cc=1, |
160 outs=outs, | 186 outs=outs, |
161 visibility=["//visibility:public"], | 187 visibility=["//visibility:public"], |
162 ) | 188 ) |
163 | 189 |
164 if default_runtime and not default_runtime in cc_libs: | 190 if default_runtime and not default_runtime in cc_libs: |
165 cc_libs += [default_runtime] | 191 cc_libs += [default_runtime] |
| 192 if use_grpc_plugin: |
| 193 cc_libs += ["//external:grpc_lib"] |
166 | 194 |
167 native.cc_library( | 195 native.cc_library( |
168 name=name, | 196 name=name, |
169 srcs=outs, | 197 srcs=outs, |
170 deps=cc_libs + deps, | 198 deps=cc_libs + deps, |
171 includes=includes, | 199 includes=includes, |
172 **kargs) | 200 **kargs) |
173 | 201 |
174 | 202 |
175 def internal_copied_filegroup( | 203 def internal_gen_well_known_protos_java(srcs): |
176 name, | 204 """Bazel rule to generate the gen_well_known_protos_java genrule |
177 srcs, | |
178 include, | |
179 **kargs): | |
180 """Bazel rule to fix sources file to workaround with python path issues. | |
181 | 205 |
182 Args: | 206 Args: |
183 name: the name of the internal_copied_filegroup rule, which will be the | 207 srcs: the well known protos |
184 name of the generated filegroup. | |
185 srcs: the source files to be copied. | |
186 include: the expected import root of the source. | |
187 **kargs: extra arguments that will be passed into the filegroup. | |
188 """ | 208 """ |
189 outs = [_RelativeOutputPath(s, include) for s in srcs] | 209 root = Label("%s//protobuf_java" % (REPOSITORY_NAME)).workspace_root |
190 | 210 if root == "": |
| 211 include = " -Isrc " |
| 212 else: |
| 213 include = " -I%s/src " % root |
191 native.genrule( | 214 native.genrule( |
192 name=name+"_genrule", | 215 name = "gen_well_known_protos_java", |
193 srcs=srcs, | 216 srcs = srcs, |
194 outs=outs, | 217 outs = [ |
195 cmd=" && ".join(["cp $(location %s) $(location %s)" % | 218 "wellknown.srcjar", |
196 (s, _RelativeOutputPath(s, include)) | 219 ], |
197 for s in srcs])) | 220 cmd = "$(location :protoc) --java_out=$(@D)/wellknown.jar" + |
198 | 221 " %s $(SRCS) " % include + |
199 native.filegroup( | 222 " && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar", |
200 name=name, | 223 tools = [":protoc"], |
201 srcs=outs, | 224 ) |
202 **kargs) | |
203 | 225 |
204 | 226 |
205 def py_proto_library( | 227 def py_proto_library( |
206 name, | 228 name, |
207 srcs=[], | 229 srcs=[], |
208 deps=[], | 230 deps=[], |
209 py_libs=[], | 231 py_libs=[], |
210 py_extra_srcs=[], | 232 py_extra_srcs=[], |
211 include=None, | 233 include=None, |
212 default_runtime="//google/protobuf:protobuf_python", | 234 default_runtime="//:protobuf_python", |
213 protoc="//google/protobuf:protoc", | 235 protoc="//:protoc", |
214 **kargs): | 236 **kargs): |
215 """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 |
216 | 238 |
217 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 |
218 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 |
219 the native rule. | 241 the native rule. |
220 | 242 |
221 Args: | 243 Args: |
222 name: the name of the py_proto_library. | 244 name: the name of the py_proto_library. |
223 srcs: the .proto files of the py_proto_library. | 245 srcs: the .proto files of the py_proto_library. |
(...skipping 19 matching lines...) Expand all Loading... |
243 name=name + "_genproto", | 265 name=name + "_genproto", |
244 srcs=srcs, | 266 srcs=srcs, |
245 deps=[s + "_genproto" for s in deps], | 267 deps=[s + "_genproto" for s in deps], |
246 includes=includes, | 268 includes=includes, |
247 protoc=protoc, | 269 protoc=protoc, |
248 gen_py=1, | 270 gen_py=1, |
249 outs=outs, | 271 outs=outs, |
250 visibility=["//visibility:public"], | 272 visibility=["//visibility:public"], |
251 ) | 273 ) |
252 | 274 |
253 if include != None: | |
254 # Copy the output files to the desired location to make the import work. | |
255 internal_copied_filegroup_name=name + "_internal_copied_filegroup" | |
256 internal_copied_filegroup( | |
257 name=internal_copied_filegroup_name, | |
258 srcs=outs, | |
259 include=include) | |
260 outs=[internal_copied_filegroup_name] | |
261 | |
262 if default_runtime and not default_runtime in py_libs + deps: | 275 if default_runtime and not default_runtime in py_libs + deps: |
263 py_libs += [default_runtime] | 276 py_libs += [default_runtime] |
264 | 277 |
265 native.py_library( | 278 native.py_library( |
266 name=name, | 279 name=name, |
267 srcs=outs+py_extra_srcs, | 280 srcs=outs+py_extra_srcs, |
268 deps=py_libs+deps, | 281 deps=py_libs+deps, |
| 282 imports=includes, |
269 **kargs) | 283 **kargs) |
270 | 284 |
271 def internal_protobuf_py_tests( | 285 def internal_protobuf_py_tests( |
272 name, | 286 name, |
273 modules=[], | 287 modules=[], |
274 **kargs): | 288 **kargs): |
275 """Bazel rules to create batch tests for protobuf internal. | 289 """Bazel rules to create batch tests for protobuf internal. |
276 | 290 |
277 Args: | 291 Args: |
278 name: the name of the rule. | 292 name: the name of the rule. |
279 modules: a list of modules for tests. The macro will create a py_test for | 293 modules: a list of modules for tests. The macro will create a py_test for |
280 each of the parameter with the source "google/protobuf/%s.py" | 294 each of the parameter with the source "google/protobuf/%s.py" |
281 kargs: extra parameters that will be passed into the py_test. | 295 kargs: extra parameters that will be passed into the py_test. |
282 | 296 |
283 """ | 297 """ |
284 for m in modules: | 298 for m in modules: |
285 s = _RelativeOutputPath( | 299 s = "python/google/protobuf/internal/%s.py" % m |
286 "python/google/protobuf/internal/%s.py" % m, "python") | |
287 native.py_test( | 300 native.py_test( |
288 name="py_%s" % m, | 301 name="py_%s" % m, |
289 srcs=[s], | 302 srcs=[s], |
290 main=s, | 303 main=s, |
291 **kargs) | 304 **kargs) |
OLD | NEW |