blob: e5af3339645af3883b62802bf261a8f3f57a12a2 [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,
Jisi Liu04658a32015-10-20 15:00:13 -0700120 protoc="//google/protobuf: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,
Jisi Liube92ffb2015-10-27 15:11:38 -0700123 default_runtime="//google/protobuf: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
Jisi Liubc4fd152015-10-20 16:02:58 -0700202def internal_copied_filegroup(
Jisi Liu993fb702015-10-19 17:19:49 -0700203 name,
204 srcs,
205 include,
206 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700207 """Bazel rule to fix sources file to workaround with python path issues.
208
209 Args:
Jisi Liubc4fd152015-10-20 16:02:58 -0700210 name: the name of the internal_copied_filegroup rule, which will be the
211 name of the generated filegroup.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700212 srcs: the source files to be copied.
213 include: the expected import root of the source.
214 **kargs: extra arguments that will be passed into the filegroup.
215 """
Jisi Liu993fb702015-10-19 17:19:49 -0700216 outs = [_RelativeOutputPath(s, include) for s in srcs]
217
218 native.genrule(
219 name=name+"_genrule",
220 srcs=srcs,
221 outs=outs,
Jisi Liu6ddcae22015-10-21 10:48:33 -0700222 cmd=" && ".join(["cp $(location %s) $(location %s)" %
223 (s, _RelativeOutputPath(s, include))
224 for s in srcs]))
Jisi Liu993fb702015-10-19 17:19:49 -0700225
226 native.filegroup(
227 name=name,
228 srcs=outs,
229 **kargs)
230
Jisi Liu993fb702015-10-19 17:19:49 -0700231def py_proto_library(
232 name,
233 srcs=[],
234 deps=[],
235 py_libs=[],
236 py_extra_srcs=[],
237 include=None,
Jisi Liube92ffb2015-10-27 15:11:38 -0700238 default_runtime="//google/protobuf:protobuf_python",
Jisi Liu04658a32015-10-20 15:00:13 -0700239 protoc="//google/protobuf:protoc",
Jisi Liu993fb702015-10-19 17:19:49 -0700240 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700241 """Bazel rule to create a Python protobuf library from proto source files
242
Jisi Liud4bef7d2015-11-02 12:24:32 -0800243 NOTE: the rule is only an internal workaround to generate protos. The
244 interface may change and the rule may be removed when bazel has introduced
245 the native rule.
246
Jisi Liu7b948cc2015-10-19 17:56:27 -0700247 Args:
248 name: the name of the py_proto_library.
249 srcs: the .proto files of the py_proto_library.
250 deps: a list of dependency labels; must be py_proto_library.
251 py_libs: a list of other py_library targets depended by the generated
252 py_library.
253 py_extra_srcs: extra source files that will be added to the output
254 py_library. This attribute is used for internal bootstrapping.
255 include: a string indicating the include path of the .proto files.
Jisi Liube92ffb2015-10-27 15:11:38 -0700256 default_runtime: the implicitly default runtime which will be depended on by
257 the generated py_library target.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700258 protoc: the label of the protocol compiler to generate the sources.
259 **kargs: other keyword arguments that are passed to cc_library.
260
261 """
Jisi Liu993fb702015-10-19 17:19:49 -0700262 outs = _PyOuts(srcs)
Jisi Liu53a56be2015-10-20 15:18:20 -0700263
264 includes = []
265 if include != None:
266 includes = [include]
267
Jisi Liu993fb702015-10-19 17:19:49 -0700268 _proto_gen(
269 name=name + "_genproto",
270 srcs=srcs,
271 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700272 includes=includes,
Jisi Liu993fb702015-10-19 17:19:49 -0700273 protoc=protoc,
274 gen_py=1,
275 outs=outs,
Martin Maly8e0c9a32015-12-04 17:44:58 -0800276 visibility=["//visibility:public"],
Jisi Liu993fb702015-10-19 17:19:49 -0700277 )
278
Jisi Liu993fb702015-10-19 17:19:49 -0700279 if include != None:
Jisi Liu7b948cc2015-10-19 17:56:27 -0700280 # Copy the output files to the desired location to make the import work.
Jisi Liubc4fd152015-10-20 16:02:58 -0700281 internal_copied_filegroup_name=name + "_internal_copied_filegroup"
282 internal_copied_filegroup(
283 name=internal_copied_filegroup_name,
Jisi Liu993fb702015-10-19 17:19:49 -0700284 srcs=outs,
285 include=include)
Jisi Liubc4fd152015-10-20 16:02:58 -0700286 outs=[internal_copied_filegroup_name]
Jisi Liu993fb702015-10-19 17:19:49 -0700287
Jisi Liube92ffb2015-10-27 15:11:38 -0700288 if default_runtime and not default_runtime in py_libs + deps:
289 py_libs += [default_runtime]
290
Jisi Liu993fb702015-10-19 17:19:49 -0700291 native.py_library(
292 name=name,
Jisi Liua33fa8e2015-10-20 15:30:44 -0700293 srcs=outs+py_extra_srcs,
294 deps=py_libs+deps,
Jisi Liu993fb702015-10-19 17:19:49 -0700295 **kargs)
296
297def internal_protobuf_py_tests(
298 name,
299 modules=[],
300 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700301 """Bazel rules to create batch tests for protobuf internal.
302
303 Args:
304 name: the name of the rule.
305 modules: a list of modules for tests. The macro will create a py_test for
306 each of the parameter with the source "google/protobuf/%s.py"
307 kargs: extra parameters that will be passed into the py_test.
308
309 """
Jisi Liu993fb702015-10-19 17:19:49 -0700310 for m in modules:
Jisi Liu7b948cc2015-10-19 17:56:27 -0700311 s = _RelativeOutputPath(
312 "python/google/protobuf/internal/%s.py" % m, "python")
Jisi Liu993fb702015-10-19 17:19:49 -0700313 native.py_test(
314 name="py_%s" % m,
Jisi Liu7b948cc2015-10-19 17:56:27 -0700315 srcs=[s],
316 main=s,
Jisi Liu993fb702015-10-19 17:19:49 -0700317 **kargs)