150 lines
5.4 KiB
Python
150 lines
5.4 KiB
Python
# postprocess_static_library takes a prebuilt archive (static library) and
|
|
# filters out unnecessary objects / redefines symbols files.
|
|
# In ESP8266's case, this is because the ROM already provides their
|
|
# implementations.
|
|
|
|
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
|
|
load("@bazel_tools//tools/cpp:toolchain_utils.bzl",
|
|
"find_cpp_toolchain", "use_cpp_toolchain")
|
|
|
|
def _impl(ctx):
|
|
# Find the toolchain configuration for the given platform. This is _not_
|
|
# the same way that other languages do this, as ctx.toolchains is empty
|
|
# for C/C++ (??)
|
|
cc_toolchain = find_cpp_toolchain(ctx)
|
|
|
|
# Populate the feature configuration. This is used by the various cc library
|
|
# functions to generate contexts.
|
|
feature_configuration = cc_common.configure_features(
|
|
ctx = ctx,
|
|
cc_toolchain = cc_toolchain,
|
|
requested_features = ctx.features,
|
|
unsupported_features = ctx.disabled_features
|
|
)
|
|
|
|
# We need these toolchain executables in order to process the library.
|
|
archive_tool = cc_common.get_tool_for_action(
|
|
feature_configuration = feature_configuration,
|
|
action_name = ACTION_NAMES.cpp_link_static_library,
|
|
)
|
|
|
|
objcopy_tool = cc_common.get_tool_for_action(
|
|
feature_configuration = feature_configuration,
|
|
action_name = "objcopy"
|
|
)
|
|
|
|
# Library label (target) for processing.
|
|
input_lib = ctx.file.library
|
|
|
|
# The output library will be named after the target of this rule.
|
|
output_lib = ctx.actions.declare_file(ctx.label.name + ".a")
|
|
|
|
# Bazel needs to know what files are inputs to a given action.
|
|
input_files = [input_lib]
|
|
|
|
# Construct the argument list to pass to the postprocessor script
|
|
args = ctx.actions.args()
|
|
args.add_all([
|
|
'--input', input_lib,
|
|
'--output', output_lib,
|
|
'--archive', archive_tool,
|
|
'--objcopy', objcopy_tool
|
|
])
|
|
|
|
# If removing objects from the library, create a file, write the objects
|
|
# to remove into it, and add it to the list of inputs for the action.
|
|
if len(ctx.attr.remove) > 0:
|
|
rmobjs = ctx.actions.declare_file(ctx.file.library.basename + ".remove")
|
|
ctx.actions.write(rmobjs, "\n".join(ctx.attr.remove))
|
|
input_files.append(rmobjs)
|
|
args.add_all(['--remove', rmobjs])
|
|
|
|
# Similar for redefining symbols.
|
|
if len(ctx.attr.redefine) > 0:
|
|
rdobjs = ctx.actions.declare_file(ctx.file.library.basename + ".redefine")
|
|
kv_pairs = [k + " " + v for k, v in ctx.attr.redefine.items()]
|
|
ctx.actions.write(rdobjs, "\n".join(kv_pairs) + "\n")
|
|
input_files.append(rdobjs)
|
|
args.add_all(['--redefine', rdobjs])
|
|
|
|
# TODO: Handle other ways to process a library.
|
|
|
|
# This runs the actual script to generate the processed library.
|
|
ctx.actions.run(
|
|
inputs = input_files,
|
|
outputs = [output_lib],
|
|
tools = cc_toolchain.all_files,
|
|
arguments = [args],
|
|
executable = ctx.executable.postprocessor,
|
|
)
|
|
|
|
# With the library in hand, the next step is to set up information for
|
|
# Bazel's C/C++ library to utilize the newly-created library.
|
|
library_to_link = cc_common.create_library_to_link(
|
|
actions = ctx.actions,
|
|
feature_configuration = feature_configuration,
|
|
static_library = output_lib,
|
|
)
|
|
|
|
linker_input = cc_common.create_linker_input(
|
|
libraries = depset([library_to_link]),
|
|
owner = ctx.label,
|
|
)
|
|
|
|
linking_context = cc_common.create_linking_context(
|
|
linker_inputs = depset([linker_input])
|
|
)
|
|
|
|
# Not yet complete: This part needs us to forward the library and its
|
|
# associated headers for targets to use without forwarding the original
|
|
# target's library (or you'll get a bunch of linking errors.
|
|
(compilation_context, compilation_outputs) = cc_common.compile(
|
|
actions = ctx.actions,
|
|
feature_configuration = feature_configuration,
|
|
cc_toolchain = cc_toolchain,
|
|
name = ctx.label.name,
|
|
)
|
|
|
|
# CcInfo is what is actually passed to future targets. We may need to merge
|
|
# this with the dependency's original info in order for builds to complete.
|
|
# Not sure yet.
|
|
this_cc_info = CcInfo(compilation_context = compilation_context, linking_context = linking_context)
|
|
cc_infos = [this_cc_info]
|
|
# print(this_cc_info.linking_context)
|
|
# print(ctx.attr.library[CcInfo].compilation_context)
|
|
# print(ctx.attr.library[CcInfo].linking_context)
|
|
# cc_infos.append(ctx.attr.library[CcInfo])
|
|
|
|
merged_cc_info = cc_common.merge_cc_infos(direct_cc_infos = [this_cc_info], cc_infos = cc_infos)
|
|
# print(merged_cc_info.linking_context)
|
|
|
|
return [
|
|
DefaultInfo(files = depset([output_lib])),
|
|
merged_cc_info
|
|
]
|
|
|
|
postprocess_static_library = rule(
|
|
implementation = _impl,
|
|
attrs = {
|
|
"library": attr.label(
|
|
allow_single_file = True,
|
|
),
|
|
"remove": attr.string_list(
|
|
doc = "A list of modules (objects) to remove from the library.",
|
|
),
|
|
"redefine": attr.string_dict(
|
|
doc = "A list of symbols to redefine in the library.",
|
|
),
|
|
"postprocessor": attr.label(
|
|
default = Label("//toolchain:postprocess_archive"),
|
|
executable = True,
|
|
cfg = "exec",
|
|
),
|
|
"_cc_toolchain": attr.label(
|
|
default = "@bazel_tools//tools/cpp:current_cc_toolchain",
|
|
)
|
|
},
|
|
fragments = ["cpp"],
|
|
toolchains = use_cpp_toolchain(),
|
|
)
|