-
Notifications
You must be signed in to change notification settings - Fork 172
Allow passing env to cc_tool #598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dzbarsky
wants to merge
1
commit into
bazelbuild:main
Choose a base branch
from
dzbarsky:zbarsky/tool-env
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Copyright 2026 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. | ||
| """Helpers for passing possibly duplicated labels through rule attributes.""" | ||
|
|
||
| def deduplicate_label_list(name, labels): | ||
| """Deduplicates a label list while preserving the original indexes. | ||
|
|
||
| Args: | ||
| name: Name of the macro target using this helper. | ||
| labels: Labels to normalize and deduplicate. | ||
|
|
||
| Returns: | ||
| A struct with deduplicated labels and original-to-deduplicated indexes. | ||
| """ | ||
| deduplicated_labels = {} | ||
| index_for_label = [] | ||
|
|
||
| for label in labels: | ||
| package_relative_label = native.package_relative_label(label) | ||
| if package_relative_label not in deduplicated_labels: | ||
| deduplicated_labels[package_relative_label] = len(deduplicated_labels) | ||
| index_for_label.append(deduplicated_labels[package_relative_label]) | ||
|
|
||
| return struct( | ||
| labels = deduplicated_labels.keys(), | ||
| indexes = index_for_label, | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,8 @@ | |
|
|
||
| load("@bazel_skylib//rules/directory:providers.bzl", "DirectoryInfo") | ||
| load("//cc/toolchains/impl:collect.bzl", "collect_data", "collect_provider") | ||
| load("//cc/toolchains/impl:label_utils.bzl", "deduplicate_label_list") | ||
| load("//cc/toolchains/impl:nested_args.bzl", "format_dict_values") | ||
| load( | ||
| ":cc_toolchain_info.bzl", | ||
| "ToolCapabilityInfo", | ||
|
|
@@ -30,12 +32,22 @@ def _cc_tool_impl(ctx): | |
| else: | ||
| fail("Expected cc_tool's src attribute to be either an executable or a single file") | ||
|
|
||
| format_targets = {} | ||
| for i in range(len(ctx.attr.format_keys)): | ||
| format_targets[ctx.attr.format_keys[i]] = ctx.attr.format_values[ctx.attr.format_value_indexes[i]] | ||
| env, _ = format_dict_values( | ||
| env = ctx.attr.env, | ||
| format = format_targets, | ||
| must_use = format_targets.keys(), | ||
| ) | ||
|
|
||
| runfiles = collect_data(ctx, ctx.attr.data + [ctx.attr.src]) | ||
| tool = ToolInfo( | ||
| label = ctx.label, | ||
| exe = exe, | ||
| runfiles = runfiles, | ||
| execution_requirements = tuple(ctx.attr.tags), | ||
| env = env, | ||
| allowlist_include_directories = depset( | ||
| direct = [d[DirectoryInfo] for d in ctx.attr.allowlist_include_directories], | ||
| ), | ||
|
|
@@ -59,7 +71,7 @@ def _cc_tool_impl(ctx): | |
| ), | ||
| ] | ||
|
|
||
| cc_tool = rule( | ||
| _cc_tool = rule( | ||
| implementation = _cc_tool_impl, | ||
| # @unsorted-dict-items | ||
| attrs = { | ||
|
|
@@ -98,6 +110,31 @@ add them to 'data' as well. | |
| This can help work around errors like: | ||
| `the source file 'main.c' includes the following non-builtin files with absolute paths | ||
| (if these are builtin files, make sure these paths are in your toolchain)`. | ||
| """, | ||
| ), | ||
| "env": attr.string_dict( | ||
| doc = """Environment variables to apply when running this tool. | ||
|
|
||
| Format expansion is performed on values using the format attribute. | ||
| """, | ||
| ), | ||
| "format_keys": attr.string_list( | ||
| doc = """Format strings used in substitutions for env values. | ||
|
|
||
| Use the cc_tool macro's format attribute instead. | ||
| """, | ||
| ), | ||
| "format_values": attr.label_list( | ||
| allow_files = True, | ||
| doc = """Targets used in substitutions for env values. | ||
|
|
||
| Use the cc_tool macro's format attribute instead. | ||
| """, | ||
| ), | ||
| "format_value_indexes": attr.int_list( | ||
| doc = """Index of the target in format_values for each format key. | ||
|
|
||
| Use the cc_tool macro's format attribute instead. | ||
| """, | ||
| ), | ||
| "capabilities": attr.label_list( | ||
|
|
@@ -136,3 +173,91 @@ cc_tool( | |
| """, | ||
| executable = True, | ||
| ) | ||
|
|
||
| def cc_tool( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From internal review:
(maybe add a TODO?) |
||
| *, | ||
| name, | ||
| src = None, | ||
| data = None, | ||
| allowlist_include_directories = None, | ||
| env = None, | ||
| format = {}, | ||
| capabilities = None, | ||
| **kwargs): | ||
| """Declares a tool for use by toolchain actions. | ||
|
|
||
| `cc_tool` rules are used in a `cc_tool_map` rule to ensure all files and | ||
| metadata required to run a tool are available when constructing a `cc_toolchain`. | ||
|
|
||
| In general, include all files that are always required to run a tool (e.g. libexec/** and | ||
| cross-referenced tools in bin/*) in the [data](#cc_tool-data) attribute. If some files are only | ||
| required when certain flags are passed to the tool, consider using a `cc_args` rule to | ||
| bind the files to the flags that require them. This reduces the overhead required to properly | ||
| enumerate a sandbox with all the files required to run a tool, and ensures that there isn't | ||
| unintentional leakage across configurations and actions. | ||
|
|
||
| Example: | ||
| ``` | ||
| load("//cc/toolchains:tool.bzl", "cc_tool") | ||
|
|
||
| cc_tool( | ||
| name = "clang", | ||
| src = "@llvm_toolchain//:bin/clang", | ||
| # Suppose clang needs libc to run. | ||
| data = ["@llvm_toolchain//:lib/x86_64-linux-gnu/libc.so.6"] | ||
| capabilities = ["//cc/toolchains/capabilities:supports_pic"], | ||
| ) | ||
| ``` | ||
|
|
||
| Args: | ||
| name: (str) The name of the target. | ||
| src: (Label) The underlying binary that this tool represents. | ||
| Usually just a single prebuilt (e.g. @toolchain//:bin/clang), but may be any | ||
| executable label. | ||
| data: (List[Label]) Additional files that are required for this tool to run. | ||
| Frequently, clang and gcc require additional files to execute as they often shell out to | ||
| other binaries (e.g. `cc1`). | ||
| allowlist_include_directories: (List[Label]) Include paths implied by using this tool. | ||
| Compilers may include a set of built-in headers that are implicitly available | ||
| unless flags like `-nostdinc` are provided. Bazel checks that all included | ||
| headers are properly provided by a dependency or allowlisted through this | ||
| mechanism. | ||
|
|
||
| As a rule of thumb, only use this if Bazel is complaining about absolute paths in your | ||
| toolchain and you've ensured that the toolchain is compiling with the | ||
| `-no-canonical-prefixes` and/or `-fno-canonical-system-headers` arguments. | ||
|
|
||
| These files are not automatically passed to each action. If they need to be, | ||
| add them to 'data' as well. | ||
|
|
||
| This can help work around errors like: | ||
| `the source file 'main.c' includes the following non-builtin files with absolute paths | ||
| (if these are builtin files, make sure these paths are in your toolchain)`. | ||
| env: (Dict[str, str]) Environment variables to apply when running this tool. | ||
| Format expansion is performed on values using `format`. | ||
| format: (Dict[str, Label]) A mapping of format strings to the label of a corresponding | ||
| target. This target can be a `directory`, `subdirectory`, or a single file that the | ||
| value should be pulled from. All instances of `{variable_name}` in the `env` dictionary | ||
| values will be replaced with the expanded value in this dictionary. | ||
| capabilities: (List[Label]) Declares that a tool is capable of doing something. | ||
| For example, `@rules_cc//cc/toolchains/capabilities:supports_pic`. | ||
| **kwargs: [common attributes](https://bazel.build/reference/be/common-definitions#common-attributes) | ||
| that should be applied to this rule. | ||
| """ | ||
| format_keys = format.keys() | ||
| format_values = deduplicate_label_list( | ||
| name = name, | ||
| labels = [format[key] for key in format_keys], | ||
| ) | ||
| return _cc_tool( | ||
| name = name, | ||
| src = src, | ||
| data = data, | ||
| allowlist_include_directories = allowlist_include_directories, | ||
| env = env, | ||
| format_keys = format_keys, | ||
| format_values = format_values.labels, | ||
| format_value_indexes = format_values.indexes, | ||
| capabilities = capabilities, | ||
| **kwargs | ||
| ) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.