blob: b83f7f5a52b72096329e158af1ab5b377431ffe4 [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):
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 Liu25d75b52015-10-14 17:41:14 -070012def _cc_outs(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 Liu25d75b52015-10-14 17:41:14 -070016def _py_outs(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 Liu9c7d9c02015-10-15 10:51:32 -070019def _proto_gen_impl(ctx):
20 """General implementation for generating protos"""
Jisi Liu39362b32015-10-14 17:12:11 -070021 srcs = ctx.files.srcs
22 deps = []
23 deps += ctx.files.srcs
24 gen_dir = _gen_dir(ctx)
25 import_flags = ["-I" + gen_dir]
26 for dep in ctx.attr.deps:
27 import_flags += dep.proto.import_flags
28 deps += dep.proto.deps
29
30 args = []
31 if ctx.attr.gen_cc:
32 args += ["--cpp_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
33 if ctx.attr.gen_py:
34 args += ["--python_out=" + ctx.var["GENDIR"] + "/" + gen_dir]
35
36 if args:
37 ctx.action(
Jisi Liu125a91b2015-10-14 17:37:39 -070038 inputs=srcs + deps,
Jisi Liu39362b32015-10-14 17:12:11 -070039 outputs=ctx.outputs.outs,
Jisi Liu125a91b2015-10-14 17:37:39 -070040 arguments=args + import_flags + [s.path for s in srcs],
Jisi Liu9c7d9c02015-10-15 10:51:32 -070041 executable=ctx.executable.protoc,
Jisi Liu39362b32015-10-14 17:12:11 -070042 )
43
44 return struct(
45 proto=struct(
Jisi Liu125a91b2015-10-14 17:37:39 -070046 srcs=srcs,
47 import_flags=import_flags,
48 deps=deps,
49 ),
50 )
Jisi Liu39362b32015-10-14 17:12:11 -070051
Jisi Liu9c7d9c02015-10-15 10:51:32 -070052_proto_gen = rule(
Jisi Liu39362b32015-10-14 17:12:11 -070053 attrs = {
Jisi Liuee8131a2015-10-14 17:20:05 -070054 "srcs": attr.label_list(allow_files = True),
55 "deps": attr.label_list(providers = ["proto"]),
Jisi Liu3101e732015-10-16 12:46:26 -070056 "include": attr.string(),
Jisi Liuee8131a2015-10-14 17:20:05 -070057 "protoc": attr.label(
58 executable = True,
59 single_file = True,
60 mandatory = True,
61 ),
62 "gen_cc": attr.bool(),
63 "gen_py": attr.bool(),
64 "outs": attr.output_list(),
65 },
66 output_to_genfiles = True,
Jisi Liu9c7d9c02015-10-15 10:51:32 -070067 implementation = _proto_gen_impl,
Jisi Liu39362b32015-10-14 17:12:11 -070068)
69
70def cc_proto_library(
Jisi Liu125a91b2015-10-14 17:37:39 -070071 name,
72 srcs=[],
Jisi Liu125a91b2015-10-14 17:37:39 -070073 deps=[],
Jisi Liud8701b52015-10-16 11:44:21 -070074 cc_libs=[],
Jisi Liu6dac0822015-10-19 14:41:00 -070075 include=None,
Jisi Liu3101e732015-10-16 12:46:26 -070076 protoc=":protoc",
77 internal_bootstrap_hack=False,
Jisi Liu125a91b2015-10-14 17:37:39 -070078 **kargs):
Jisi Liu3101e732015-10-16 12:46:26 -070079 """Bazel rule to create a C++ protobuf library from proto source files
80
81 Args:
82 name: the name of the cc_proto_library.
83 srcs: the .proto files of the cc_proto_library.
84 deps: a list of dependency labels; must be cc_proto_library.
85 cc_libs: a list of other cc_library targets depended by the generated
86 cc_library.
87 include: a string indicating the include path of the .proto files.
88 protoc: the label of the protocol compiler to generate the sources.
89 internal_bootstrap_hack: a flag indicate the cc_proto_library is used only
90 for bootstraping. When it is set to True, no files will be generated.
91 The rule will simply be a provider for .proto files, so that other
92 cc_proto_library can depend on it.
93 **kargs: other keyword arguments that are passed to cc_library.
94
95 """
Jisi Liu39362b32015-10-14 17:12:11 -070096
97 if internal_bootstrap_hack:
98 # For pre-checked-in generated files, we add the internal_bootstrap_hack
99 # which will skip the codegen action.
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700100 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700101 name=name + "_genproto",
102 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700103 deps=[s + "_genproto" for s in deps],
Jisi Liu3101e732015-10-16 12:46:26 -0700104 include=include,
Jisi Liu125a91b2015-10-14 17:37:39 -0700105 protoc=protoc,
Jisi Liu39362b32015-10-14 17:12:11 -0700106 )
107 # An empty cc_library to make rule dependency consistent.
108 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700109 name=name,
Jisi Liud8701b52015-10-16 11:44:21 -0700110 **kargs)
Jisi Liu39362b32015-10-14 17:12:11 -0700111 return
112
Jisi Liu25d75b52015-10-14 17:41:14 -0700113 outs = _cc_outs(srcs)
Jisi Liu9c7d9c02015-10-15 10:51:32 -0700114 _proto_gen(
Jisi Liu125a91b2015-10-14 17:37:39 -0700115 name=name + "_genproto",
116 srcs=srcs,
Jisi Liud8701b52015-10-16 11:44:21 -0700117 deps=[s + "_genproto" for s in deps],
Jisi Liu3101e732015-10-16 12:46:26 -0700118 include=include,
Jisi Liu125a91b2015-10-14 17:37:39 -0700119 protoc=protoc,
120 gen_cc=1,
121 outs=outs,
Jisi Liu39362b32015-10-14 17:12:11 -0700122 )
123
Jisi Liu6dac0822015-10-19 14:41:00 -0700124 includes = []
125 if include != None:
126 includes = [include]
127
Jisi Liu39362b32015-10-14 17:12:11 -0700128 native.cc_library(
Jisi Liu125a91b2015-10-14 17:37:39 -0700129 name=name,
130 srcs=outs,
Jisi Liud8701b52015-10-16 11:44:21 -0700131 deps=cc_libs + deps,
Jisi Liu6dac0822015-10-19 14:41:00 -0700132 includes=includes,
Jisi Liud8701b52015-10-16 11:44:21 -0700133 **kargs)