diff --git a/command_line_option/BUILD.bazel b/command_line_option/BUILD.bazel index a4d5f0f80d..15c22f360b 100644 --- a/command_line_option/BUILD.bazel +++ b/command_line_option/BUILD.bazel @@ -18,6 +18,11 @@ alias( actual = "//python:none", ) +alias( + name = "extra_toolchains", + actual = "//python:none", +) + filegroup( name = "distribution", srcs = glob(["**"]), diff --git a/docs/api/rules_python/command_line_option/index.md b/docs/api/rules_python/command_line_option/index.md index a7dfa340eb..02d29206f5 100644 --- a/docs/api/rules_python/command_line_option/index.md +++ b/docs/api/rules_python/command_line_option/index.md @@ -51,3 +51,26 @@ See the [Bazel documentation for --enable_runfiles](https://bazel.build/referenc The special value `INHERIT` can be specified to use the existing flag value. ::: + +## extra_toolchains + +:::{bzl:target} extra_toolchains + +Special target for the Bazel-builtin `//command_line_option:extra_toolchains` +flag. + +See the [Bazel documentation for --extra_toolchains](https://bazel.build/reference/command-line-reference#flag--extra_toolchains). + +The special value `INHERIT` can be specified to use the existing flag value. + +:::{note} +Unlike the normal Bazel built-in flag, which accepts a list of labels, this +pseudo-flag must be specified as a single, comma-separated string when set +using the `config_settings` attribute. For example: + +```python +"//command_line_option:extra_toolchains": "//my/tc1,//my/tc2" +``` +::: +::: + diff --git a/python/features.bzl b/python/features.bzl index 26acc8c5fe..a2cb95f1ee 100644 --- a/python/features.bzl +++ b/python/features.bzl @@ -86,6 +86,7 @@ def _features_typedef(): _TARGETS = { "//command_line_option:build_runfile_links": True, "//command_line_option:enable_runfiles": True, + "//command_line_option:extra_toolchains": True, "//python/cc:current_py_cc_headers_abi3": True, } diff --git a/python/private/attributes.bzl b/python/private/attributes.bzl index beaa7a6a73..ad741d078d 100644 --- a/python/private/attributes.bzl +++ b/python/private/attributes.bzl @@ -446,10 +446,15 @@ def apply_config_settings_attr(settings, attr): if key.package == "command_line_option": if value == "INHERIT": continue - else: - str_key = "//command_line_option:" + key.name + str_key = "//command_line_option:" + key.name + if key.name == "extra_toolchains": + if value == "": + value = [] + else: + value = [v.strip() for v in value.split(",") if v.strip()] else: str_key = str(key) + settings[str_key] = value return settings diff --git a/python/private/common_labels.bzl b/python/private/common_labels.bzl index ff4e7e1dad..a83ba2b462 100644 --- a/python/private/common_labels.bzl +++ b/python/private/common_labels.bzl @@ -14,6 +14,7 @@ labels = struct( # NOTE: Special target; see definition for details. ENABLE_RUNFILES = str(Label("//command_line_option:enable_runfiles")), EXEC_TOOLS_TOOLCHAIN = str(Label("//python/config_settings:exec_tools_toolchain")), + EXTRA_TOOLCHAINS = str(Label("//command_line_option:extra_toolchains")), NONE = str(Label("//python:none")), PIP_ENV_MARKER_CONFIG = str(Label("//python/config_settings:pip_env_marker_config")), PIP_WHL_OSX_VERSION = str(Label("//python/config_settings:pip_whl_osx_version")), diff --git a/python/private/transition_labels.bzl b/python/private/transition_labels.bzl index 5f0aa69056..7a6531ed0f 100644 --- a/python/private/transition_labels.bzl +++ b/python/private/transition_labels.bzl @@ -12,6 +12,7 @@ _BASE_TRANSITION_LABELS = [ labels.BOOTSTRAP_IMPL, labels.DEBUGGER, labels.EXEC_TOOLS_TOOLCHAIN, + "//command_line_option:extra_toolchains", labels.PIP_ENV_MARKER_CONFIG, labels.PIP_WHL_OSX_VERSION, labels.PRECOMPILE, diff --git a/tests/base_rules/py_executable_base_tests.bzl b/tests/base_rules/py_executable_base_tests.bzl index dff0399bc2..7531de4c30 100644 --- a/tests/base_rules/py_executable_base_tests.bzl +++ b/tests/base_rules/py_executable_base_tests.bzl @@ -109,6 +109,29 @@ def _test_basic_zip_impl(env, target): _tests.append(_test_basic_zip) +def _test_config_settings_extra_toolchains(name, config): + rt_util.helper_target( + config.rule, + name = name + "_subject", + srcs = ["main.py"], + main = "main.py", + config_settings = { + "//command_line_option:extra_toolchains": "{tc},{tc}".format(tc = CC_TOOLCHAIN), + }, + ) + analysis_test( + name = name, + impl = _test_config_settings_extra_toolchains_impl, + target = name + "_subject", + ) + +def _test_config_settings_extra_toolchains_impl(env, target): + # If we got here, it means analysis succeeded, which implies the transition + # successfully parsed the CSV string into a list. + env.expect.that_target(target).has_provider(PyInfo) + +_tests.append(_test_config_settings_extra_toolchains) + def _test_cross_compile_to_unix(name, config): rt_util.helper_target( config.rule, diff --git a/tests/integration/bzlmod_lockfile/MODULE.bazel.lock b/tests/integration/bzlmod_lockfile/MODULE.bazel.lock index 0dcc4b2a48..d21fec2d7d 100644 --- a/tests/integration/bzlmod_lockfile/MODULE.bazel.lock +++ b/tests/integration/bzlmod_lockfile/MODULE.bazel.lock @@ -250,7 +250,7 @@ }, "@@rules_python+//python/uv:uv.bzl%uv": { "general": { - "bzlTransitiveDigest": "yrEbeCJlv5gbdoRjwwR/EDEkc3pfuQy/FTYKMNoK5Wc=", + "bzlTransitiveDigest": "Z5ZPR9z4PkJRXSyJ4KQEqM4kwiqWBCn8Ajzxy9YlS/g=", "usagesDigest": "6yXGw7XDyXjOfqBL0SBu1YBEMMYPQzCE3jTzUCkxPgg=", "recordedInputs": [ "REPO_MAPPING:rules_python+,bazel_tools bazel_tools",