blob: 98aad882cbb9b71b353ac05d9e934e678d45aa41 [file] [log] [blame] [edit]
# Copyright 2024 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Rules for declaring preprocessed linker scripts."""
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain")
load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME")
def _preprocess_linker_script_impl(ctx):
cc_toolchain = find_cpp_toolchain(ctx)
output_script = ctx.actions.declare_file(ctx.label.name + ".ld")
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
cxx_compiler_path = cc_common.get_tool_for_action(
feature_configuration = feature_configuration,
action_name = C_COMPILE_ACTION_NAME,
)
compilation_context = cc_common.merge_compilation_contexts(
compilation_contexts = [dep[CcInfo].compilation_context for dep in ctx.attr.deps],
)
c_compile_variables = cc_common.create_compile_variables(
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts,
include_directories = compilation_context.includes,
quote_include_directories = compilation_context.quote_includes,
system_include_directories = compilation_context.system_includes,
preprocessor_defines = depset(ctx.attr.defines, transitive = [compilation_context.defines]),
)
cmd_line = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
action_name = C_COMPILE_ACTION_NAME,
variables = c_compile_variables,
)
env = cc_common.get_environment_variables(
feature_configuration = feature_configuration,
action_name = C_COMPILE_ACTION_NAME,
variables = c_compile_variables,
)
ctx.actions.run(
outputs = [output_script],
inputs = depset(
[ctx.file.linker_script],
transitive = [compilation_context.headers, cc_toolchain.all_files],
),
executable = cxx_compiler_path,
arguments = [
"-E",
"-P",
"-xc",
ctx.file.linker_script.path,
"-o",
output_script.path,
] + cmd_line,
env = env,
)
linker_input = cc_common.create_linker_input(
owner = ctx.label,
user_link_flags = ["-T", output_script.path],
additional_inputs = depset(direct = [output_script]),
)
linking_context = cc_common.create_linking_context(
linker_inputs = depset(direct = [linker_input]),
)
return [
DefaultInfo(files = depset([output_script])),
CcInfo(linking_context = linking_context),
]
pw_linker_script = rule(
_preprocess_linker_script_impl,
doc = """Create a linker script target. Supports preprocessing with the C
preprocessor and adding the resulting linker script to linkopts. Also
provides a DefaultInfo containing the processed linker script.
""",
attrs = {
"copts": attr.string_list(doc = "C compile options."),
"defines": attr.string_list(doc = "C preprocessor defines."),
"deps": attr.label_list(
providers = [CcInfo],
doc = """Dependencies of this linker script. Can be used to provide
header files and defines. Only the CompilationContext of
the provided dependencies are used.""",
),
"linker_script": attr.label(
mandatory = True,
allow_single_file = True,
doc = "Linker script to preprocess.",
),
},
toolchains = use_cpp_toolchain(),
fragments = ["cpp"],
)