mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-03 22:02:51 +01:00
Also consolidate on using `//bazel/cc_rules:defs.bzl` where appropriate. Also update a couple of Bazel modules deps of `@rules_cc` to the latest versions.
151 lines
6.4 KiB
Python
151 lines
6.4 KiB
Python
# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
# Exceptions. See /LICENSE for license information.
|
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
"""Provides variables and rules to automate working with LLVM's CLI tools."""
|
|
|
|
load("//bazel/cc_rules:defs.bzl", "cc_library")
|
|
|
|
# The main LLVM command line tools, including their "primary" name, binary name,
|
|
# and the library dependency required to use them.
|
|
LLVM_MAIN_TOOLS = {
|
|
"ar": struct(bin_name = "llvm-ar", lib = "@llvm-project//llvm:llvm-ar-lib"),
|
|
"cgdata": struct(bin_name = "llvm-cgdata", lib = "@llvm-project//llvm:llvm-cgdata-lib"),
|
|
"cxxfilt": struct(bin_name = "llvm-cxxfilt", lib = "@llvm-project//llvm:llvm-cxxfilt-lib"),
|
|
"debuginfod-find": struct(bin_name = "llvm-debuginfod-find", lib = "@llvm-project//llvm:llvm-debuginfod-find-lib"),
|
|
"dsymutil": struct(bin_name = "dsymutil", lib = "@llvm-project//llvm:dsymutil-lib"),
|
|
"dwp": struct(bin_name = "llvm-dwp", lib = "@llvm-project//llvm:llvm-dwp-lib"),
|
|
"gsymutil": struct(bin_name = "llvm-gsymutil", lib = "@llvm-project//llvm:llvm-gsymutil-lib"),
|
|
"ifs": struct(bin_name = "llvm-ifs", lib = "@llvm-project//llvm:llvm-ifs-lib"),
|
|
"libtool-darwin": struct(bin_name = "llvm-libtool-darwin", lib = "@llvm-project//llvm:llvm-libtool-darwin-lib"),
|
|
"lipo": struct(bin_name = "llvm-lipo", lib = "@llvm-project//llvm:llvm-lipo-lib"),
|
|
"ml": struct(bin_name = "llvm-ml", lib = "@llvm-project//llvm:llvm-ml-lib"),
|
|
"mt": struct(bin_name = "llvm-mt", lib = "@llvm-project//llvm:llvm-mt-lib"),
|
|
"nm": struct(bin_name = "llvm-nm", lib = "@llvm-project//llvm:llvm-nm-lib"),
|
|
"objcopy": struct(bin_name = "llvm-objcopy", lib = "@llvm-project//llvm:llvm-objcopy-lib"),
|
|
"objdump": struct(bin_name = "llvm-objdump", lib = "@llvm-project//llvm:llvm-objdump-lib"),
|
|
"rc": struct(bin_name = "llvm-rc", lib = "@llvm-project//llvm:llvm-rc-lib"),
|
|
"readobj": struct(bin_name = "llvm-readobj", lib = "@llvm-project//llvm:llvm-readobj-lib"),
|
|
"sancov": struct(bin_name = "sancov", lib = "@llvm-project//llvm:sancov-lib"),
|
|
"size": struct(bin_name = "llvm-size", lib = "@llvm-project//llvm:llvm-size-lib"),
|
|
"symbolizer": struct(bin_name = "llvm-symbolizer", lib = "@llvm-project//llvm:llvm-symbolizer-lib"),
|
|
}
|
|
|
|
# A collection of additional alias names that should be available for the main
|
|
# tools. The key is the main tool with the support for these names, followed by
|
|
# a list of the aliased names.
|
|
#
|
|
# Note that we don't track separate binary names for the alias names as those
|
|
# are always formed by prepending `llvm-` for the aliases.
|
|
LLVM_TOOL_ALIASES = {
|
|
"ar": ["ranlib", "lib", "dlltool"],
|
|
"objcopy": ["bitcode-strip", "install-name-tool", "strip"],
|
|
"objdump": ["otool"],
|
|
"rc": ["windres"],
|
|
"readobj": ["readelf"],
|
|
"symbolizer": ["addr2line"],
|
|
}
|
|
|
|
_DEF_FILE_TEMPLATE = """
|
|
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
// This is a generated X-macro header for defining LLVM tools. It does not use
|
|
// `#include` guards, and instead is designed to be `#include`ed after the
|
|
// x-macro is defined in order for its inclusion to expand to the desired
|
|
// output. Macro definitions are cleaned up at the end of this file.
|
|
//
|
|
// Each X-macro takes four arguments:
|
|
// - `Id` is the identifier-shaped PascalCased tool name.
|
|
// - `Name` is a string literal of the tool name.
|
|
// - `BinName` is a string literal of the binary name of the tool when installed
|
|
// as a stand-alone command line tool.
|
|
// - `MainFn` is the function symbol name used to run the tool as-if its `main`.
|
|
//
|
|
// There are three X-macros available:
|
|
// - `CARBON_LLVM_TOOL` is available for every tool.
|
|
// - `CARBON_LLVM_MAIN_TOOL` is available for each tool with a distinct
|
|
// `MainFn` symbol name.
|
|
// - `CARBON_LLVM_ALIAS_TOOL` is available for each tool that is an alias of
|
|
// some other tool. It's `MainFn` will be the alias-target symbol name.
|
|
//
|
|
// See toolchain/driver/llvm_tools.bzl for more details.
|
|
|
|
#ifndef CARBON_LLVM_TOOL
|
|
#define CARBON_LLVM_TOOL(Id, Name, BinName, MainFn)
|
|
#endif
|
|
|
|
#ifndef CARBON_LLVM_MAIN_TOOL
|
|
#define CARBON_LLVM_MAIN_TOOL(Id, Name, BinName, MainFn) \\
|
|
CARBON_LLVM_TOOL(Id, Name, BinName, MainFn)
|
|
#endif
|
|
|
|
#ifndef CARBON_LLVM_ALIAS_TOOL
|
|
#define CARBON_LLVM_ALIAS_TOOL(Id, Name, BinName, MainFn) \\
|
|
CARBON_LLVM_TOOL(Id, Name, BinName, MainFn)
|
|
#endif
|
|
|
|
{}
|
|
|
|
#undef CARBON_LLVM_TOOL
|
|
#undef CARBON_LLVM_MAIN_TOOL
|
|
#undef CARBON_LLVM_ALIAS_TOOL
|
|
"""
|
|
|
|
_DEF_MACRO_TEMPLATE = """
|
|
CARBON_LLVM_{kind}TOOL({id}, "{name}", "{bin_name}", {main_fn})
|
|
""".strip()
|
|
|
|
def _build_def_macro(kind, name, bin_name, main_info):
|
|
id = "".join([w.title() for w in name.split("-")])
|
|
main_fn = main_info.bin_name.replace("-", "_") + "_main"
|
|
return _DEF_MACRO_TEMPLATE.format(
|
|
kind = kind,
|
|
id = id,
|
|
name = name,
|
|
bin_name = bin_name,
|
|
main_fn = main_fn,
|
|
)
|
|
|
|
def _generate_llvm_tools_def_rule(ctx):
|
|
def_lines = []
|
|
|
|
for name, tool_info in LLVM_MAIN_TOOLS.items():
|
|
def_lines.append(_build_def_macro("MAIN_", name, tool_info.bin_name, tool_info))
|
|
|
|
for target, aliases in LLVM_TOOL_ALIASES.items():
|
|
tool_info = LLVM_MAIN_TOOLS[target]
|
|
for alias in aliases:
|
|
bin_name = "llvm-" + alias
|
|
def_lines.append(_build_def_macro("ALIAS_", alias, bin_name, tool_info))
|
|
|
|
def_file = ctx.actions.declare_file(ctx.label.name)
|
|
ctx.actions.write(def_file, _DEF_FILE_TEMPLATE.format("\n".join(def_lines)))
|
|
return [DefaultInfo(files = depset([def_file]))]
|
|
|
|
generate_llvm_tools_def_rule = rule(
|
|
implementation = _generate_llvm_tools_def_rule,
|
|
attrs = {},
|
|
)
|
|
|
|
def generate_llvm_tools_def(name, out, **kwargs):
|
|
"""Generates the LLVM tools `.def` file.
|
|
|
|
This first generates the `.def` file into the `out` filename, and then
|
|
synthesizes a `cc_library` rule exporting that file in its `textual_hdrs`.
|
|
|
|
The `cc_library` rule name is the provided `name` and should be depended on
|
|
by code that includes the generated file. The `kwargs` are expanded into the
|
|
`cc_library` in case other attributes need to be configured there.
|
|
|
|
The two-step process is necessary to avoid trying to compile or otherwise
|
|
process the generated file as something other than a textual header.
|
|
"""
|
|
generate_llvm_tools_def_rule(name = out)
|
|
cc_library(
|
|
name = name,
|
|
textual_hdrs = [out],
|
|
**kwargs
|
|
)
|