blob: 45dfc6c26e963f5ffb8a560ce3b8b8c939ccae6c [file] [log] [blame]
Jisi Liu39362b32015-10-14 17:12:11 -07001# -*- mode: python; -*- PYTHON-PREPROCESSING-REQUIRED
2
Jisi Liu39362b32015-10-14 17:12:11 -07003def _gen_dir(ctx):
4 if not ctx.attr.prefix:
5 return ctx.label.package
6 if not ctx.label.package:
7 return ctx.attr.prefix
8 return ctx.label.package + '/' + ctx.attr.prefix
9
10def CcOuts(srcs):
11 return [s[:-len(".proto")] + ".pb.h" for s in srcs] + \
Jisi Liu125a91b2015-10-14 17:37:39 -070012 [s[:-len(".proto")] + ".pb.cc" for s in srcs]
Jisi Liu39362b32015-10-14 17:12:11 -070013
14def PyOuts(srcs):
Jisi Liu125a91b2015-10-14 17:37:39 -070015 return [s[:-len(".proto")] + "_pb2.py" for s in srcs]
Jisi Liu39362b32015-10-14 17:12:11 -070016
17def _proto_srcs_impl(ctx):
18 """General implementation for calculating proto srcs"""
19 srcs = ctx.files.srcs
20 deps = []
21 deps += ctx.files.srcs
22 gen_dir = _gen_dir(ctx)
23 import_flags = ["-I" + gen_dir]
24 for dep in ctx.attr.deps:
25 import_flags += dep.proto.import_flags
26 deps += dep.proto.deps
27
28 args = []
29 if ctx.attr.gen_cc:
30 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
31 if ctx.attr.gen_py:
32 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
33
34 if args:
35 ctx.action(
Jisi Liu125a91b2015-10-14 17:37:39 -070036 inputs=srcs + deps,
Jisi Liu39362b32015-10-14 17:12:11 -070037 outputs=ctx.outputs.outs,
Jisi Liu125a91b2015-10-14 17:37:39 -070038 arguments=args + import_flags + [s.path for s in srcs],
Jisi Liu39362b32015-10-14 17:12:11 -070039 executable=ctx.executable.protoc
40 )
41
42 return struct(
43 proto=struct(
Jisi Liu125a91b2015-10-14 17:37:39 -070044 srcs=srcs,
45 import_flags=import_flags,
46 deps=deps,
47 ),
48 )
Jisi Liu39362b32015-10-14 17:12:11 -070049
50_proto_srcs = rule(
Jisi Liu39362b32015-10-14 17:12:11 -070051 attrs = {
Jisi Liuee8131a2015-10-14 17:20:05 -070052 "srcs": attr.label_list(allow_files = True),
53 "deps": attr.label_list(providers = ["proto"]),
54 "prefix": attr.string(),
55 "protoc": attr.label(
56 executable = True,
57 single_file = True,
58 mandatory = True,
59 ),
60 "gen_cc": attr.bool(),
61 "gen_py": attr.bool(),
62 "outs": attr.output_list(),
63 },
64 output_to_genfiles = True,
65 implementation = _proto_srcs_impl,
Jisi Liu39362b32015-10-14 17:12:11 -070066)
67
68def cc_proto_library(
Jisi Liu125a91b2015-10-14 17:37:39 -070069 name,
70 srcs=[],
71 protoc=":protoc",
72 internal_bootstrap_hack=False,
73 prefix="",
74 proto_deps=[],
75 deps=[],
76 **kargs):
Jisi Liu39362b32015-10-14 17:12:11 -070077
78 if internal_bootstrap_hack:
79 # For pre-checked-in generated files, we add the internal_bootstrap_hack
80 # which will skip the codegen action.
81 _proto_srcs(
Jisi Liu125a91b2015-10-14 17:37:39 -070082 name=name + "_genproto",
83 srcs=srcs,
84 deps=[s + "_genproto" for s in proto_deps],
85 prefix=prefix,
86 protoc=protoc,
Jisi Liu39362b32015-10-14 17:12:11 -070087 )
88 # An empty cc_library to make rule dependency consistent.
89 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -070090 name=name,
Jisi Liu39362b32015-10-14 17:12:11 -070091 **kargs)
92 return
93
94 outs = CcOuts(srcs)
95 _proto_srcs(
Jisi Liu125a91b2015-10-14 17:37:39 -070096 name=name + "_genproto",
97 srcs=srcs,
98 deps=[s + "_genproto" for s in proto_deps],
99 prefix=prefix,
100 protoc=protoc,
101 gen_cc=1,
102 outs=outs,
Jisi Liu39362b32015-10-14 17:12:11 -0700103 )
104
105 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700106 name=name,
107 srcs=outs,
108 deps=deps + proto_deps,
109 includes=[prefix],
Jisi Liu39362b32015-10-14 17:12:11 -0700110 **kargs)