mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-19 07:06:46 +00:00
184 lines
6.7 KiB
Python
184 lines
6.7 KiB
Python
# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
|
|
# See https://llvm.org/LICENSE.txt for license information.
|
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
"""Configuration for the llvm-driver tool."""
|
|
|
|
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
|
|
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
|
|
|
|
# Mapping from every tool to the cc_library that implements the tool's entrypoint.
|
|
_TOOLS = {
|
|
"clang-scan-deps": "//clang:clang-scan-deps-lib",
|
|
"clang": "//clang:clang-driver",
|
|
"dsymutil": "//llvm:dsymutil-lib",
|
|
"lld": "//lld:lld-lib",
|
|
"llvm-ar": "//llvm:llvm-ar-lib",
|
|
"llvm-cgdata": "//llvm:llvm-cgdata-lib",
|
|
"llvm-cxxfilt": "//llvm:llvm-cxxfilt-lib",
|
|
"llvm-debuginfod-find": "//llvm:llvm-debuginfod-find-lib",
|
|
"llvm-dwp": "//llvm:llvm-dwp-lib",
|
|
"llvm-gsymutil": "//llvm:llvm-gsymutil-lib",
|
|
"llvm-ifs": "//llvm:llvm-ifs-lib",
|
|
"llvm-libtool-darwin": "//llvm:llvm-libtool-darwin-lib",
|
|
"llvm-lipo": "//llvm:llvm-lipo-lib",
|
|
"llvm-ml": "//llvm:llvm-ml-lib",
|
|
"llvm-mt": "//llvm:llvm-mt-lib",
|
|
"llvm-nm": "//llvm:llvm-nm-lib",
|
|
"llvm-objcopy": "//llvm:llvm-objcopy-lib",
|
|
"llvm-objdump": "//llvm:llvm-objdump-lib",
|
|
"llvm-profdata": "//llvm:llvm-profdata-lib",
|
|
"llvm-rc": "//llvm:llvm-rc-lib",
|
|
"llvm-readobj": "//llvm:llvm-readobj-lib",
|
|
"llvm-size": "//llvm:llvm-size-lib",
|
|
"llvm-symbolizer": "//llvm:llvm-symbolizer-lib",
|
|
"sancov": "//llvm:sancov-lib",
|
|
}
|
|
|
|
# Tools automatically get their own name as an alias, but there may be additional
|
|
# aliases for a given tool.
|
|
_EXTRA_ALIASES = {
|
|
"clang": ["clang++", "clang-cl", "clang-cpp"],
|
|
"lld": ["ld", "lld-link", "ld.lld", "ld64.lld", "wasm-ld"],
|
|
"llvm-ar": ["ranlib", "lib", "dlltool"],
|
|
"llvm-cxxfilt": ["c++filt"],
|
|
"llvm-objcopy": ["bitcode-strip", "install-name-tool", "strip"],
|
|
"llvm-objdump": ["otool"],
|
|
"llvm-rc": ["windres"],
|
|
"llvm-readobj": ["readelf"],
|
|
"llvm-symbolizer": ["addr2line"],
|
|
}
|
|
|
|
def _validated_string_list_flag_impl(ctx):
|
|
invalid_values = [v for v in ctx.build_setting_value if v not in ctx.attr.values]
|
|
if invalid_values:
|
|
fail("Tool(s) [{}] are not in the known list of tools: {}".format(
|
|
", ".join(invalid_values),
|
|
", ".join(ctx.attr.values),
|
|
))
|
|
return BuildSettingInfo(value = ctx.build_setting_value)
|
|
|
|
# Like string_list_flag, but with the validation that string_flag provides.
|
|
_validated_string_list_flag = rule(
|
|
implementation = _validated_string_list_flag_impl,
|
|
build_setting = config.string_list(flag = True),
|
|
attrs = {
|
|
"values": attr.string_list(
|
|
doc = "The list of allowed values for this setting. An error is raised if any other value is given.",
|
|
),
|
|
},
|
|
doc = "A string list-typed build setting that can be set on the command line",
|
|
)
|
|
|
|
def generate_driver_selects(name):
|
|
"""Generates flags and config settings to configure the tool list.
|
|
|
|
By default, all supported tools are included in the "llvm" driver binary.
|
|
To build only a subset, specify just the subset you want as the flag.
|
|
For example, to produce a binary with just llvm-nm and llvm-size, run:
|
|
|
|
$ bazel build \
|
|
--@llvm-project//llvm:driver-tools=llvm-nm,llvm-size \
|
|
@llvm-project//llvm:llvm
|
|
|
|
Note: this assumes the flag name is "driver-tools" by being invoked as:
|
|
generate_driver_selects(name = "driver-tools")
|
|
|
|
Args:
|
|
name: the name of the flag that configures which tools are included.
|
|
"""
|
|
|
|
_validated_string_list_flag(
|
|
name = name,
|
|
build_setting_default = _TOOLS.keys(),
|
|
values = _TOOLS.keys(),
|
|
)
|
|
for tool in _TOOLS.keys():
|
|
native.config_setting(
|
|
name = "{}-include-{}".format(name, tool),
|
|
flag_values = {name: tool},
|
|
)
|
|
|
|
def select_driver_tools(flag):
|
|
"""Produce a list of tool deps based on generate_driver_selects().
|
|
|
|
Args:
|
|
flag: name that was used for generate_driver_selects().
|
|
Returns:
|
|
List of tool deps based on generate_driver_selects().
|
|
"""
|
|
tools = []
|
|
for tool, target in _TOOLS.items():
|
|
tools += select({
|
|
"{}-include-{}".format(flag, tool): [target],
|
|
"//conditions:default": [],
|
|
})
|
|
return tools
|
|
|
|
def _generate_driver_tools_def_impl(ctx):
|
|
# Depending on how the LLVM build files are included,
|
|
# it may or may not have the @llvm-project repo prefix.
|
|
# Compare just on the name. We could also include the package,
|
|
# but the name itself is unique in practice.
|
|
label_to_name = {Label(v).name: k for k, v in _TOOLS.items()}
|
|
|
|
# Reverse sort by the *main* tool name, but keep aliases together.
|
|
# This is consistent with how tools/llvm-driver/CMakeLists.txt does it,
|
|
# and this makes sure that more specific tools are checked first.
|
|
# For example, "clang-scan-deps" should not match "clang".
|
|
tools = [label_to_name[tool.label.name] for tool in ctx.attr.driver_tools]
|
|
tool_alias_pairs = []
|
|
for tool_name in reversed(tools):
|
|
tool_alias_pairs.append((tool_name, tool_name))
|
|
for extra_alias in _EXTRA_ALIASES.get(tool_name, []):
|
|
tool_alias_pairs.append((tool_name, extra_alias))
|
|
|
|
lines = [
|
|
'LLVM_DRIVER_TOOL("{alias}", {tool})'.format(
|
|
tool = tool_name.replace("-", "_"),
|
|
alias = alias.removeprefix("llvm-"),
|
|
)
|
|
for (tool_name, alias) in tool_alias_pairs
|
|
]
|
|
lines.append("#undef LLVM_DRIVER_TOOL")
|
|
|
|
ctx.actions.write(
|
|
output = ctx.outputs.out,
|
|
content = "\n".join(lines),
|
|
)
|
|
|
|
generate_driver_tools_def = rule(
|
|
implementation = _generate_driver_tools_def_impl,
|
|
doc = """Generate a list of LLVM_DRIVER_TOOL macros.
|
|
See tools/llvm-driver/CMakeLists.txt for the reference implementation.""",
|
|
attrs = {
|
|
"driver_tools": attr.label_list(
|
|
doc = "List of tools to include in the generated header. Use select_driver_tools() to provide this.",
|
|
providers = [CcInfo],
|
|
),
|
|
"out": attr.output(
|
|
doc = "Name of the generated .def output file.",
|
|
mandatory = True,
|
|
),
|
|
},
|
|
)
|
|
|
|
def llvm_driver_cc_binary(
|
|
name,
|
|
deps = None,
|
|
**kwargs):
|
|
"""cc_binary wrapper for binaries using the llvm-driver template."""
|
|
expand_template(
|
|
name = "_gen_" + name,
|
|
out = name + "-driver.cpp",
|
|
substitutions = {"@TOOL_NAME@": name.replace("-", "_")},
|
|
template = "//llvm:cmake/modules/llvm-driver-template.cpp.in",
|
|
)
|
|
deps = deps or []
|
|
native.cc_binary(
|
|
name = name,
|
|
srcs = [name + "-driver.cpp"],
|
|
deps = deps + ["//llvm:Support"],
|
|
**kwargs
|
|
)
|