xref: /aosp_15_r20/external/pigweed/pw_build/pw_linker_script.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 declaring preprocessed linker scripts."""
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("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME")
18*61c4878aSAndroid Build Coastguard Worker
19*61c4878aSAndroid Build Coastguard Workerdef _preprocess_linker_script_impl(ctx):
20*61c4878aSAndroid Build Coastguard Worker    cc_toolchain = find_cpp_toolchain(ctx)
21*61c4878aSAndroid Build Coastguard Worker    output_script = ctx.actions.declare_file(ctx.label.name + ".ld")
22*61c4878aSAndroid Build Coastguard Worker    feature_configuration = cc_common.configure_features(
23*61c4878aSAndroid Build Coastguard Worker        ctx = ctx,
24*61c4878aSAndroid Build Coastguard Worker        cc_toolchain = cc_toolchain,
25*61c4878aSAndroid Build Coastguard Worker        requested_features = ctx.features,
26*61c4878aSAndroid Build Coastguard Worker        unsupported_features = ctx.disabled_features,
27*61c4878aSAndroid Build Coastguard Worker    )
28*61c4878aSAndroid Build Coastguard Worker    cxx_compiler_path = cc_common.get_tool_for_action(
29*61c4878aSAndroid Build Coastguard Worker        feature_configuration = feature_configuration,
30*61c4878aSAndroid Build Coastguard Worker        action_name = C_COMPILE_ACTION_NAME,
31*61c4878aSAndroid Build Coastguard Worker    )
32*61c4878aSAndroid Build Coastguard Worker    compilation_context = cc_common.merge_compilation_contexts(
33*61c4878aSAndroid Build Coastguard Worker        compilation_contexts = [dep[CcInfo].compilation_context for dep in ctx.attr.deps],
34*61c4878aSAndroid Build Coastguard Worker    )
35*61c4878aSAndroid Build Coastguard Worker    c_compile_variables = cc_common.create_compile_variables(
36*61c4878aSAndroid Build Coastguard Worker        feature_configuration = feature_configuration,
37*61c4878aSAndroid Build Coastguard Worker        cc_toolchain = cc_toolchain,
38*61c4878aSAndroid Build Coastguard Worker        user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts,
39*61c4878aSAndroid Build Coastguard Worker        include_directories = compilation_context.includes,
40*61c4878aSAndroid Build Coastguard Worker        quote_include_directories = compilation_context.quote_includes,
41*61c4878aSAndroid Build Coastguard Worker        system_include_directories = compilation_context.system_includes,
42*61c4878aSAndroid Build Coastguard Worker        preprocessor_defines = depset(ctx.attr.defines, transitive = [compilation_context.defines]),
43*61c4878aSAndroid Build Coastguard Worker    )
44*61c4878aSAndroid Build Coastguard Worker    cmd_line = cc_common.get_memory_inefficient_command_line(
45*61c4878aSAndroid Build Coastguard Worker        feature_configuration = feature_configuration,
46*61c4878aSAndroid Build Coastguard Worker        action_name = C_COMPILE_ACTION_NAME,
47*61c4878aSAndroid Build Coastguard Worker        variables = c_compile_variables,
48*61c4878aSAndroid Build Coastguard Worker    )
49*61c4878aSAndroid Build Coastguard Worker    env = cc_common.get_environment_variables(
50*61c4878aSAndroid Build Coastguard Worker        feature_configuration = feature_configuration,
51*61c4878aSAndroid Build Coastguard Worker        action_name = C_COMPILE_ACTION_NAME,
52*61c4878aSAndroid Build Coastguard Worker        variables = c_compile_variables,
53*61c4878aSAndroid Build Coastguard Worker    )
54*61c4878aSAndroid Build Coastguard Worker    ctx.actions.run(
55*61c4878aSAndroid Build Coastguard Worker        outputs = [output_script],
56*61c4878aSAndroid Build Coastguard Worker        inputs = depset(
57*61c4878aSAndroid Build Coastguard Worker            [ctx.file.linker_script],
58*61c4878aSAndroid Build Coastguard Worker            transitive = [compilation_context.headers, cc_toolchain.all_files],
59*61c4878aSAndroid Build Coastguard Worker        ),
60*61c4878aSAndroid Build Coastguard Worker        executable = cxx_compiler_path,
61*61c4878aSAndroid Build Coastguard Worker        arguments = [
62*61c4878aSAndroid Build Coastguard Worker            "-E",
63*61c4878aSAndroid Build Coastguard Worker            "-P",
64*61c4878aSAndroid Build Coastguard Worker            "-xc",
65*61c4878aSAndroid Build Coastguard Worker            ctx.file.linker_script.path,
66*61c4878aSAndroid Build Coastguard Worker            "-o",
67*61c4878aSAndroid Build Coastguard Worker            output_script.path,
68*61c4878aSAndroid Build Coastguard Worker        ] + cmd_line,
69*61c4878aSAndroid Build Coastguard Worker        env = env,
70*61c4878aSAndroid Build Coastguard Worker    )
71*61c4878aSAndroid Build Coastguard Worker    linker_input = cc_common.create_linker_input(
72*61c4878aSAndroid Build Coastguard Worker        owner = ctx.label,
73*61c4878aSAndroid Build Coastguard Worker        user_link_flags = ["-T", output_script.path],
74*61c4878aSAndroid Build Coastguard Worker        additional_inputs = depset(direct = [output_script]),
75*61c4878aSAndroid Build Coastguard Worker    )
76*61c4878aSAndroid Build Coastguard Worker    linking_context = cc_common.create_linking_context(
77*61c4878aSAndroid Build Coastguard Worker        linker_inputs = depset(direct = [linker_input]),
78*61c4878aSAndroid Build Coastguard Worker    )
79*61c4878aSAndroid Build Coastguard Worker    return [
80*61c4878aSAndroid Build Coastguard Worker        DefaultInfo(files = depset([output_script])),
81*61c4878aSAndroid Build Coastguard Worker        CcInfo(linking_context = linking_context),
82*61c4878aSAndroid Build Coastguard Worker    ]
83*61c4878aSAndroid Build Coastguard Worker
84*61c4878aSAndroid Build Coastguard Workerpw_linker_script = rule(
85*61c4878aSAndroid Build Coastguard Worker    _preprocess_linker_script_impl,
86*61c4878aSAndroid Build Coastguard Worker    doc = """Create a linker script target. Supports preprocessing with the C
87*61c4878aSAndroid Build Coastguard Worker    preprocessor and adding the resulting linker script to linkopts. Also
88*61c4878aSAndroid Build Coastguard Worker    provides a DefaultInfo containing the processed linker script.
89*61c4878aSAndroid Build Coastguard Worker    """,
90*61c4878aSAndroid Build Coastguard Worker    attrs = {
91*61c4878aSAndroid Build Coastguard Worker        "copts": attr.string_list(doc = "C compile options."),
92*61c4878aSAndroid Build Coastguard Worker        "defines": attr.string_list(doc = "C preprocessor defines."),
93*61c4878aSAndroid Build Coastguard Worker        "deps": attr.label_list(
94*61c4878aSAndroid Build Coastguard Worker            providers = [CcInfo],
95*61c4878aSAndroid Build Coastguard Worker            doc = """Dependencies of this linker script. Can be used to provide
96*61c4878aSAndroid Build Coastguard Worker                     header files and defines. Only the CompilationContext of
97*61c4878aSAndroid Build Coastguard Worker                     the provided dependencies are used.""",
98*61c4878aSAndroid Build Coastguard Worker        ),
99*61c4878aSAndroid Build Coastguard Worker        "linker_script": attr.label(
100*61c4878aSAndroid Build Coastguard Worker            mandatory = True,
101*61c4878aSAndroid Build Coastguard Worker            allow_single_file = True,
102*61c4878aSAndroid Build Coastguard Worker            doc = "Linker script to preprocess.",
103*61c4878aSAndroid Build Coastguard Worker        ),
104*61c4878aSAndroid Build Coastguard Worker        "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
105*61c4878aSAndroid Build Coastguard Worker    },
106*61c4878aSAndroid Build Coastguard Worker    toolchains = use_cpp_toolchain(),
107*61c4878aSAndroid Build Coastguard Worker    fragments = ["cpp"],
108*61c4878aSAndroid Build Coastguard Worker)
109