# Copyright 2024 The Bazel Authors. All rights reserved. # # 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 # # http://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. """Implementation of cc_tool_map.""" load( "//cc/toolchains/impl:collect.bzl", "collect_provider", "collect_tools", ) load( ":cc_toolchain_info.bzl", "ActionTypeSetInfo", "ToolConfigInfo", ) def _cc_tool_map_impl(ctx): tools = collect_tools(ctx, ctx.attr.tools) action_sets = collect_provider(ctx.attr.actions, ActionTypeSetInfo) action_to_tool = {} action_to_as = {} for i in range(len(action_sets)): action_set = action_sets[i] tool = tools[ctx.attr.tool_index_for_action[i]] for action in action_set.actions.to_list(): if action in action_to_as: fail("The action %s appears multiple times in your tool_map (as %s and %s)" % (action.label, action_set.label, action_to_as[action].label)) action_to_as[action] = action_set action_to_tool[action] = tool return [ToolConfigInfo(label = ctx.label, configs = action_to_tool)] _cc_tool_map = rule( implementation = _cc_tool_map_impl, # @unsorted-dict-items attrs = { "actions": attr.label_list( providers = [ActionTypeSetInfo], mandatory = True, doc = """A list of action names to apply this action to. See //cc/toolchains/actions:BUILD for valid options. """, ), "tools": attr.label_list( mandatory = True, cfg = "exec", allow_files = True, doc = """The tool to use for the specified actions. The tool may be a `cc_tool` or other executable rule. """, ), "tool_index_for_action": attr.int_list( mandatory = True, doc = """The index of the tool in `tools` for the action in `actions`.""", ), }, provides = [ToolConfigInfo], ) def cc_tool_map(name, tools, **kwargs): """A toolchain configuration rule that maps toolchain actions to tools. A `cc_tool_map` aggregates all the tools that may be used for a given toolchain and maps them to their corresponding actions. Conceptually, this is similar to the `CXX=/path/to/clang++` environment variables that most build systems use to determine which tools to use for a given action. To simplify usage, some actions have been grouped together (for example, [@rules_cc//cc/toolchains/actions:cpp_compile_actions](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/actions/BUILD)) to logically express "all the C++ compile actions". In Bazel, there is a little more granularity to the mapping, so the mapping doesn't follow the traditional `CXX`, `AR`, etc. naming scheme. For a comprehensive list of all the well-known actions, see //cc/toolchains/actions:BUILD. Example usage: ``` load("//cc/toolchains:tool_map.bzl", "cc_tool_map") cc_tool_map( name = "all_tools", tools = { "//cc/toolchains/actions:assembly_actions": ":asm", "//cc/toolchains/actions:c_compile": ":clang", "//cc/toolchains/actions:cpp_compile_actions": ":clang++", "//cc/toolchains/actions:link_actions": ":lld", "//cc/toolchains/actions:objcopy_embed_data": ":llvm-objcopy", "//cc/toolchains/actions:strip": ":llvm-strip", "//cc/toolchains/actions:ar_actions": ":llvm-ar", }, ) ``` Args: name: (str) The name of the target. tools: (Dict[Label, Label]) A mapping between `cc_action_type`/`cc_action_type_set` targets and the `cc_tool` or executable target that implements that action. **kwargs: [common attributes](https://bazel.build/reference/be/common-definitions#common-attributes) that should be applied to this rule. """ actions = [] tool_index_for_action = [] deduplicated_tools = {} for action, tool in tools.items(): actions.append(action) label = native.package_relative_label(tool) if label not in deduplicated_tools: deduplicated_tools[label] = len(deduplicated_tools) tool_index_for_action.append(deduplicated_tools[label]) _cc_tool_map( name = name, actions = actions, tools = deduplicated_tools.keys(), tool_index_for_action = tool_index_for_action, **kwargs )