| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- # 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
- )
|