blob: 27e88850f5325128b08e8ca460bc14d741da5de9 [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 Liu6dac0822015-10-19 14:41:00 -07004 if ctx.attr.include == None:
5 return ""
Jisi Liu3101e732015-10-16 12:46:26 -07006 if not ctx.attr.include:
Jisi Liu39362b32015-10-14 17:12:11 -07007 return ctx.label.package
8 if not ctx.label.package:
Jisi Liu3101e732015-10-16 12:46:26 -07009 return ctx.attr.include
10 return ctx.label.package + '/' + ctx.attr.include
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 Liu39362b32015-10-14 17:12:11 -070047 import_flags = ["-I" + gen_dir]
48 for dep in ctx.attr.deps:
49 import_flags += dep.proto.import_flags
50 deps += dep.proto.deps
51
52 args = []
53 if ctx.attr.gen_cc:
54 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
55 if ctx.attr.gen_py:
56 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
57
58 if args:
59 ctx.action(
Jisi Liu125a91b2015-10-14 17:37:39 -070060 inputs=srcs + deps,
Jisi Liu39362b32015-10-14 17:12:11 -070061 outputs=ctx.outputs.outs,
Jisi Liu125a91b2015-10-14 17:37:39 -070062 arguments=args + import_flags + [s.path for s in srcs],
Jisi Liu9c7d9c02015-10-15 10:51:32 -070063 executable=ctx.executable.protoc,
Jisi Liu39362b32015-10-14 17:12:11 -070064 )
65
66 return struct(
67 proto=struct(
Jisi Liu125a91b2015-10-14 17:37:39 -070068 srcs=srcs,
69 import_flags=import_flags,
70 deps=deps,
71 ),
72 )
Jisi Liu39362b32015-10-14 17:12:11 -070073
Jisi Liu9c7d9c02015-10-15 10:51:32 -070074_proto_gen = rule(
Jisi Liu39362b32015-10-14 17:12:11 -070075 attrs = {
Jisi Liuee8131a2015-10-14 17:20:05 -070076 "srcs": attr.label_list(allow_files = True),
77 "deps": attr.label_list(providers = ["proto"]),
Jisi Liu3101e732015-10-16 12:46:26 -070078 "include": attr.string(),
Jisi Liuee8131a2015-10-14 17:20:05 -070079 "protoc": attr.label(
80 executable = True,
81 single_file = True,
82 mandatory = True,
83 ),
84 "gen_cc": attr.bool(),
85 "gen_py": attr.bool(),
86 "outs": attr.output_list(),
87 },
88 output_to_genfiles = True,
Jisi Liu9c7d9c02015-10-15 10:51:32 -070089 implementation = _proto_gen_impl,
Jisi Liu39362b32015-10-14 17:12:11 -070090)
91
92def cc_proto_library(
Jisi Liu125a91b2015-10-14 17:37:39 -070093 name,
94 srcs=[],
Jisi Liu125a91b2015-10-14 17:37:39 -070095 deps=[],
Jisi Liud8701b52015-10-16 11:44:21 -070096 cc_libs=[],
Jisi Liu6dac0822015-10-19 14:41:00 -070097 include=None,
Jisi Liu3101e732015-10-16 12:46:26 -070098 protoc=":protoc",
99 internal_bootstrap_hack=False,
Jisi Liu125a91b2015-10-14 17:37:39 -0700100 **kargs):
Jisi Liu3101e732015-10-16 12:46:26 -0700101 """Bazel rule to create a C++ protobuf library from proto source files
102
103 Args:
104 name: the name of the cc_proto_library.
105 srcs: the .proto files of the cc_proto_library.
106 deps: a list of dependency labels; must be cc_proto_library.
107 cc_libs: a list of other cc_library targets depended by the generated
108 cc_library.
109 include: a string indicating the include path of the .proto files.
110 protoc: the label of the protocol compiler to generate the sources.
111 internal_bootstrap_hack: a flag indicate the cc_proto_library is used only
112 for bootstraping. When it is set to True, no files will be generated.
113 The rule will simply be a provider for .proto files, so that other
114 cc_proto_library can depend on it.
115 **kargs: other keyword arguments that are passed to cc_library.
116
117 """
Jisi Liu39362b32015-10-14 17:12:11 -0700118
119 if internal_bootstrap_hack:
120 # For pre-checked-in generated files, we add the internal_bootstrap_hack
121 # which will skip the codegen action.
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700122 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700123 name=name + "_genproto",
124 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700125 deps=[s + "_genproto" for s in deps],
Jisi Liu3101e732015-10-16 12:46:26 -0700126 include=include,
Jisi Liu125a91b2015-10-14 17:37:39 -0700127 protoc=protoc,
Jisi Liu39362b32015-10-14 17:12:11 -0700128 )
129 # An empty cc_library to make rule dependency consistent.
130 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700131 name=name,
Jisi Liud8701b52015-10-16 11:44:21 -0700132 **kargs)
Jisi Liu39362b32015-10-14 17:12:11 -0700133 return
134
Jisi Liu993fb702015-10-19 17:19:49 -0700135 outs = _CcOuts(srcs)
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700136 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700137 name=name + "_genproto",
138 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700139 deps=[s + "_genproto" for s in deps],
Jisi Liu3101e732015-10-16 12:46:26 -0700140 include=include,
Jisi Liu125a91b2015-10-14 17:37:39 -0700141 protoc=protoc,
142 gen_cc=1,
143 outs=outs,
Jisi Liu39362b32015-10-14 17:12:11 -0700144 )
145
Jisi Liu6dac0822015-10-19 14:41:00 -0700146 includes = []
147 if include != None:
148 includes = [include]
149
Jisi Liu39362b32015-10-14 17:12:11 -0700150 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700151 name=name,
152 srcs=outs,
Jisi Liud8701b52015-10-16 11:44:21 -0700153 deps=cc_libs + deps,
Jisi Liu6dac0822015-10-19 14:41:00 -0700154 includes=includes,
Jisi Liud8701b52015-10-16 11:44:21 -0700155 **kargs)
Jisi Liu993fb702015-10-19 17:19:49 -0700156
157
158def copied_srcs(
159 name,
160 srcs,
161 include,
162 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700163 """Bazel rule to fix sources file to workaround with python path issues.
164
165 Args:
166 name: the name of the copied_srcs rule, which will be the name of the
167 generated filegroup.
168 srcs: the source files to be copied.
169 include: the expected import root of the source.
170 **kargs: extra arguments that will be passed into the filegroup.
171 """
Jisi Liu993fb702015-10-19 17:19:49 -0700172 outs = [_RelativeOutputPath(s, include) for s in srcs]
173
174 native.genrule(
175 name=name+"_genrule",
176 srcs=srcs,
177 outs=outs,
178 cmd=";".join(["cp $(location %s) $(location %s)" % \
179 (s, _RelativeOutputPath(s, include)) \
180 for s in srcs]))
181
182 native.filegroup(
183 name=name,
184 srcs=outs,
185 **kargs)
186
187
188def py_proto_library(
189 name,
190 srcs=[],
191 deps=[],
192 py_libs=[],
193 py_extra_srcs=[],
194 include=None,
195 protoc=":protoc",
196 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700197 """Bazel rule to create a Python protobuf library from proto source files
198
199 Args:
200 name: the name of the py_proto_library.
201 srcs: the .proto files of the py_proto_library.
202 deps: a list of dependency labels; must be py_proto_library.
203 py_libs: a list of other py_library targets depended by the generated
204 py_library.
205 py_extra_srcs: extra source files that will be added to the output
206 py_library. This attribute is used for internal bootstrapping.
207 include: a string indicating the include path of the .proto files.
208 protoc: the label of the protocol compiler to generate the sources.
209 **kargs: other keyword arguments that are passed to cc_library.
210
211 """
Jisi Liu993fb702015-10-19 17:19:49 -0700212 outs = _PyOuts(srcs)
213 _proto_gen(
214 name=name + "_genproto",
215 srcs=srcs,
216 deps=[s + "_genproto" for s in deps],
217 include=include,
218 protoc=protoc,
219 gen_py=1,
220 outs=outs,
221 )
222
Jisi Liu993fb702015-10-19 17:19:49 -0700223 if include != None:
Jisi Liu7b948cc2015-10-19 17:56:27 -0700224 # Copy the output files to the desired location to make the import work.
225 copied_srcs_name=name + "_copied_srcs"
Jisi Liu993fb702015-10-19 17:19:49 -0700226 copied_srcs(
227 name=copied_srcs_name,
228 srcs=outs,
229 include=include)
230 srcs=[copied_srcs_name]
231
232 native.py_library(
233 name=name,
234 srcs=srcs+py_extra_srcs,
235 deps=py_libs,
236 **kargs)
237
238def internal_protobuf_py_tests(
239 name,
240 modules=[],
241 **kargs):
Jisi Liu7b948cc2015-10-19 17:56:27 -0700242 """Bazel rules to create batch tests for protobuf internal.
243
244 Args:
245 name: the name of the rule.
246 modules: a list of modules for tests. The macro will create a py_test for
247 each of the parameter with the source "google/protobuf/%s.py"
248 kargs: extra parameters that will be passed into the py_test.
249
250 """
Jisi Liu993fb702015-10-19 17:19:49 -0700251 for m in modules:
Jisi Liu7b948cc2015-10-19 17:56:27 -0700252 s = _RelativeOutputPath(
253 "python/google/protobuf/internal/%s.py" % m, "python")
Jisi Liu993fb702015-10-19 17:19:49 -0700254 native.py_test(
255 name="py_%s" % m,
Jisi Liu7b948cc2015-10-19 17:56:27 -0700256 srcs=[s],
257 main=s,
Jisi Liu993fb702015-10-19 17:19:49 -0700258 **kargs)