blob: 87aed9c81e71c7a3c6c41fe8c6f646480e92e19a [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):
163 outs = [_RelativeOutputPath(s, include) for s in srcs]
164
165 native.genrule(
166 name=name+"_genrule",
167 srcs=srcs,
168 outs=outs,
169 cmd=";".join(["cp $(location %s) $(location %s)" % \
170 (s, _RelativeOutputPath(s, include)) \
171 for s in srcs]))
172
173 native.filegroup(
174 name=name,
175 srcs=outs,
176 **kargs)
177
178
179def py_proto_library(
180 name,
181 srcs=[],
182 deps=[],
183 py_libs=[],
184 py_extra_srcs=[],
185 include=None,
186 protoc=":protoc",
187 **kargs):
188 outs = _PyOuts(srcs)
189 _proto_gen(
190 name=name + "_genproto",
191 srcs=srcs,
192 deps=[s + "_genproto" for s in deps],
193 include=include,
194 protoc=protoc,
195 gen_py=1,
196 outs=outs,
197 )
198
199 copied_srcs_name=name + "_copied_srcs"
200 if include != None:
201 copied_srcs(
202 name=copied_srcs_name,
203 srcs=outs,
204 include=include)
205 srcs=[copied_srcs_name]
206
207 native.py_library(
208 name=name,
209 srcs=srcs+py_extra_srcs,
210 deps=py_libs,
211 **kargs)
212
213def internal_protobuf_py_tests(
214 name,
215 modules=[],
216 **kargs):
217 for m in modules:
218 native.py_test(
219 name="py_%s" % m,
220 srcs=["google/protobuf/internal/%s.py" % m],
221 main="google/protobuf/internal/%s.py" % m,
222 **kargs)