blob: 9ed7c54ac766ab03ad2e53b457a6bd546ffb18a1 [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(
84 executable = True,
85 single_file = True,
86 mandatory = True,
87 ),
88 "gen_cc": attr.bool(),
89 "gen_py": attr.bool(),
90 "outs": attr.output_list(),
91 },
92 output_to_genfiles = True,
Jisi Liu9c7d9c02015-10-15 10:51:32 -070093 implementation = _proto_gen_impl,
Jisi Liu39362b32015-10-14 17:12:11 -070094)
95
96def cc_proto_library(
Jisi Liu125a91b2015-10-14 17:37:39 -070097 name,
98 srcs=[],
Jisi Liu125a91b2015-10-14 17:37:39 -070099 deps=[],
Jisi Liud8701b52015-10-16 11:44:21 -0700100 cc_libs=[],
Jisi Liu6dac0822015-10-19 14:41:00 -0700101 include=None,
Jisi Liu04658a32015-10-20 15:00:13 -0700102 protoc="//google/protobuf:protoc",
Jisi Liu3101e732015-10-16 12:46:26 -0700103 internal_bootstrap_hack=False,
Jisi Liube92ffb2015-10-27 15:11:38 -0700104 default_runtime="//google/protobuf:protobuf",
Jisi Liu125a91b2015-10-14 17:37:39 -0700105 **kargs):
Jisi Liu3101e732015-10-16 12:46:26 -0700106 """Bazel rule to create a C++ protobuf library from proto source files
107
Jisi Liud4bef7d2015-11-02 12:24:32 -0800108 NOTE: the rule is only an internal workaround to generate protos. The
109 interface may change and the rule may be removed when bazel has introduced
110 the native rule.
111
Jisi Liu3101e732015-10-16 12:46:26 -0700112 Args:
113 name: the name of the cc_proto_library.
114 srcs: the .proto files of the cc_proto_library.
115 deps: a list of dependency labels; must be cc_proto_library.
116 cc_libs: a list of other cc_library targets depended by the generated
117 cc_library.
118 include: a string indicating the include path of the .proto files.
119 protoc: the label of the protocol compiler to generate the sources.
120 internal_bootstrap_hack: a flag indicate the cc_proto_library is used only
121 for bootstraping. When it is set to True, no files will be generated.
122 The rule will simply be a provider for .proto files, so that other
123 cc_proto_library can depend on it.
Jisi Liube92ffb2015-10-27 15:11:38 -0700124 default_runtime: the implicitly default runtime which will be depended on by
125 the generated cc_library target.
Jisi Liu3101e732015-10-16 12:46:26 -0700126 **kargs: other keyword arguments that are passed to cc_library.
127
128 """
Jisi Liu39362b32015-10-14 17:12:11 -0700129
Jisi Liu53a56be2015-10-20 15:18:20 -0700130 includes = []
131 if include != None:
132 includes = [include]
133
Jisi Liu39362b32015-10-14 17:12:11 -0700134 if internal_bootstrap_hack:
135 # For pre-checked-in generated files, we add the internal_bootstrap_hack
136 # which will skip the codegen action.
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700137 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700138 name=name + "_genproto",
139 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700140 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700141 includes=includes,
Jisi Liu125a91b2015-10-14 17:37:39 -0700142 protoc=protoc,
Jisi Liu39362b32015-10-14 17:12:11 -0700143 )
144 # An empty cc_library to make rule dependency consistent.
145 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700146 name=name,
Jisi Liud8701b52015-10-16 11:44:21 -0700147 **kargs)
Jisi Liu39362b32015-10-14 17:12:11 -0700148 return
149
Jisi Liu993fb702015-10-19 17:19:49 -0700150 outs = _CcOuts(srcs)
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700151 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700152 name=name + "_genproto",
153 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700154 deps=[s + "_genproto" for s in deps],
Jisi Liu53a56be2015-10-20 15:18:20 -0700155 includes=includes,
Jisi Liu125a91b2015-10-14 17:37:39 -0700156 protoc=protoc,
157 gen_cc=1,
158 outs=outs,
Jisi Liu39362b32015-10-14 17:12:11 -0700159 )
160
Jisi Liube92ffb2015-10-27 15:11:38 -0700161 if default_runtime and not default_runtime in cc_libs:
162 cc_libs += [default_runtime]
Jisi Liu6dac0822015-10-19 14:41:00 -0700163
Jisi Liu39362b32015-10-14 17:12:11 -0700164 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700165 name=name,
166 srcs=outs,
Jisi Liud8701b52015-10-16 11:44:21 -0700167 deps=cc_libs + deps,
Jisi Liu6dac0822015-10-19 14:41:00 -0700168 includes=includes,
Jisi Liud8701b52015-10-16 11:44:21 -0700169 **kargs)
Jisi Liu993fb702015-10-19 17:19:49 -0700170
171
Jisi Liubc4fd152015-10-20 16:02:58 -0700172def internal_copied_filegroup(
Jisi Liu993fb702015-10-19 17:19:49 -0700173 name,
174 srcs,
175 include,
176 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700177 """Bazel rule to fix sources file to workaround with python path issues.
178
179 Args:
Jisi Liubc4fd152015-10-20 16:02:58 -0700180 name: the name of the internal_copied_filegroup rule, which will be the
181 name of the generated filegroup.
Jisi Liu7b948cc2015-10-19 17:56:27 -0700182 srcs: the source files to be copied.
183 include: the expected import root of the source.
184 **kargs: extra arguments that will be passed into the filegroup.
185 """
Jisi Liu993fb702015-10-19 17:19:49 -0700186 outs = [_RelativeOutputPath(s, include) for s in srcs]
187
188 native.genrule(
189 name=name+"_genrule",
190 srcs=srcs,
191 outs=outs,
Jisi Liu6ddcae22015-10-21 10:48:33 -0700192 cmd=" && ".join(["cp $(location %s) $(location %s)" %
193 (s, _RelativeOutputPath(s, include))
194 for s in srcs]))
Jisi Liu993fb702015-10-19 17:19:49 -0700195
196 native.filegroup(
197 name=name,
198 srcs=outs,
199 **kargs)
200
201
202def py_proto_library(
203 name,
204 srcs=[],
205 deps=[],
206 py_libs=[],
207 py_extra_srcs=[],
208 include=None,
Jisi Liube92ffb2015-10-27 15:11:38 -0700209 default_runtime="//google/protobuf:protobuf_python",
Jisi Liu04658a32015-10-20 15:00:13 -0700210 protoc="//google/protobuf: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,
247 )
248
Jisi Liu993fb702015-10-19 17:19:49 -0700249 if include != None:
Jisi Liu7b948cc2015-10-19 17:56:27 -0700250 # Copy the output files to the desired location to make the import work.
Jisi Liubc4fd152015-10-20 16:02:58 -0700251 internal_copied_filegroup_name=name + "_internal_copied_filegroup"
252 internal_copied_filegroup(
253 name=internal_copied_filegroup_name,
Jisi Liu993fb702015-10-19 17:19:49 -0700254 srcs=outs,
255 include=include)
Jisi Liubc4fd152015-10-20 16:02:58 -0700256 outs=[internal_copied_filegroup_name]
Jisi Liu993fb702015-10-19 17:19:49 -0700257
Jisi Liube92ffb2015-10-27 15:11:38 -0700258 if default_runtime and not default_runtime in py_libs + deps:
259 py_libs += [default_runtime]
260
Jisi Liu993fb702015-10-19 17:19:49 -0700261 native.py_library(
262 name=name,
Jisi Liua33fa8e2015-10-20 15:30:44 -0700263 srcs=outs+py_extra_srcs,
264 deps=py_libs+deps,
Jisi Liu993fb702015-10-19 17:19:49 -0700265 **kargs)
266
267def internal_protobuf_py_tests(
268 name,
269 modules=[],
270 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700271 """Bazel rules to create batch tests for protobuf internal.
272
273 Args:
274 name: the name of the rule.
275 modules: a list of modules for tests. The macro will create a py_test for
276 each of the parameter with the source "google/protobuf/%s.py"
277 kargs: extra parameters that will be passed into the py_test.
278
279 """
Jisi Liu993fb702015-10-19 17:19:49 -0700280 for m in modules:
Jisi Liu7b948cc2015-10-19 17:56:27 -0700281 s = _RelativeOutputPath(
282 "python/google/protobuf/internal/%s.py" % m, "python")
Jisi Liu993fb702015-10-19 17:19:49 -0700283 native.py_test(
284 name="py_%s" % m,
Jisi Liu7b948cc2015-10-19 17:56:27 -0700285 srcs=[s],
286 main=s,
Jisi Liu993fb702015-10-19 17:19:49 -0700287 **kargs)