xref: /aosp_15_r20/external/pigweed/pw_build/binary_tools.bzl (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker# Copyright 2024 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker#
3*61c4878aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker# use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker# the License at
6*61c4878aSAndroid Build Coastguard Worker#
7*61c4878aSAndroid Build Coastguard Worker#     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker#
9*61c4878aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker# License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker# the License.
14*61c4878aSAndroid Build Coastguard Worker"""Rules for processing binary executables."""
15*61c4878aSAndroid Build Coastguard Worker
16*61c4878aSAndroid Build Coastguard Workerload("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain")
17*61c4878aSAndroid Build Coastguard Workerload("@pw_toolchain//actions:providers.bzl", "ActionNameInfo")
18*61c4878aSAndroid Build Coastguard Worker
19*61c4878aSAndroid Build Coastguard Workerdef _run_action_on_executable(
20*61c4878aSAndroid Build Coastguard Worker        ctx,
21*61c4878aSAndroid Build Coastguard Worker        action_name,
22*61c4878aSAndroid Build Coastguard Worker        action_args,
23*61c4878aSAndroid Build Coastguard Worker        input,
24*61c4878aSAndroid Build Coastguard Worker        output,
25*61c4878aSAndroid Build Coastguard Worker        additional_outputs,
26*61c4878aSAndroid Build Coastguard Worker        output_executable = False):
27*61c4878aSAndroid Build Coastguard Worker    """Macro to be used in rule implementation to run an action on input executable.
28*61c4878aSAndroid Build Coastguard Worker
29*61c4878aSAndroid Build Coastguard Worker    Looks up the current toolchain to find the path to the specified action."""
30*61c4878aSAndroid Build Coastguard Worker    cc_toolchain = find_cpp_toolchain(ctx)
31*61c4878aSAndroid Build Coastguard Worker
32*61c4878aSAndroid Build Coastguard Worker    feature_configuration = cc_common.configure_features(
33*61c4878aSAndroid Build Coastguard Worker        ctx = ctx,
34*61c4878aSAndroid Build Coastguard Worker        cc_toolchain = cc_toolchain,
35*61c4878aSAndroid Build Coastguard Worker        requested_features = ctx.features,
36*61c4878aSAndroid Build Coastguard Worker        unsupported_features = ctx.disabled_features,
37*61c4878aSAndroid Build Coastguard Worker    )
38*61c4878aSAndroid Build Coastguard Worker    tool_path = cc_common.get_tool_for_action(
39*61c4878aSAndroid Build Coastguard Worker        feature_configuration = feature_configuration,
40*61c4878aSAndroid Build Coastguard Worker        action_name = action_name,
41*61c4878aSAndroid Build Coastguard Worker    )
42*61c4878aSAndroid Build Coastguard Worker
43*61c4878aSAndroid Build Coastguard Worker    ctx.actions.run_shell(
44*61c4878aSAndroid Build Coastguard Worker        inputs = depset(
45*61c4878aSAndroid Build Coastguard Worker            direct = [input],
46*61c4878aSAndroid Build Coastguard Worker            transitive = [
47*61c4878aSAndroid Build Coastguard Worker                cc_toolchain.all_files,
48*61c4878aSAndroid Build Coastguard Worker            ],
49*61c4878aSAndroid Build Coastguard Worker        ),
50*61c4878aSAndroid Build Coastguard Worker        outputs = [output],
51*61c4878aSAndroid Build Coastguard Worker        command = "{tool} {args}".format(
52*61c4878aSAndroid Build Coastguard Worker            tool = tool_path,
53*61c4878aSAndroid Build Coastguard Worker            args = action_args,
54*61c4878aSAndroid Build Coastguard Worker        ),
55*61c4878aSAndroid Build Coastguard Worker    )
56*61c4878aSAndroid Build Coastguard Worker
57*61c4878aSAndroid Build Coastguard Worker    return DefaultInfo(
58*61c4878aSAndroid Build Coastguard Worker        files = depset([output] + additional_outputs),
59*61c4878aSAndroid Build Coastguard Worker        executable = output if output_executable else None,
60*61c4878aSAndroid Build Coastguard Worker    )
61*61c4878aSAndroid Build Coastguard Worker
62*61c4878aSAndroid Build Coastguard Workerdef _pw_elf_to_bin_impl(ctx):
63*61c4878aSAndroid Build Coastguard Worker    return _run_action_on_executable(
64*61c4878aSAndroid Build Coastguard Worker        ctx = ctx,
65*61c4878aSAndroid Build Coastguard Worker        action_name = ctx.attr._objcopy[ActionNameInfo].name,
66*61c4878aSAndroid Build Coastguard Worker        action_args = "{args} {input} {output}".format(
67*61c4878aSAndroid Build Coastguard Worker            args = "-Obinary",
68*61c4878aSAndroid Build Coastguard Worker            input = ctx.executable.elf_input.path,
69*61c4878aSAndroid Build Coastguard Worker            output = ctx.outputs.bin_out.path,
70*61c4878aSAndroid Build Coastguard Worker        ),
71*61c4878aSAndroid Build Coastguard Worker        input = ctx.executable.elf_input,
72*61c4878aSAndroid Build Coastguard Worker        output = ctx.outputs.bin_out,
73*61c4878aSAndroid Build Coastguard Worker        additional_outputs = ctx.files.elf_input,
74*61c4878aSAndroid Build Coastguard Worker        output_executable = True,
75*61c4878aSAndroid Build Coastguard Worker    )
76*61c4878aSAndroid Build Coastguard Worker
77*61c4878aSAndroid Build Coastguard Workerpw_elf_to_bin = rule(
78*61c4878aSAndroid Build Coastguard Worker    implementation = _pw_elf_to_bin_impl,
79*61c4878aSAndroid Build Coastguard Worker    doc = """Takes in an ELF executable and uses the toolchain objcopy tool to
80*61c4878aSAndroid Build Coastguard Worker    create a binary file, not containing any ELF headers. This can be used to
81*61c4878aSAndroid Build Coastguard Worker    create a bare-metal bootable image.
82*61c4878aSAndroid Build Coastguard Worker    """,
83*61c4878aSAndroid Build Coastguard Worker    attrs = {
84*61c4878aSAndroid Build Coastguard Worker        "bin_out": attr.output(mandatory = True),
85*61c4878aSAndroid Build Coastguard Worker        "elf_input": attr.label(mandatory = True, executable = True, cfg = "target"),
86*61c4878aSAndroid Build Coastguard Worker        "_objcopy": attr.label(
87*61c4878aSAndroid Build Coastguard Worker            default = "@pw_toolchain//actions:objcopy_embed_data",
88*61c4878aSAndroid Build Coastguard Worker            providers = [ActionNameInfo],
89*61c4878aSAndroid Build Coastguard Worker        ),
90*61c4878aSAndroid Build Coastguard Worker    },
91*61c4878aSAndroid Build Coastguard Worker    executable = True,
92*61c4878aSAndroid Build Coastguard Worker    toolchains = use_cpp_toolchain(),
93*61c4878aSAndroid Build Coastguard Worker    fragments = ["cpp"],
94*61c4878aSAndroid Build Coastguard Worker)
95*61c4878aSAndroid Build Coastguard Worker
96*61c4878aSAndroid Build Coastguard Workerdef _pw_elf_to_dump_impl(ctx):
97*61c4878aSAndroid Build Coastguard Worker    return _run_action_on_executable(
98*61c4878aSAndroid Build Coastguard Worker        ctx = ctx,
99*61c4878aSAndroid Build Coastguard Worker        action_name = ctx.attr._objdump[ActionNameInfo].name,
100*61c4878aSAndroid Build Coastguard Worker        action_args = "{args} {input} > {output}".format(
101*61c4878aSAndroid Build Coastguard Worker            args = "-dx",
102*61c4878aSAndroid Build Coastguard Worker            input = ctx.executable.elf_input.path,
103*61c4878aSAndroid Build Coastguard Worker            output = ctx.outputs.dump_out.path,
104*61c4878aSAndroid Build Coastguard Worker        ),
105*61c4878aSAndroid Build Coastguard Worker        input = ctx.executable.elf_input,
106*61c4878aSAndroid Build Coastguard Worker        output = ctx.outputs.dump_out,
107*61c4878aSAndroid Build Coastguard Worker        additional_outputs = ctx.files.elf_input,
108*61c4878aSAndroid Build Coastguard Worker    )
109*61c4878aSAndroid Build Coastguard Worker
110*61c4878aSAndroid Build Coastguard Workerpw_elf_to_dump = rule(
111*61c4878aSAndroid Build Coastguard Worker    implementation = _pw_elf_to_dump_impl,
112*61c4878aSAndroid Build Coastguard Worker    doc = """Takes in an ELF executable and uses the toolchain objdump tool to
113*61c4878aSAndroid Build Coastguard Worker    create a text file dump of the contents.
114*61c4878aSAndroid Build Coastguard Worker    """,
115*61c4878aSAndroid Build Coastguard Worker    attrs = {
116*61c4878aSAndroid Build Coastguard Worker        "dump_out": attr.output(mandatory = True),
117*61c4878aSAndroid Build Coastguard Worker        "elf_input": attr.label(mandatory = True, executable = True, cfg = "target"),
118*61c4878aSAndroid Build Coastguard Worker        "_objdump": attr.label(
119*61c4878aSAndroid Build Coastguard Worker            default = "@pw_toolchain//actions:objdump_embed_data",
120*61c4878aSAndroid Build Coastguard Worker            providers = [ActionNameInfo],
121*61c4878aSAndroid Build Coastguard Worker        ),
122*61c4878aSAndroid Build Coastguard Worker    },
123*61c4878aSAndroid Build Coastguard Worker    toolchains = use_cpp_toolchain(),
124*61c4878aSAndroid Build Coastguard Worker    fragments = ["cpp"],
125*61c4878aSAndroid Build Coastguard Worker)
126