xref: /aosp_15_r20/external/perfetto/bazel/proto_gen.bzl (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker# Copyright (C) 2019 The Android Open Source Project
2*6dbdd20aSAndroid Build Coastguard Worker#
3*6dbdd20aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
4*6dbdd20aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
5*6dbdd20aSAndroid Build Coastguard Worker# You may obtain a copy of the License at
6*6dbdd20aSAndroid Build Coastguard Worker#
7*6dbdd20aSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
8*6dbdd20aSAndroid Build Coastguard Worker#
9*6dbdd20aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*6dbdd20aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
11*6dbdd20aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6dbdd20aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
13*6dbdd20aSAndroid Build Coastguard Worker# limitations under the License.
14*6dbdd20aSAndroid Build Coastguard Worker
15*6dbdd20aSAndroid Build Coastguard Worker# This file defines the proto_gen() rule that is used for generating protos
16*6dbdd20aSAndroid Build Coastguard Worker# with custom plugins (ipc and protozero).
17*6dbdd20aSAndroid Build Coastguard Worker
18*6dbdd20aSAndroid Build Coastguard Workerdef _proto_gen_impl(ctx):
19*6dbdd20aSAndroid Build Coastguard Worker    proto_src = [
20*6dbdd20aSAndroid Build Coastguard Worker        f
21*6dbdd20aSAndroid Build Coastguard Worker        for dep in ctx.attr.deps
22*6dbdd20aSAndroid Build Coastguard Worker        for f in dep[ProtoInfo].direct_sources
23*6dbdd20aSAndroid Build Coastguard Worker    ]
24*6dbdd20aSAndroid Build Coastguard Worker    includes = [
25*6dbdd20aSAndroid Build Coastguard Worker        f
26*6dbdd20aSAndroid Build Coastguard Worker        for dep in ctx.attr.deps
27*6dbdd20aSAndroid Build Coastguard Worker        for f in dep[ProtoInfo].transitive_imports.to_list()
28*6dbdd20aSAndroid Build Coastguard Worker    ]
29*6dbdd20aSAndroid Build Coastguard Worker    proto_paths = [
30*6dbdd20aSAndroid Build Coastguard Worker        f
31*6dbdd20aSAndroid Build Coastguard Worker        for dep in ctx.attr.deps
32*6dbdd20aSAndroid Build Coastguard Worker        for f in dep[ProtoInfo].transitive_proto_path.to_list()
33*6dbdd20aSAndroid Build Coastguard Worker    ]
34*6dbdd20aSAndroid Build Coastguard Worker
35*6dbdd20aSAndroid Build Coastguard Worker    proto_path = "."
36*6dbdd20aSAndroid Build Coastguard Worker
37*6dbdd20aSAndroid Build Coastguard Worker    out_dir = ctx.bin_dir.path
38*6dbdd20aSAndroid Build Coastguard Worker    strip_base_path = ""
39*6dbdd20aSAndroid Build Coastguard Worker    if ctx.attr.root != "//":
40*6dbdd20aSAndroid Build Coastguard Worker        # This path is hit in Google internal builds, where root is typically
41*6dbdd20aSAndroid Build Coastguard Worker        # //third_party/perfetto.
42*6dbdd20aSAndroid Build Coastguard Worker        proto_path = "."
43*6dbdd20aSAndroid Build Coastguard Worker
44*6dbdd20aSAndroid Build Coastguard Worker        # The below will likely be //third_party/perfetto/ but may also be any
45*6dbdd20aSAndroid Build Coastguard Worker        # subdir under //third_party/perfetto.
46*6dbdd20aSAndroid Build Coastguard Worker        strip_base_path = ctx.label.package + "/"
47*6dbdd20aSAndroid Build Coastguard Worker    elif ctx.label.workspace_root:
48*6dbdd20aSAndroid Build Coastguard Worker        # This path is hit when proto targets are built as @perfetto//:xxx
49*6dbdd20aSAndroid Build Coastguard Worker        # instead of //:xxx. This happens in embedder builds.
50*6dbdd20aSAndroid Build Coastguard Worker        proto_path = ctx.label.workspace_root
51*6dbdd20aSAndroid Build Coastguard Worker
52*6dbdd20aSAndroid Build Coastguard Worker        # We could be using the sibling repository layout, in which case we do nothing.
53*6dbdd20aSAndroid Build Coastguard Worker        if not ctx.label.workspace_root.startswith("../"):
54*6dbdd20aSAndroid Build Coastguard Worker            # workspace_root == "external/perfetto" and we need to rebase the paths
55*6dbdd20aSAndroid Build Coastguard Worker            # passed to protoc.
56*6dbdd20aSAndroid Build Coastguard Worker            out_dir += "/" + ctx.label.workspace_root
57*6dbdd20aSAndroid Build Coastguard Worker        strip_base_path = ctx.label.workspace_root + "/"
58*6dbdd20aSAndroid Build Coastguard Worker
59*6dbdd20aSAndroid Build Coastguard Worker
60*6dbdd20aSAndroid Build Coastguard Worker    out_files = []
61*6dbdd20aSAndroid Build Coastguard Worker    suffix = ctx.attr.suffix
62*6dbdd20aSAndroid Build Coastguard Worker    for src in proto_src:
63*6dbdd20aSAndroid Build Coastguard Worker        base_path = src.path[:-len(".proto")]
64*6dbdd20aSAndroid Build Coastguard Worker        if base_path.startswith(strip_base_path):
65*6dbdd20aSAndroid Build Coastguard Worker            base_path = base_path[len(strip_base_path):]
66*6dbdd20aSAndroid Build Coastguard Worker        out_files += [ctx.actions.declare_file(base_path + ".%s.h" % suffix)]
67*6dbdd20aSAndroid Build Coastguard Worker        out_files += [ctx.actions.declare_file(base_path + ".%s.cc" % suffix)]
68*6dbdd20aSAndroid Build Coastguard Worker
69*6dbdd20aSAndroid Build Coastguard Worker    arguments = [
70*6dbdd20aSAndroid Build Coastguard Worker        "--proto_path=" + proto_path
71*6dbdd20aSAndroid Build Coastguard Worker        for proto_path in proto_paths
72*6dbdd20aSAndroid Build Coastguard Worker    ]
73*6dbdd20aSAndroid Build Coastguard Worker
74*6dbdd20aSAndroid Build Coastguard Worker    plugin_deps = []
75*6dbdd20aSAndroid Build Coastguard Worker    if ctx.attr.plugin:
76*6dbdd20aSAndroid Build Coastguard Worker        wrap_arg = ctx.attr.wrapper_namespace
77*6dbdd20aSAndroid Build Coastguard Worker        arguments += [
78*6dbdd20aSAndroid Build Coastguard Worker            "--plugin=protoc-gen-plugin=" + ctx.executable.plugin.path,
79*6dbdd20aSAndroid Build Coastguard Worker            "--plugin_out=wrapper_namespace=" + wrap_arg + ":" + out_dir,
80*6dbdd20aSAndroid Build Coastguard Worker        ]
81*6dbdd20aSAndroid Build Coastguard Worker        plugin_deps += [ctx.executable.plugin]
82*6dbdd20aSAndroid Build Coastguard Worker    else:
83*6dbdd20aSAndroid Build Coastguard Worker        arguments += [
84*6dbdd20aSAndroid Build Coastguard Worker            "--cpp_out=lite=true:" + out_dir,
85*6dbdd20aSAndroid Build Coastguard Worker        ]
86*6dbdd20aSAndroid Build Coastguard Worker
87*6dbdd20aSAndroid Build Coastguard Worker    arguments += [src.path for src in proto_src]
88*6dbdd20aSAndroid Build Coastguard Worker    ctx.actions.run(
89*6dbdd20aSAndroid Build Coastguard Worker        inputs = proto_src + includes + plugin_deps,
90*6dbdd20aSAndroid Build Coastguard Worker        tools = plugin_deps,
91*6dbdd20aSAndroid Build Coastguard Worker        outputs = out_files,
92*6dbdd20aSAndroid Build Coastguard Worker        executable = ctx.executable.protoc,
93*6dbdd20aSAndroid Build Coastguard Worker        arguments = arguments,
94*6dbdd20aSAndroid Build Coastguard Worker    )
95*6dbdd20aSAndroid Build Coastguard Worker    cc_files = depset([f for f in out_files if f.path.endswith(".cc")])
96*6dbdd20aSAndroid Build Coastguard Worker    h_files = depset([f for f in out_files if f.path.endswith(".h")])
97*6dbdd20aSAndroid Build Coastguard Worker    return [
98*6dbdd20aSAndroid Build Coastguard Worker        DefaultInfo(files = cc_files),
99*6dbdd20aSAndroid Build Coastguard Worker        OutputGroupInfo(
100*6dbdd20aSAndroid Build Coastguard Worker            cc = cc_files,
101*6dbdd20aSAndroid Build Coastguard Worker            h = h_files,
102*6dbdd20aSAndroid Build Coastguard Worker        ),
103*6dbdd20aSAndroid Build Coastguard Worker    ]
104*6dbdd20aSAndroid Build Coastguard Worker
105*6dbdd20aSAndroid Build Coastguard Worker
106*6dbdd20aSAndroid Build Coastguard Workerproto_gen = rule(
107*6dbdd20aSAndroid Build Coastguard Worker    attrs = {
108*6dbdd20aSAndroid Build Coastguard Worker        "deps": attr.label_list(
109*6dbdd20aSAndroid Build Coastguard Worker            mandatory = True,
110*6dbdd20aSAndroid Build Coastguard Worker            allow_empty = False,
111*6dbdd20aSAndroid Build Coastguard Worker            providers = [ProtoInfo],
112*6dbdd20aSAndroid Build Coastguard Worker        ),
113*6dbdd20aSAndroid Build Coastguard Worker        "plugin": attr.label(
114*6dbdd20aSAndroid Build Coastguard Worker            executable = True,
115*6dbdd20aSAndroid Build Coastguard Worker            mandatory = False,
116*6dbdd20aSAndroid Build Coastguard Worker            cfg = "host",
117*6dbdd20aSAndroid Build Coastguard Worker        ),
118*6dbdd20aSAndroid Build Coastguard Worker        "wrapper_namespace": attr.string(
119*6dbdd20aSAndroid Build Coastguard Worker            mandatory = False,
120*6dbdd20aSAndroid Build Coastguard Worker            default = ""
121*6dbdd20aSAndroid Build Coastguard Worker        ),
122*6dbdd20aSAndroid Build Coastguard Worker        "suffix": attr.string(
123*6dbdd20aSAndroid Build Coastguard Worker            mandatory = True,
124*6dbdd20aSAndroid Build Coastguard Worker        ),
125*6dbdd20aSAndroid Build Coastguard Worker        "protoc": attr.label(
126*6dbdd20aSAndroid Build Coastguard Worker            executable = True,
127*6dbdd20aSAndroid Build Coastguard Worker            cfg = "host",
128*6dbdd20aSAndroid Build Coastguard Worker        ),
129*6dbdd20aSAndroid Build Coastguard Worker        "root": attr.string(
130*6dbdd20aSAndroid Build Coastguard Worker            mandatory = False,
131*6dbdd20aSAndroid Build Coastguard Worker            default = "//",
132*6dbdd20aSAndroid Build Coastguard Worker        ),
133*6dbdd20aSAndroid Build Coastguard Worker    },
134*6dbdd20aSAndroid Build Coastguard Worker    implementation = _proto_gen_impl,
135*6dbdd20aSAndroid Build Coastguard Worker)
136*6dbdd20aSAndroid Build Coastguard Worker
137*6dbdd20aSAndroid Build Coastguard Worker
138*6dbdd20aSAndroid Build Coastguard Workerdef _proto_descriptor_gen_impl(ctx):
139*6dbdd20aSAndroid Build Coastguard Worker    descriptors = [
140*6dbdd20aSAndroid Build Coastguard Worker        f
141*6dbdd20aSAndroid Build Coastguard Worker        for dep in ctx.attr.deps
142*6dbdd20aSAndroid Build Coastguard Worker        for f in dep[ProtoInfo].transitive_descriptor_sets.to_list()
143*6dbdd20aSAndroid Build Coastguard Worker    ]
144*6dbdd20aSAndroid Build Coastguard Worker    ctx.actions.run_shell(
145*6dbdd20aSAndroid Build Coastguard Worker        inputs=descriptors,
146*6dbdd20aSAndroid Build Coastguard Worker        outputs=ctx.outputs.outs,
147*6dbdd20aSAndroid Build Coastguard Worker        command='cat %s > %s' % (
148*6dbdd20aSAndroid Build Coastguard Worker            ' '.join([f.path for f in descriptors]), ctx.outputs.outs[0].path)
149*6dbdd20aSAndroid Build Coastguard Worker    )
150*6dbdd20aSAndroid Build Coastguard Worker
151*6dbdd20aSAndroid Build Coastguard Worker
152*6dbdd20aSAndroid Build Coastguard Workerproto_descriptor_gen = rule(
153*6dbdd20aSAndroid Build Coastguard Worker    implementation=_proto_descriptor_gen_impl,
154*6dbdd20aSAndroid Build Coastguard Worker    attrs = {
155*6dbdd20aSAndroid Build Coastguard Worker        "deps": attr.label_list(
156*6dbdd20aSAndroid Build Coastguard Worker            mandatory = True,
157*6dbdd20aSAndroid Build Coastguard Worker            allow_empty = False,
158*6dbdd20aSAndroid Build Coastguard Worker            providers = [ProtoInfo],
159*6dbdd20aSAndroid Build Coastguard Worker        ),
160*6dbdd20aSAndroid Build Coastguard Worker        "outs": attr.output_list(mandatory=True),
161*6dbdd20aSAndroid Build Coastguard Worker    }
162*6dbdd20aSAndroid Build Coastguard Worker)
163