blob: c2a649b591176fd26f7eb24c115f48703b63cf47 [file] [log] [blame]
Primiano Tucci1d409982019-09-19 10:15:18 +01001# Copyright (C) 2019 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15load("@perfetto_cfg//:perfetto_cfg.bzl", "PERFETTO_CONFIG")
Lalit Maganti117272f2020-09-11 14:01:18 +010016load("@perfetto//bazel:proto_gen.bzl", "proto_descriptor_gen", "proto_gen")
Primiano Tucci1d409982019-09-19 10:15:18 +010017
18# +----------------------------------------------------------------------------+
19# | Base C++ rules. |
20# +----------------------------------------------------------------------------+
21
22def default_cc_args():
23 return {
Pascal Muetschardd2723862019-09-23 13:10:05 -070024 "deps": PERFETTO_CONFIG.deps.build_config,
Sami Kyostila4a7bcd62020-01-17 13:38:31 +000025 "copts": [
26 "-Wno-pragma-system-header-outside-header",
27 ],
Primiano Tucci1d409982019-09-19 10:15:18 +010028 "includes": ["include"],
29 "linkopts": select({
Primiano Tuccie8020f92019-11-26 13:24:01 +000030 "@perfetto//bazel:os_linux": ["-ldl", "-lrt", "-lpthread"],
Primiano Tucci1d409982019-09-19 10:15:18 +010031 "@perfetto//bazel:os_osx": [],
Pascal Muetschardc6911232019-09-24 13:40:28 -070032 "@perfetto//bazel:os_windows": [],
33 "//conditions:default": ["-ldl"],
Primiano Tucci1d409982019-09-19 10:15:18 +010034 }),
35 }
36
Harvey Yang321c4fc2021-10-25 14:11:50 +080037def perfetto_build_config_cc_library(**kwargs):
38 if not _rule_override("cc_library", **kwargs):
39 native.cc_library(**kwargs)
40
41def perfetto_filegroup(**kwargs):
42 if not _rule_override("filegroup", **kwargs):
43 native.filegroup(**kwargs)
44
45def perfetto_genrule(**kwargs):
46 if not _rule_override("genrule", **kwargs):
47 native.genrule(**kwargs)
48
Primiano Tucci1d409982019-09-19 10:15:18 +010049def perfetto_cc_library(**kwargs):
50 args = _merge_dicts(default_cc_args(), kwargs)
51 if not _rule_override("cc_library", **args):
52 native.cc_library(**args)
53
54def perfetto_cc_binary(**kwargs):
55 args = _merge_dicts(default_cc_args(), kwargs)
56 if not _rule_override("cc_binary", **args):
57 native.cc_binary(**args)
58
59def perfetto_py_binary(**kwargs):
60 if not _rule_override("py_binary", **kwargs):
61 native.py_binary(**kwargs)
62
Anindita Ghosh237a7762020-06-30 10:46:52 +000063def perfetto_py_library(**kwargs):
64 if not _rule_override("py_library", **kwargs):
65 native.py_library(**kwargs)
66
Primiano Tucci1d409982019-09-19 10:15:18 +010067# +----------------------------------------------------------------------------+
68# | Proto-related rules |
69# +----------------------------------------------------------------------------+
70
71def perfetto_proto_library(**kwargs):
72 if not _rule_override("proto_library", **kwargs):
73 native.proto_library(**kwargs)
74
75def perfetto_cc_proto_library(**kwargs):
76 if not _rule_override("cc_proto_library", **kwargs):
77 native.cc_proto_library(**kwargs)
78
Lalit Maganti65600342019-09-19 21:35:35 +010079def perfetto_java_proto_library(**kwargs):
80 if not _rule_override("java_proto_library", **kwargs):
81 native.java_proto_library(**kwargs)
82
Lalit Maganti46e2bda2020-05-06 12:51:33 +010083def perfetto_java_lite_proto_library(**kwargs):
84 if not _rule_override("java_lite_proto_library", **kwargs):
85 native.java_lite_proto_library(**kwargs)
86
Lalit Maganti06f638c2022-04-01 18:44:14 +010087# Unlike the other rules, this is an noop by default because Bazel does not
Lalit Maganti225ae652022-06-27 21:28:21 +010088# support Go proto libraries.
89def perfetto_go_proto_library(**kwargs):
90 _rule_override("go_proto_library", **kwargs)
91
92# Unlike the other rules, this is an noop by default because Bazel does not
Lalit Maganti06f638c2022-04-01 18:44:14 +010093# support Python proto libraries.
94def perfetto_py_proto_library(**kwargs):
95 _rule_override("py_proto_library", **kwargs)
96
Lalit Maganti65600342019-09-19 21:35:35 +010097# +----------------------------------------------------------------------------+
98# | Misc rules. |
99# +----------------------------------------------------------------------------+
100
Primiano Tucci1d409982019-09-19 10:15:18 +0100101# Generates .pbzero.{cc,h} from .proto(s). We deliberately do NOT generate
102# conventional .pb.{cc,h} from here as protozero gen sources do not have any
103# dependency on libprotobuf.
104def perfetto_cc_protozero_library(name, deps, **kwargs):
105 if _rule_override(
106 "cc_protozero_library",
107 name = name,
108 deps = deps,
109 **kwargs
110 ):
111 return
112
Lalit Maganti25b59732021-04-20 16:18:32 +0100113 # A perfetto_cc_protozero_library has two types of dependencies:
114 # 1. Exactly one dependency on a proto_library target. This defines the
115 # .proto sources for the target
116 # 2. Zero or more deps on other perfetto_cc_protozero_library targets. This
117 # to deal with the case of foo.proto including common.proto from another
118 # target.
119 _proto_deps = [d for d in deps if d.endswith("_protos")]
120 _cc_deps = [d for d in deps if d not in _proto_deps]
121 if len(_proto_deps) != 1:
122 fail("Too many proto deps for target %s" % name)
123
Harvey Yang321c4fc2021-10-25 14:11:50 +0800124 args = {
125 'name': name + "_src",
126 'deps': _proto_deps,
127 'suffix': "pbzero",
128 'plugin': PERFETTO_CONFIG.root + ":protozero_plugin",
129 'wrapper_namespace': "pbzero",
130 'protoc': PERFETTO_CONFIG.deps.protoc[0],
131 'root': PERFETTO_CONFIG.root,
132 }
133 if not _rule_override("proto_gen", **args):
134 proto_gen(**args)
Primiano Tucci1d409982019-09-19 10:15:18 +0100135
Harvey Yang321c4fc2021-10-25 14:11:50 +0800136 perfetto_filegroup(
Primiano Tucci1d409982019-09-19 10:15:18 +0100137 name = name + "_h",
138 srcs = [":" + name + "_src"],
139 output_group = "h",
140 )
141
142 perfetto_cc_library(
143 name = name,
144 srcs = [":" + name + "_src"],
145 hdrs = [":" + name + "_h"],
Lalit Maganti25b59732021-04-20 16:18:32 +0100146 deps = [PERFETTO_CONFIG.root + ":protozero"] + _cc_deps,
Primiano Tucci1d409982019-09-19 10:15:18 +0100147 **kwargs
148 )
149
150# Generates .ipc.{cc,h} and .pb.{cc.h} from .proto(s). The IPC sources depend
151# on .pb.h so we need to generate also the standard protobuf sources here.
152def perfetto_cc_ipc_library(name, deps, **kwargs):
153 if _rule_override("cc_ipc_library", name = name, deps = deps, **kwargs):
154 return
155
Primiano Tuccie8020f92019-11-26 13:24:01 +0000156 # A perfetto_cc_ipc_library has two types of dependencies:
157 # 1. Exactly one dependency on a proto_library target. This defines the
158 # .proto sources for the target
159 # 2. Zero or more deps on other perfetto_cc_protocpp_library targets. This
160 # to deal with the case of foo.proto including common.proto from another
161 # target.
162 _proto_deps = [d for d in deps if d.endswith("_protos")]
163 _cc_deps = [d for d in deps if d not in _proto_deps]
164 if len(_proto_deps) != 1:
Lalit Maganti6e1a4d92019-12-19 13:43:56 +0000165 fail("Too many proto deps for target %s" % name)
Primiano Tucci1d409982019-09-19 10:15:18 +0100166
167 # Generates .ipc.{cc,h}.
Harvey Yang4f5db1b2021-10-28 15:02:03 +0800168 args = {
169 'name': name + "_src",
170 'deps': _proto_deps,
171 'suffix': "ipc",
172 'plugin': PERFETTO_CONFIG.root + ":ipc_plugin",
173 'wrapper_namespace': "gen",
174 'protoc': PERFETTO_CONFIG.deps.protoc[0],
175 'root': PERFETTO_CONFIG.root,
176 }
177 if not _rule_override("proto_gen", **args):
178 proto_gen(**args)
Primiano Tucci1d409982019-09-19 10:15:18 +0100179
Harvey Yang4f5db1b2021-10-28 15:02:03 +0800180 perfetto_filegroup(
Primiano Tucci1d409982019-09-19 10:15:18 +0100181 name = name + "_h",
182 srcs = [":" + name + "_src"],
183 output_group = "h",
184 )
185
186 perfetto_cc_library(
187 name = name,
188 srcs = [":" + name + "_src"],
189 hdrs = [":" + name + "_h"],
190 deps = [
Primiano Tuccie8020f92019-11-26 13:24:01 +0000191 # Generated .ipc.{cc,h} depend on this and protozero.
Primiano Tucci1d409982019-09-19 10:15:18 +0100192 PERFETTO_CONFIG.root + ":perfetto_ipc",
Primiano Tucci916f4e52020-10-16 20:40:33 +0200193 PERFETTO_CONFIG.root + ":protozero",
Primiano Tuccie8020f92019-11-26 13:24:01 +0000194 ] + _cc_deps,
Primiano Tucci1d409982019-09-19 10:15:18 +0100195 **kwargs
196 )
197
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100198# Generates .gen.{cc,h} from .proto(s).
199def perfetto_cc_protocpp_library(name, deps, **kwargs):
200 if _rule_override(
201 "cc_protocpp_library",
202 name = name,
203 deps = deps,
204 **kwargs
205 ):
206 return
207
208 # A perfetto_cc_protocpp_library has two types of dependencies:
209 # 1. Exactly one dependency on a proto_library target. This defines the
210 # .proto sources for the target
211 # 2. Zero or more deps on other perfetto_cc_protocpp_library targets. This
212 # to deal with the case of foo.proto including common.proto from another
213 # target.
214 _proto_deps = [d for d in deps if d.endswith("_protos")]
215 _cc_deps = [d for d in deps if d not in _proto_deps]
Primiano Tuccie8020f92019-11-26 13:24:01 +0000216 if len(_proto_deps) != 1:
Lalit Maganti6e1a4d92019-12-19 13:43:56 +0000217 fail("Too many proto deps for target %s" % name)
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100218
Harvey Yang4f5db1b2021-10-28 15:02:03 +0800219 args = {
220 'name': name + "_gen",
221 'deps': _proto_deps,
222 'suffix': "gen",
223 'plugin': PERFETTO_CONFIG.root + ":cppgen_plugin",
224 'wrapper_namespace': "gen",
225 'protoc': PERFETTO_CONFIG.deps.protoc[0],
226 'root': PERFETTO_CONFIG.root,
227 }
228 if not _rule_override("proto_gen", **args):
229 proto_gen(**args)
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100230
Harvey Yang4f5db1b2021-10-28 15:02:03 +0800231 perfetto_filegroup(
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100232 name = name + "_gen_h",
233 srcs = [":" + name + "_gen"],
234 output_group = "h",
235 )
236
Lalit Magantib8698fa2020-05-11 19:25:36 +0100237 # The headers from the gen plugin have implicit dependencies
238 # on each other so will fail when compiled independently. Use
239 # textual_hdrs to indicate this to Bazel.
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100240 perfetto_cc_library(
241 name = name,
242 srcs = [":" + name + "_gen"],
Lalit Magantib8698fa2020-05-11 19:25:36 +0100243 textual_hdrs = [":" + name + "_gen_h"],
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100244 deps = [
Primiano Tucci916f4e52020-10-16 20:40:33 +0200245 PERFETTO_CONFIG.root + ":protozero",
Primiano Tucci57dd66b2019-10-15 23:09:04 +0100246 ] + _cc_deps,
247 **kwargs
248 )
249
Lalit Maganti117272f2020-09-11 14:01:18 +0100250def perfetto_proto_descriptor(name, deps, outs, **kwargs):
Harvey Yang321c4fc2021-10-25 14:11:50 +0800251 args = {
252 'name': name,
253 'deps': deps,
254 'outs': outs,
255 }
256 if not _rule_override("proto_descriptor_gen", **args):
257 proto_descriptor_gen(**args)
Lalit Maganti117272f2020-09-11 14:01:18 +0100258
259# Generator .descriptor.h from protos
260def perfetto_cc_proto_descriptor(name, deps, outs, **kwargs):
261 cmd = [
262 "$(location gen_cc_proto_descriptor_py)",
263 "--cpp_out=$@",
264 "--gen_dir=$(GENDIR)",
265 "$<"
266 ]
Harvey Yang321c4fc2021-10-25 14:11:50 +0800267 perfetto_genrule(
Lalit Maganti117272f2020-09-11 14:01:18 +0100268 name = name + "_gen",
269 cmd = " ".join(cmd),
270 exec_tools = [
271 ":gen_cc_proto_descriptor_py",
272 ],
273 srcs = deps,
274 outs = outs,
275 )
276
277 perfetto_cc_library(
278 name = name,
279 hdrs = [":" + name + "_gen"],
280 **kwargs
281 )
282
Primiano Tucci1d409982019-09-19 10:15:18 +0100283# +----------------------------------------------------------------------------+
284# | Misc utility functions |
285# +----------------------------------------------------------------------------+
286
287def _rule_override(rule_name, **kwargs):
288 overrides = getattr(PERFETTO_CONFIG, "rule_overrides", struct())
289 overridden_rule = getattr(overrides, rule_name, None)
290 if overridden_rule:
291 overridden_rule(**kwargs)
292 return True
293 return False
294
295def _merge_dicts(*args):
296 res = {}
297 for arg in args:
298 for k, v in arg.items():
Lalit Magantif9c004d2020-01-06 14:44:34 +0000299 if type(v) == "string" or type(v) == "bool":
Primiano Tucci1d409982019-09-19 10:15:18 +0100300 res[k] = v
301 elif type(v) == "list" or type(v) == "select":
302 res[k] = res.get(k, []) + v
303 else:
304 fail("key type not supported: " + type(v))
305 return res