blob: 86c6f251e6fde820a8592fd2c1f599585b804a2c [file] [log] [blame]
Jisi Liu39362b32015-10-14 17:12:11 -07001# -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED
2
Jisi Liu993fb702015-10-19 17:19:49 -07003def _GenDir(ctx):
Jisi Liu53a56be2015-10-20 15:18:20 -07004 if not ctx.attr.includes:
Jisi Liu6dac0822015-10-19 14:41:00 -07005 return ""
Jisi Liu53a56be2015-10-20 15:18:20 -07006 if not ctx.attr.includes[0]:
Jisi Liu39362b32015-10-14 17:12:11 -07007 return ctx.label.package
8 if not ctx.label.package:
Jisi Liu53a56be2015-10-20 15:18:20 -07009 return ctx.attr.includes[0]
10 return ctx.label.package + '/' + ctx.attr.includes[0]
Jisi Liu39362b32015-10-14 17:12:11 -070011
Jisi Liu993fb702015-10-19 17:19:49 -070012def _CcOuts(srcs):
Jisi Liu39362b32015-10-14 17:12:11 -070013 return [s[:-len(".proto")] + ".pb.h" for s in srcs] + \
Jisi Liu125a91b2015-10-14 17:37:39 -070014 [s[:-len(".proto")] + ".pb.cc" for s in srcs]
Jisi Liu39362b32015-10-14 17:12:11 -070015
Jisi Liu993fb702015-10-19 17:19:49 -070016def _PyOuts(srcs):
Jisi Liu125a91b2015-10-14 17:37:39 -070017 return [s[:-len(".proto")] + "_pb2.py" for s in srcs]
Jisi Liu39362b32015-10-14 17:12:11 -070018
Jisi Liu993fb702015-10-19 17:19:49 -070019def _RelativeOutputPath(path, include):
20 if include == None:
21 return path
22
23 if not path.startswith(include):
24 fail("Include path %s isn't part of the path %s." % (include, path))
25
26 if include and include[-1] != '/':
27 include = include + '/'
28
29 path = path[len(include):]
30
31 if not path.startswith(PACKAGE_NAME):
32 fail("The package %s is not within the path %s" % (PACKAGE_NAME, path))
33
34 if not PACKAGE_NAME:
35 return path
36
37 return path[len(PACKAGE_NAME)+1:]
38
39
40
Jisi Liu9c7d9c02015-10-15 10:51:32 -070041def _proto_gen_impl(ctx):
42 """General implementation for generating protos"""
Jisi Liu39362b32015-10-14 17:12:11 -070043 srcs = ctx.files.srcs
44 deps = []
45 deps += ctx.files.srcs
Jisi Liu993fb702015-10-19 17:19:49 -070046 gen_dir = _GenDir(ctx)
Jisi Liu53a56be2015-10-20 15:18:20 -070047 if gen_dir:
48 import_flags = ["-I" + gen_dir]
49 else:
50 import_flags = ["-I."]
51
Jisi Liu39362b32015-10-14 17:12:11 -070052 for dep in ctx.attr.deps:
53 import_flags += dep.proto.import_flags
54 deps += dep.proto.deps
55
56 args = []
57 if ctx.attr.gen_cc:
58 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
59 if ctx.attr.gen_py:
60 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
61
62 if args:
63 ctx.action(
Jisi Liu125a91b2015-10-14 17:37:39 -070064 inputs=srcs + deps,
Jisi Liu39362b32015-10-14 17:12:11 -070065 outputs=ctx.outputs.outs,
Jisi Liu125a91b2015-10-14 17:37:39 -070066 arguments=args + import_flags + [s.path for s in srcs],
Jisi Liu9c7d9c02015-10-15 10:51:32 -070067 executable=ctx.executable.protoc,
Jisi Liu39362b32015-10-14 17:12:11 -070068 )
69
70 return struct(
71 proto=struct(
Jisi Liu125a91b2015-10-14 17:37:39 -070072 srcs=srcs,
73 import_flags=import_flags,
74 deps=deps,
75 ),
76 )
Jisi Liu39362b32015-10-14 17:12:11 -070077
Jisi Liu9c7d9c02015-10-15 10:51:32 -070078_proto_gen = rule(
Jisi Liu39362b32015-10-14 17:12:11 -070079 attrs = {
Jisi Liuee8131a2015-10-14 17:20:05 -070080 "srcs": attr.label_list(allow_files = True),
81 "deps": attr.label_list(providers = ["proto"]),
Jisi Liu53a56be2015-10-20 15:18:20 -070082 "includes": attr.string_list(),
Jisi Liuee8131a2015-10-14 17:20:05 -070083 "protoc": attr.label(
Andrew Harp38f131f2015-11-03 16:39:32 -050084 cfg = HOST_CFG,
Jisi Liuee8131a2015-10-14 17:20:05 -070085 executable = True,
86 single_file = True,
87 mandatory = True,
88 ),
89 "gen_cc": attr.bool(),
90 "gen_py": attr.bool(),
91 "outs": attr.output_list(),
92 },
93 output_to_genfiles = True,
Jisi Liu9c7d9c02015-10-15 10:51:32 -070094 implementation = _proto_gen_impl,
Jisi Liu39362b32015-10-14 17:12:11 -070095)
96
97def cc_proto_library(
Jisi Liu125a91b2015-10-14 17:37:39 -070098 name,
99 srcs=[],
Jisi Liu125a91b2015-10-14 17:37:39 -0700100 deps=[],
Jisi Liud8701b52015-10-16 11:44:21 -0700101 cc_libs=[],
Jisi Liu6dac0822015-10-19 14:41:00 -0700102 include=None,
Jisi Liu04658a32015-10-20 15:00:13 -0700103 protoc="//google/protobuf:protoc",
Jisi Liu3101e732015-10-16 12:46:26 -0700104 internal_bootstrap_hack=False,
Jisi Liube92ffb2015-10-27 15:11:38 -0700105 default_runtime="//google/protobuf:protobuf",
Jisi Liu125a91b2015-10-14 17:37:39 -0700106 **kargs):
Jisi Liu3101e732015-10-16 12:46:26 -0700107 """Bazel rule to create a C++ protobuf library from proto source files
108
Jisi Liud4bef7d2015-11-02 12:24:32 -0800109 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
111 the native rule.
112
Jisi Liu3101e732015-10-16 12:46:26 -0700113 Args:
114 name: the name of the cc_proto_library.
115 srcs: the .proto files of the cc_proto_library.
116 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
118 cc_library.
119 include: a string indicating the include path of the .proto files.
120 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
122 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
124 cc_proto_library can depend on it.
Jisi Liube92ffb2015-10-27 15:11:38 -0700125 default_runtime: the implicitly default runtime which will be depended on by
126 the generated cc_library target.
Jisi Liu3101e732015-10-16 12:46:26 -0700127 **kargs: other keyword arguments that are passed to cc_library.
128
129 """
Jisi Liu39362b32015-10-14 17:12:11 -0700130
Jisi Liu53a56be2015-10-20 15:18:20 -0700131 includes = []
132 if include != None:
133 includes = [include]
134
Jisi Liu39362b32015-10-14 17:12:11 -0700135 if internal_bootstrap_hack:
136 # For pre-checked-in generated files, we add the internal_bootstrap_hack
137 # which will skip the codegen action.
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700138 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700139 name=name + "_genproto",
140 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700141 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700142 includes=includes,
Jisi Liu125a91b2015-10-14 17:37:39 -0700143 protoc=protoc,
Jisi Liu39362b32015-10-14 17:12:11 -0700144 )
145 # An empty cc_library to make rule dependency consistent.
146 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700147 name=name,
Jisi Liud8701b52015-10-16 11:44:21 -0700148 **kargs)
Jisi Liu39362b32015-10-14 17:12:11 -0700149 return
150
Jisi Liu993fb702015-10-19 17:19:49 -0700151 outs = _CcOuts(srcs)
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700152 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700153 name=name + "_genproto",
154 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700155 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700156 includes=includes,
Jisi Liu125a91b2015-10-14 17:37:39 -0700157 protoc=protoc,
158 gen_cc=1,
159 outs=outs,
Jisi Liu39362b32015-10-14 17:12:11 -0700160 )
161
Jisi Liube92ffb2015-10-27 15:11:38 -0700162 if default_runtime and not default_runtime in cc_libs:
163 cc_libs += [default_runtime]
Jisi Liu6dac0822015-10-19 14:41:00 -0700164
Jisi Liu39362b32015-10-14 17:12:11 -0700165 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700166 name=name,
167 srcs=outs,
Jisi Liud8701b52015-10-16 11:44:21 -0700168 deps=cc_libs + deps,
Jisi Liu6dac0822015-10-19 14:41:00 -0700169 includes=includes,
Jisi Liud8701b52015-10-16 11:44:21 -0700170 **kargs)
Jisi Liu993fb702015-10-19 17:19:49 -0700171
172
Jisi Liubc4fd152015-10-20 16:02:58 -0700173def internal_copied_filegroup(
Jisi Liu993fb702015-10-19 17:19:49 -0700174 name,
175 srcs,
176 include,
177 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700178 """Bazel rule to fix sources file to workaround with python path issues.
179
180 Args:
Jisi Liubc4fd152015-10-20 16:02:58 -0700181 name: the name of the internal_copied_filegroup rule, which will be the
182 name of the generated filegroup.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700183 srcs: the source files to be copied.
184 include: the expected import root of the source.
185 **kargs: extra arguments that will be passed into the filegroup.
186 """
Jisi Liu993fb702015-10-19 17:19:49 -0700187 outs = [_RelativeOutputPath(s, include) for s in srcs]
188
189 native.genrule(
190 name=name+"_genrule",
191 srcs=srcs,
192 outs=outs,
Jisi Liu6ddcae22015-10-21 10:48:33 -0700193 cmd=" && ".join(["cp $(location %s) $(location %s)" %
194 (s, _RelativeOutputPath(s, include))
195 for s in srcs]))
Jisi Liu993fb702015-10-19 17:19:49 -0700196
197 native.filegroup(
198 name=name,
199 srcs=outs,
200 **kargs)
201
202
203def py_proto_library(
204 name,
205 srcs=[],
206 deps=[],
207 py_libs=[],
208 py_extra_srcs=[],
209 include=None,
Jisi Liube92ffb2015-10-27 15:11:38 -0700210 default_runtime="//google/protobuf:protobuf_python",
Jisi Liu04658a32015-10-20 15:00:13 -0700211 protoc="//google/protobuf:protoc",
Jisi Liu993fb702015-10-19 17:19:49 -0700212 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700213 """Bazel rule to create a Python protobuf library from proto source files
214
Jisi Liud4bef7d2015-11-02 12:24:32 -0800215 NOTE: the rule is only an internal workaround to generate protos. The
216 interface may change and the rule may be removed when bazel has introduced
217 the native rule.
218
Jisi Liu7b948cc2015-10-19 17:56:27 -0700219 Args:
220 name: the name of the py_proto_library.
221 srcs: the .proto files of the py_proto_library.
222 deps: a list of dependency labels; must be py_proto_library.
223 py_libs: a list of other py_library targets depended by the generated
224 py_library.
225 py_extra_srcs: extra source files that will be added to the output
226 py_library. This attribute is used for internal bootstrapping.
227 include: a string indicating the include path of the .proto files.
Jisi Liube92ffb2015-10-27 15:11:38 -0700228 default_runtime: the implicitly default runtime which will be depended on by
229 the generated py_library target.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700230 protoc: the label of the protocol compiler to generate the sources.
231 **kargs: other keyword arguments that are passed to cc_library.
232
233 """
Jisi Liu993fb702015-10-19 17:19:49 -0700234 outs = _PyOuts(srcs)
Jisi Liu53a56be2015-10-20 15:18:20 -0700235
236 includes = []
237 if include != None:
238 includes = [include]
239
Jisi Liu993fb702015-10-19 17:19:49 -0700240 _proto_gen(
241 name=name + "_genproto",
242 srcs=srcs,
243 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700244 includes=includes,
Jisi Liu993fb702015-10-19 17:19:49 -0700245 protoc=protoc,
246 gen_py=1,
247 outs=outs,
248 )
249
Jisi Liu993fb702015-10-19 17:19:49 -0700250 if include != None:
Jisi Liu7b948cc2015-10-19 17:56:27 -0700251 # Copy the output files to the desired location to make the import work.
Jisi Liubc4fd152015-10-20 16:02:58 -0700252 internal_copied_filegroup_name=name + "_internal_copied_filegroup"
253 internal_copied_filegroup(
254 name=internal_copied_filegroup_name,
Jisi Liu993fb702015-10-19 17:19:49 -0700255 srcs=outs,
256 include=include)
Jisi Liubc4fd152015-10-20 16:02:58 -0700257 outs=[internal_copied_filegroup_name]
Jisi Liu993fb702015-10-19 17:19:49 -0700258
Jisi Liube92ffb2015-10-27 15:11:38 -0700259 if default_runtime and not default_runtime in py_libs + deps:
260 py_libs += [default_runtime]
261
Jisi Liu993fb702015-10-19 17:19:49 -0700262 native.py_library(
263 name=name,
Jisi Liua33fa8e2015-10-20 15:30:44 -0700264 srcs=outs+py_extra_srcs,
265 deps=py_libs+deps,
Jisi Liu993fb702015-10-19 17:19:49 -0700266 **kargs)
267
268def internal_protobuf_py_tests(
269 name,
270 modules=[],
271 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700272 """Bazel rules to create batch tests for protobuf internal.
273
274 Args:
275 name: the name of the rule.
276 modules: a list of modules for tests. The macro will create a py_test for
277 each of the parameter with the source "google/protobuf/%s.py"
278 kargs: extra parameters that will be passed into the py_test.
279
280 """
Jisi Liu993fb702015-10-19 17:19:49 -0700281 for m in modules:
Jisi Liu7b948cc2015-10-19 17:56:27 -0700282 s = _RelativeOutputPath(
283 "python/google/protobuf/internal/%s.py" % m, "python")
Jisi Liu993fb702015-10-19 17:19:49 -0700284 native.py_test(
285 name="py_%s" % m,
Jisi Liu7b948cc2015-10-19 17:56:27 -0700286 srcs=[s],
287 main=s,
Jisi Liu993fb702015-10-19 17:19:49 -0700288 **kargs)