blob: e237ebc3f8ba8f5a74a02a0dde7eea6f121b431b [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
15# This file defines the proto_gen() rule that is used for generating protos
16# with custom plugins (ipc and protozero).
17
18def _proto_gen_impl(ctx):
19 proto_src = [
20 f
21 for dep in ctx.attr.deps
22 for f in dep[ProtoInfo].direct_sources
23 ]
24 includes = [
25 f
26 for dep in ctx.attr.deps
27 for f in dep[ProtoInfo].transitive_imports.to_list()
28 ]
Kean Mariotti24e89062024-04-22 10:28:08 +000029 proto_paths = [
30 f
31 for dep in ctx.attr.deps
32 for f in dep[ProtoInfo].transitive_proto_path.to_list()
33 ]
Primiano Tucci1d409982019-09-19 10:15:18 +010034
35 proto_path = "."
36
Lalit Magantie0a12372024-03-19 15:33:20 +000037 out_dir = ctx.bin_dir.path
Primiano Tucci1d409982019-09-19 10:15:18 +010038 strip_base_path = ""
39 if ctx.attr.root != "//":
40 # This path is hit in Google internal builds, where root is typically
41 # //third_party/perfetto.
42 proto_path = "."
Lalit Magantia4244e42019-09-20 12:03:32 +010043
44 # The below will likely be //third_party/perfetto/ but may also be any
45 # subdir under //third_party/perfetto.
Lalit Maganti40a75cb2024-02-05 16:13:59 +000046 strip_base_path = ctx.label.package + "/"
Primiano Tucci1d409982019-09-19 10:15:18 +010047 elif ctx.label.workspace_root:
48 # This path is hit when proto targets are built as @perfetto//:xxx
Erwin Jansenb0b4de52024-05-21 21:55:07 -070049 # instead of //:xxx. This happens in embedder builds.
Primiano Tucci1d409982019-09-19 10:15:18 +010050 proto_path = ctx.label.workspace_root
Erwin Jansenb0b4de52024-05-21 21:55:07 -070051
52 # We could be using the sibling repository layout, in which case we do nothing.
53 if not ctx.label.workspace_root.startswith("../"):
54 # workspace_root == "external/perfetto" and we need to rebase the paths
55 # passed to protoc.
56 out_dir += "/" + ctx.label.workspace_root
Primiano Tucci1d409982019-09-19 10:15:18 +010057 strip_base_path = ctx.label.workspace_root + "/"
58
Erwin Jansenb0b4de52024-05-21 21:55:07 -070059
Primiano Tucci1d409982019-09-19 10:15:18 +010060 out_files = []
61 suffix = ctx.attr.suffix
62 for src in proto_src:
63 base_path = src.path[:-len(".proto")]
64 if base_path.startswith(strip_base_path):
65 base_path = base_path[len(strip_base_path):]
66 out_files += [ctx.actions.declare_file(base_path + ".%s.h" % suffix)]
67 out_files += [ctx.actions.declare_file(base_path + ".%s.cc" % suffix)]
68
69 arguments = [
Kean Mariotti24e89062024-04-22 10:28:08 +000070 "--proto_path=" + proto_path
71 for proto_path in proto_paths
Primiano Tucci1d409982019-09-19 10:15:18 +010072 ]
Kean Mariotti24e89062024-04-22 10:28:08 +000073
Primiano Tucci1d409982019-09-19 10:15:18 +010074 plugin_deps = []
75 if ctx.attr.plugin:
Primiano Tuccie8020f92019-11-26 13:24:01 +000076 wrap_arg = ctx.attr.wrapper_namespace
Primiano Tucci1d409982019-09-19 10:15:18 +010077 arguments += [
78 "--plugin=protoc-gen-plugin=" + ctx.executable.plugin.path,
Primiano Tuccie8020f92019-11-26 13:24:01 +000079 "--plugin_out=wrapper_namespace=" + wrap_arg + ":" + out_dir,
Primiano Tucci1d409982019-09-19 10:15:18 +010080 ]
81 plugin_deps += [ctx.executable.plugin]
82 else:
83 arguments += [
Primiano Tucci7b6a7882020-01-20 22:34:31 +000084 "--cpp_out=lite=true:" + out_dir,
Primiano Tucci1d409982019-09-19 10:15:18 +010085 ]
86
87 arguments += [src.path for src in proto_src]
88 ctx.actions.run(
89 inputs = proto_src + includes + plugin_deps,
90 tools = plugin_deps,
91 outputs = out_files,
92 executable = ctx.executable.protoc,
93 arguments = arguments,
94 )
Lalit Magantib8698fa2020-05-11 19:25:36 +010095 cc_files = depset([f for f in out_files if f.path.endswith(".cc")])
96 h_files = depset([f for f in out_files if f.path.endswith(".h")])
Primiano Tucci1d409982019-09-19 10:15:18 +010097 return [
Lalit Magantib8698fa2020-05-11 19:25:36 +010098 DefaultInfo(files = cc_files),
Primiano Tucci1d409982019-09-19 10:15:18 +010099 OutputGroupInfo(
Lalit Magantib8698fa2020-05-11 19:25:36 +0100100 cc = cc_files,
101 h = h_files,
Primiano Tucci1d409982019-09-19 10:15:18 +0100102 ),
103 ]
104
Lalit Magantib8698fa2020-05-11 19:25:36 +0100105
Primiano Tucci1d409982019-09-19 10:15:18 +0100106proto_gen = rule(
107 attrs = {
108 "deps": attr.label_list(
109 mandatory = True,
110 allow_empty = False,
111 providers = [ProtoInfo],
112 ),
113 "plugin": attr.label(
114 executable = True,
115 mandatory = False,
116 cfg = "host",
117 ),
Primiano Tuccie8020f92019-11-26 13:24:01 +0000118 "wrapper_namespace": attr.string(
119 mandatory = False,
120 default = ""
121 ),
Primiano Tucci1d409982019-09-19 10:15:18 +0100122 "suffix": attr.string(
123 mandatory = True,
124 ),
125 "protoc": attr.label(
126 executable = True,
127 cfg = "host",
128 ),
129 "root": attr.string(
130 mandatory = False,
131 default = "//",
132 ),
133 },
Primiano Tucci1d409982019-09-19 10:15:18 +0100134 implementation = _proto_gen_impl,
135)
Lalit Maganti117272f2020-09-11 14:01:18 +0100136
137
138def _proto_descriptor_gen_impl(ctx):
139 descriptors = [
140 f
141 for dep in ctx.attr.deps
142 for f in dep[ProtoInfo].transitive_descriptor_sets.to_list()
143 ]
144 ctx.actions.run_shell(
145 inputs=descriptors,
146 outputs=ctx.outputs.outs,
147 command='cat %s > %s' % (
148 ' '.join([f.path for f in descriptors]), ctx.outputs.outs[0].path)
149 )
150
151
152proto_descriptor_gen = rule(
153 implementation=_proto_descriptor_gen_impl,
154 attrs = {
155 "deps": attr.label_list(
156 mandatory = True,
157 allow_empty = False,
158 providers = [ProtoInfo],
159 ),
160 "outs": attr.output_list(mandatory=True),
161 }
162)