blob: 71eaba22f0172af88aaa81b0c16836d9bb242b20 [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
Jisi Liu993fb702015-10-19 17:19:49 -0700202def py_proto_library(
203 name,
204 srcs=[],
205 deps=[],
206 py_libs=[],
207 py_extra_srcs=[],
208 include=None,
David Z. Chen985c9682016-02-11 18:11:10 -0800209 default_runtime="//:protobuf_python",
210 protoc="//:protoc",
Jisi Liu993fb702015-10-19 17:19:49 -0700211 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700212 """Bazel rule to create a Python protobuf library from proto source files
213
Jisi Liud4bef7d2015-11-02 12:24:32 -0800214 NOTE: the rule is only an internal workaround to generate protos. The
215 interface may change and the rule may be removed when bazel has introduced
216 the native rule.
217
Jisi Liu7b948cc2015-10-19 17:56:27 -0700218 Args:
219 name: the name of the py_proto_library.
220 srcs: the .proto files of the py_proto_library.
221 deps: a list of dependency labels; must be py_proto_library.
222 py_libs: a list of other py_library targets depended by the generated
223 py_library.
224 py_extra_srcs: extra source files that will be added to the output
225 py_library. This attribute is used for internal bootstrapping.
226 include: a string indicating the include path of the .proto files.
Jisi Liube92ffb2015-10-27 15:11:38 -0700227 default_runtime: the implicitly default runtime which will be depended on by
228 the generated py_library target.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700229 protoc: the label of the protocol compiler to generate the sources.
230 **kargs: other keyword arguments that are passed to cc_library.
231
232 """
Jisi Liu993fb702015-10-19 17:19:49 -0700233 outs = _PyOuts(srcs)
Jisi Liu53a56be2015-10-20 15:18:20 -0700234
235 includes = []
236 if include != None:
237 includes = [include]
238
Jisi Liu993fb702015-10-19 17:19:49 -0700239 _proto_gen(
240 name=name + "_genproto",
241 srcs=srcs,
242 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700243 includes=includes,
Jisi Liu993fb702015-10-19 17:19:49 -0700244 protoc=protoc,
245 gen_py=1,
246 outs=outs,
Martin Maly8e0c9a32015-12-04 17:44:58 -0800247 visibility=["//visibility:public"],
Jisi Liu993fb702015-10-19 17:19:49 -0700248 )
249
Jisi Liube92ffb2015-10-27 15:11:38 -0700250 if default_runtime and not default_runtime in py_libs + deps:
251 py_libs += [default_runtime]
252
Jisi Liu993fb702015-10-19 17:19:49 -0700253 native.py_library(
254 name=name,
Jisi Liua33fa8e2015-10-20 15:30:44 -0700255 srcs=outs+py_extra_srcs,
256 deps=py_libs+deps,
David Z. Chen985c9682016-02-11 18:11:10 -0800257 imports=includes,
Jisi Liu993fb702015-10-19 17:19:49 -0700258 **kargs)
259
260def internal_protobuf_py_tests(
261 name,
262 modules=[],
263 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700264 """Bazel rules to create batch tests for protobuf internal.
265
266 Args:
267 name: the name of the rule.
268 modules: a list of modules for tests. The macro will create a py_test for
269 each of the parameter with the source "google/protobuf/%s.py"
270 kargs: extra parameters that will be passed into the py_test.
271
272 """
Jisi Liu993fb702015-10-19 17:19:49 -0700273 for m in modules:
David Z. Chen985c9682016-02-11 18:11:10 -0800274 s = "python/google/protobuf/internal/%s.py" % m
Jisi Liu993fb702015-10-19 17:19:49 -0700275 native.py_test(
276 name="py_%s" % m,
Jisi Liu7b948cc2015-10-19 17:56:27 -0700277 srcs=[s],
278 main=s,
Jisi Liu993fb702015-10-19 17:19:49 -0700279 **kargs)