From d6a741f208ec8ac36748a264048c641050103d6b Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 20 Apr 2026 17:59:10 -0700 Subject: [PATCH] Add bootstrapping flags to the build system (#7084) This takes the bootstrap support that was added and makes it available under convenient user-facing flags for while we're doing development. For example, to build a bootstrap compiler and use it to build and run the tests under `//common/...` you can now use: ``` bazel test --//:bootstrap_stage=1 --//:bootstrap_exec_config=true //common/... ``` This will use the stage1 bootstrap compiler, and it will build that compiler in the exec config (so it is optimized and the above even works when cross-building with Bazel). Assisted-by: Antigravity with Gemini --- BUILD | 27 +++++++++- .../carbon_cc_toolchain_config.bzl | 49 +++++++++++++++++-- toolchain/install/bazel/install.BUILD | 10 ++++ 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/BUILD b/BUILD index 529f97e42cce..46cdca2e5773 100644 --- a/BUILD +++ b/BUILD @@ -2,7 +2,7 @@ # Exceptions. See /LICENSE for license information. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -load("@bazel_skylib//rules:common_settings.bzl", "bool_setting", "int_setting") +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "bool_setting", "int_flag") filegroup( name = "clang_tidy_config", @@ -22,8 +22,31 @@ bool_setting( visibility = ["//visibility:public"], ) -int_setting( +int_flag( name = "bootstrap_stage", build_setting_default = 0, visibility = ["//visibility:public"], ) + +# A setting that causes bootstrapping to occur using the `exec` config rather +# than the target config. +# +# The exec config is the more technically correct way of doing bootstrapping +# than the target config. For example it allows bootstrapping with a target that +# isn't compatible with the current execution host. However, in development +# builds, it is likely to force building the entire toolchain twice -- once in +# the target config for running test, and a second time in the exec config for +# the bootstrap. As a consequence, this is disabled by default. +# +# TODO: Add documentation for using the bootstrap flags once stabilized. +bool_flag( + name = "bootstrap_exec_config", + build_setting_default = False, + visibility = ["//visibility:public"], +) + +config_setting( + name = "bootstrap_with_exec_config", + flag_values = {"//:bootstrap_exec_config": "True"}, + visibility = ["//visibility:public"], +) diff --git a/bazel/cc_toolchains/carbon_cc_toolchain_config.bzl b/bazel/cc_toolchains/carbon_cc_toolchain_config.bzl index d3632099af3b..3e40aa6be3b6 100644 --- a/bazel/cc_toolchains/carbon_cc_toolchain_config.bzl +++ b/bazel/cc_toolchains/carbon_cc_toolchain_config.bzl @@ -259,6 +259,47 @@ filegroup_with_stage = rule( """, ) +def _exec_filegroup_impl(ctx): + return [DefaultInfo(files = depset(ctx.files.srcs))] + +_exec_filegroup = rule( + implementation = _exec_filegroup_impl, + attrs = { + "srcs": attr.label_list(cfg = "exec"), + }, +) + +def filegroup_with_stage_and_exec(name, srcs, stage, tags = []): + """Wraps `filegroup_with_stage` with a conditional `exec` config transition. + + When `//:bootstrap_exec_config` is disabled, this works exactly like + `filegroup_with_stage`. But when it is _enabled_, it also adds an `exec` + config transition. This allows bootstrapping for a target that is not exec + compatible with the host, and in general makes bootstrapping more robust at + the expense of a likely duplicate build of the entire toolchain. + """ + filegroup_with_stage( + name = name + "_stage_only", + srcs = srcs, + stage = stage, + tags = tags, + ) + + _exec_filegroup( + name = name + "_with_exec", + srcs = [":" + name + "_stage_only"], + tags = tags, + ) + + native.alias( + name = name, + actual = select({ + "//:bootstrap_with_exec_config": ":" + name + "_with_exec", + "//conditions:default": ":" + name + "_stage_only", + }), + tags = tags, + ) + def _gen_cc_toolchain_paths_impl(ctx): cc_toolchain = find_cpp_toolchain(ctx) @@ -332,21 +373,21 @@ def carbon_cc_toolchain_suite( # and not in the runtimes build. These allow us to form the inputs to both # the runtimes toolchain and the main toolchain of this stage that are built # entirely by the base stage toolchain. - filegroup_with_stage( + filegroup_with_stage_and_exec( name = "{}_clang_hdrs".format(name), srcs = clang_hdrs, stage = base_stage, tags = tags, ) - filegroup_with_stage( + filegroup_with_stage_and_exec( name = "{}_base_files".format(name), srcs = base_files, stage = base_stage, tags = tags, ) - filegroup_with_stage( + filegroup_with_stage_and_exec( name = "{}_runtimes_compile_files".format(name), srcs = [ ":{}_base_files".format(name), @@ -356,7 +397,7 @@ def carbon_cc_toolchain_suite( tags = tags, ) - filegroup_with_stage( + filegroup_with_stage_and_exec( name = "{}_compile_files".format(name), srcs = [":{}_base_files".format(name)] + all_hdrs, stage = base_stage, diff --git a/toolchain/install/bazel/install.BUILD b/toolchain/install/bazel/install.BUILD index 3cb6b0137ef8..a17d8c7b0ebc 100644 --- a/toolchain/install/bazel/install.BUILD +++ b/toolchain/install/bazel/install.BUILD @@ -66,6 +66,16 @@ config_setting( flag_values = {":bootstrap_stage": "1"}, ) +bool_setting( + name = "bootstrap_exec_config", + build_setting_default = False, +) + +config_setting( + name = "bootstrap_with_exec_config", + flag_values = {":bootstrap_exec_config": "True"}, +) + filegroup( name = "llvm_bins", srcs = glob(["llvm/bin/*"]),