diff --git a/bazel/cc_toolchains/BUILD b/bazel/cc_toolchains/BUILD index 543c1d082b05..a166950aaebc 100644 --- a/bazel/cc_toolchains/BUILD +++ b/bazel/cc_toolchains/BUILD @@ -4,7 +4,7 @@ load("@bazel_skylib//lib:selects.bzl", "selects") load("@rules_python//python:defs.bzl", "py_library", "py_test") -load(":carbon_cc_toolchain_config.bzl", "gen_cc_toolchain_paths_with_stage") +load(":carbon_bootstrapping.bzl", "gen_cc_toolchain_paths_with_stage") package(default_visibility = ["//visibility:public"]) diff --git a/bazel/cc_toolchains/carbon_bootstrapping.bzl b/bazel/cc_toolchains/carbon_bootstrapping.bzl new file mode 100644 index 000000000000..8ad9a67b9ed7 --- /dev/null +++ b/bazel/cc_toolchains/carbon_bootstrapping.bzl @@ -0,0 +1,222 @@ +# 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 + +"""Starlark rules for bootstrapping the Carbon toolchain.""" + +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") +load("//toolchain/runtimes:carbon_runtimes.bzl", "carbon_runtimes_build") +load( + ":carbon_cc_toolchain_config.bzl", + "carbon_cc_toolchain", +) + +def _bootstrap_transition_impl(_, attr): + return { + "//:bootstrap_stage": attr.stage, + + # Note that we need to either set or clear the runtimes build flag each + # time we transition to a different bootstarp stage or we can + # incorrectly inherit an unexpected state. + "//:runtimes_build": attr.enable_runtimes_build, + } + +_bootstrap_transition = transition( + inputs = [], + outputs = [ + "//:bootstrap_stage", + "//:runtimes_build", + ], + implementation = _bootstrap_transition_impl, +) + +def _filegroup_with_stage_impl(ctx): + return [DefaultInfo(files = depset(ctx.files.srcs))] + +filegroup_with_stage = rule( + implementation = _filegroup_with_stage_impl, + attrs = { + "enable_runtimes_build": attr.bool(default = False), + "srcs": attr.label_list(mandatory = True, cfg = _bootstrap_transition), + "stage": attr.int(mandatory = True), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, + doc = "A filegroup whose sources are built using a specific toolchain stage.", +) + +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. + """ + 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) + + expanded_vars = [ + ctx.expand_make_variables("vars", v, {}) + for v in ctx.attr.vars + ] + + out = ctx.actions.declare_file(ctx.attr.name + ".txt") + ctx.actions.write(out, "\n".join(expanded_vars) + "\n") + + # Include all toolchain files in runfiles. + runfiles = ctx.runfiles(files = [out]).merge( + ctx.runfiles(transitive_files = cc_toolchain.all_files), + ) + + return [DefaultInfo(files = depset([out]), runfiles = runfiles)] + +gen_cc_toolchain_paths_with_stage = rule( + implementation = _gen_cc_toolchain_paths_impl, + attrs = { + "enable_runtimes_build": attr.bool(default = False), + "stage": attr.int(mandatory = True), + "vars": attr.string_list( + default = ["$(CC)", "$(AR)", "$(NM)", "$(OBJCOPY)", "$(STRIP)"], + ), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + "_cc_toolchain": attr.label( + default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"), + ), + }, + toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], + cfg = _bootstrap_transition, +) + +def carbon_bootstrapped_cc_toolchain( + name, + all_hdrs, + base_files, + clang_hdrs, + platforms, + runtimes_cfg, + build_stage = 1, + base_stage = 0, + tags = []): + """Create a bootstrapped Carbon `cc_toolchain` for the current target. + + This builds on `carbon_cc_toolchain`, but enables bootstrapping the produced + toolchain from a base stage's toolchain. + + Args: + name: + The name of the toolchain suite to produce, used as the base of the + names of each component of the toolchain suite. + all_hdrs: A list of header files to include in the toolchain. + base_files: A list of files to include in the toolchain. + build_stage: The stage to use for the build files. + base_stage: The stage to use for the base files. + clang_hdrs: A list of header files to include in the toolchain. + platforms: An array of (os, cpu) pairs to support in the toolchain. + runtimes_cfg: The runtimes configuration to use in the toolchain. + tags: Tags to apply to the toolchain. + """ + filegroup_with_stage_and_exec( + name = "{}_clang_hdrs".format(name), + srcs = clang_hdrs, + stage = base_stage, + tags = tags, + ) + + filegroup_with_stage_and_exec( + name = "{}_base_files".format(name), + srcs = base_files, + stage = base_stage, + tags = tags, + ) + + filegroup_with_stage_and_exec( + name = "{}_runtimes_compile_files".format(name), + srcs = [ + ":{}_base_files".format(name), + ":{}_clang_hdrs".format(name), + ], + stage = base_stage, + tags = tags, + ) + + filegroup_with_stage_and_exec( + name = "{}_compile_files".format(name), + srcs = [":{}_base_files".format(name)] + all_hdrs, + stage = base_stage, + tags = tags, + ) + + # The runtimes build for this stage of the bootstrap is only compatible with + # both the build stage and the runtimes build. We'll induce those below, and + # constrain them here to avoid any other usage. + carbon_runtimes_build( + name = "{}_runtimes_build".format(name), + config = runtimes_cfg, + clang_hdrs = ["{}_clang_hdrs".format(name)], + tags = tags, + target_compatible_with = select({ + ":is_runtimes_build": [], + "//conditions:default": ["@platforms//:incompatible"], + }) + select({ + ":is_bootstrap_stage_{}".format(build_stage): [], + "//conditions:default": ["@platforms//:incompatible"], + }), + ) + + # Wrap the runtimes build in a filegroup that both sets the stage to the + # build stage as well as enabling runtimes building. Note that this is _not_ + # the base stage -- runtimes should be built by the same stage, simply using + # the runtimes build setting. + filegroup_with_stage( + name = "{}_runtimes".format(name), + srcs = [":{}_runtimes_build".format(name)], + stage = build_stage, + enable_runtimes_build = True, + tags = tags, + ) + + carbon_cc_toolchain( + name = name, + platforms = platforms, + base_files_target = ":{}_base_files".format(name), + runtimes_compile_files_target = ":{}_runtimes_compile_files".format(name), + compile_files_target = ":{}_compile_files".format(name), + runtimes_target = ":{}_runtimes".format(name), + extra_toolchain_settings = [":is_bootstrap_stage_{}".format(build_stage)], + tags = tags, + ) diff --git a/bazel/cc_toolchains/carbon_cc_toolchain_config.bzl b/bazel/cc_toolchains/carbon_cc_toolchain_config.bzl index b4ac143b986f..f01b9db2583a 100644 --- a/bazel/cc_toolchains/carbon_cc_toolchain_config.bzl +++ b/bazel/cc_toolchains/carbon_cc_toolchain_config.bzl @@ -4,7 +4,6 @@ """Starlark cc_toolchain configuration rules for using the Carbon toolchain""" -load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES", "ACTION_NAME_GROUPS") load( "@rules_cc//cc:cc_toolchain_config_lib.bzl", @@ -19,7 +18,6 @@ load( "cc_toolchain", ) load("@rules_cc//cc/common:cc_common.bzl", "cc_common") -load("//toolchain/runtimes:carbon_runtimes.bzl", "carbon_runtimes_build") load( "carbon_clang_variables.bzl", "clang_include_dirs", @@ -214,202 +212,61 @@ carbon_cc_toolchain_config = rule( provides = [CcToolchainConfigInfo], ) -def _transition_with_stage_impl(_, attr): +def _runtimes_transition_impl(_, attr): return { - "//:bootstrap_stage": attr.stage, - "//:runtimes_build": attr.enable_runtimes_build, + "//:runtimes_build": True, } -_transition_with_stage = transition( +_runtimes_transition = transition( inputs = [], outputs = [ - "//:bootstrap_stage", "//:runtimes_build", ], - implementation = _transition_with_stage_impl, + implementation = _runtimes_transition_impl, ) -def _filegroup_with_stage_impl(ctx): +def _filegroup_with_runtimes_build_impl(ctx): return [DefaultInfo(files = depset(ctx.files.srcs))] -filegroup_with_stage = rule( - implementation = _filegroup_with_stage_impl, +filegroup_with_runtimes_build = rule( + implementation = _filegroup_with_runtimes_build_impl, attrs = { - # Whether to enable runtimes building for the sources of this filegroup. - "enable_runtimes_build": attr.bool(default = False), - - # Mark that our dependencies are built through a transition. - "srcs": attr.label_list(mandatory = True, cfg = _transition_with_stage), - - # The bootstrap stage that the sources of this filegroup should be built - # with. - "stage": attr.int(mandatory = True), - - # Enable transitions in this rule. + "srcs": attr.label_list(mandatory = True, cfg = _runtimes_transition), "_allowlist_function_transition": attr.label( default = "@bazel_tools//tools/allowlists/function_transition_allowlist", ), }, - doc = """ - A filegroup whose sources are built using a specific toolchain stage, and - which provides an interface to build those sources with or without enabling - runtimes building. - """, + doc = "A filegroup whose sources are built with or without runtimes building enabled.", ) -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) - - expanded_vars = [ - ctx.expand_make_variables("vars", v, {}) - for v in ctx.attr.vars - ] - - out = ctx.actions.declare_file(ctx.attr.name + ".txt") - ctx.actions.write(out, "\n".join(expanded_vars) + "\n") - - # Include all toolchain files in runfiles. - runfiles = ctx.runfiles(files = [out]).merge( - ctx.runfiles(transitive_files = cc_toolchain.all_files), - ) - - return [DefaultInfo(files = depset([out]), runfiles = runfiles)] - -gen_cc_toolchain_paths_with_stage = rule( - implementation = _gen_cc_toolchain_paths_impl, - attrs = { - "enable_runtimes_build": attr.bool(default = False), - "stage": attr.int(mandatory = True), - "vars": attr.string_list( - default = ["$(CC)", "$(AR)", "$(NM)", "$(OBJCOPY)", "$(STRIP)"], - ), - "_allowlist_function_transition": attr.label( - default = "@bazel_tools//tools/allowlists/function_transition_allowlist", - ), - "_cc_toolchain": attr.label( - default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"), - ), - }, - toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], - cfg = _transition_with_stage, -) - -def carbon_cc_toolchain_suite( +def carbon_cc_toolchain( name, - all_hdrs, - base_files, - clang_hdrs, platforms, - runtimes_cfg, - build_stage = 1, - base_stage = 0, + base_files_target, + runtimes_compile_files_target, + compile_files_target, + runtimes_target, + extra_toolchain_settings = [], tags = []): - """Create a Carbon `cc_toolchain` for the current target platform. + """Create a Carbon `cc_toolchain` for the current target. - This provides the final toolchain for Carbon, but also all of the - infrastructure for supporting on-demand built runtimes in this toolchain. - - There is also support for bootstrapping, where one `build_stage` toolchain - builds on top of another `base_stage`. + This macro constructs the configuration and toolchain rules for a baseline + Carbon toolchain, including building its own runtimes on demand. Args: - name: - The name of the toolchain suite to produce, used as the base of the - names of each component of the toolchain suite. - all_hdrs: A list of header files to include in the toolchain. - base_files: A list of files to include in the toolchain. - build_stage: The stage to use for the build files. - base_stage: The stage to use for the base files. - clang_hdrs: A list of header files to include in the toolchain. - platforms: An array of (os, cpu) pairs to support in the toolchain. - runtimes_cfg: The runtimes configuration to use in the toolchain. + name: The base name for the toolchain targets. + platforms: Supported platforms. + base_files_target: Target for base files. + runtimes_compile_files_target: Target for runtimes compile files. + compile_files_target: Target for compile files. + runtimes_target: Target for runtimes. + extra_toolchain_settings: Extra toolchain settings. tags: Tags to apply to the toolchain. """ - - # First, declare file groups that are explicitly built using the base stage, - # 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_and_exec( - name = "{}_clang_hdrs".format(name), - srcs = clang_hdrs, - stage = base_stage, - tags = tags, - ) - - filegroup_with_stage_and_exec( - name = "{}_base_files".format(name), - srcs = base_files, - stage = base_stage, - tags = tags, - ) - - filegroup_with_stage_and_exec( - name = "{}_runtimes_compile_files".format(name), - srcs = [ - ":{}_base_files".format(name), - ":{}_clang_hdrs".format(name), - ], - stage = base_stage, - tags = tags, - ) - - filegroup_with_stage_and_exec( - name = "{}_compile_files".format(name), - srcs = [":{}_base_files".format(name)] + all_hdrs, - stage = base_stage, - tags = tags, - ) - - # Now build a configuration and toolchain that is configured to work - # _without_ runtimes, and be used to _build_ the runtimes on-demand. carbon_cc_toolchain_config( name = "{}_runtimes_toolchain_config".format(name), identifier_prefix = "{}_runtimes".format(name), target_cpu = select({ - # Note that we need to select on both OS and CPU so that we end up - # spelling the CPU in the correct OS-specific ways. ":is_{}_{}".format(os, cpu): cpu for os, cpus in platforms.items() for cpu in cpus @@ -418,20 +275,20 @@ def carbon_cc_toolchain_suite( "@platforms//os:{}".format(os): os for os in platforms.keys() }), - bins = ":{}_base_files".format(name), + bins = base_files_target, tags = tags, ) cc_toolchain( name = "{}_runtimes_cc_toolchain".format(name), - all_files = ":{}_runtimes_compile_files".format(name), - ar_files = ":{}_base_files".format(name), - as_files = ":{}_runtimes_compile_files".format(name), - compiler_files = ":{}_runtimes_compile_files".format(name), - dwp_files = ":{}_base_files".format(name), - linker_files = ":{}_base_files".format(name), - objcopy_files = ":{}_base_files".format(name), - strip_files = ":{}_base_files".format(name), + all_files = runtimes_compile_files_target, + ar_files = base_files_target, + as_files = runtimes_compile_files_target, + compiler_files = runtimes_compile_files_target, + dwp_files = base_files_target, + linker_files = base_files_target, + objcopy_files = base_files_target, + strip_files = base_files_target, toolchain_config = ":{}_runtimes_toolchain_config".format(name), toolchain_identifier = select({ ":is_{}_{}".format(os, cpu): "{}_{}_{}_runtimes_toolchain".format(name, os, cpu) @@ -443,48 +300,17 @@ def carbon_cc_toolchain_suite( native.toolchain( name = "{}_runtimes_toolchain".format(name), - target_settings = [ - ":is_bootstrap_stage_{}".format(build_stage), - ":is_runtimes_build", - ], + target_settings = [":is_runtimes_build"] + extra_toolchain_settings, use_target_platform_constraints = True, toolchain = ":{}_runtimes_cc_toolchain".format(name), toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", tags = tags, ) - # Now that we have a toolchain for building runtimes, actually do the build - # here using the runtimes config provided to us. This is important to do - # here because we need each runtimes build for a particular bootstrapping - # stage of the toolchain to be distinct. - carbon_runtimes_build( - name = "{}_runtimes_build".format(name), - config = runtimes_cfg, - clang_hdrs = [":{}_clang_hdrs".format(name)], - tags = tags, - ) - - # Wrap the built runtimes for this stage in a filegroup that ensures they - # are built at this stage, but with the runtimes build enabled. This will - # select the runtimes build toolchain above that doesn't yet provide any - # runtimes, avoiding a cycle when the main toolchain below depends on these - # runtimes. - filegroup_with_stage( - name = "{}_runtimes".format(name), - enable_runtimes_build = True, - srcs = ["{}_runtimes_build".format(name)], - stage = build_stage, - tags = tags, - ) - - # Now we can build the main toolchain configuration, filegroups including - # the on-demand built runtimes, and the final tolochain itself. carbon_cc_toolchain_config( name = "{}_toolchain_config".format(name), identifier_prefix = name, target_cpu = select({ - # Note that we need to select on both OS and CPU so that we end up - # spelling the CPU in the correct OS-specific ways. ":is_{}_{}".format(os, cpu): cpu for os, cpus in platforms.items() for cpu in cpus @@ -493,16 +319,16 @@ def carbon_cc_toolchain_suite( "@platforms//os:{}".format(os): os for os in platforms.keys() }), - runtimes = ":{}_runtimes".format(name), - bins = ":{}_base_files".format(name), + runtimes = runtimes_target, + bins = base_files_target, tags = tags, ) native.filegroup( name = "{}_linker_files".format(name), srcs = [ - ":{}_base_files".format(name), - ":{}_runtimes".format(name), + base_files_target, + runtimes_target, ], tags = tags, ) @@ -510,7 +336,7 @@ def carbon_cc_toolchain_suite( native.filegroup( name = "{}_all_files".format(name), srcs = [ - ":{}_compile_files".format(name), + compile_files_target, ":{}_linker_files".format(name), ], tags = tags, @@ -519,13 +345,13 @@ def carbon_cc_toolchain_suite( cc_toolchain( name = "{}_cc_toolchain".format(name), all_files = ":{}_all_files".format(name), - ar_files = ":" + name + "_base_files", - as_files = ":" + name + "_compile_files", - compiler_files = ":" + name + "_compile_files", - dwp_files = ":" + name + "_linker_files", - linker_files = ":" + name + "_linker_files", - objcopy_files = ":" + name + "_base_files", - strip_files = ":" + name + "_base_files", + ar_files = base_files_target, + as_files = compile_files_target, + compiler_files = compile_files_target, + dwp_files = ":{}_linker_files".format(name), + linker_files = ":{}_linker_files".format(name), + objcopy_files = base_files_target, + strip_files = base_files_target, toolchain_config = ":" + name + "_toolchain_config", toolchain_identifier = select({ ":is_{}_{}".format(os, cpu): "{}_{}_{}_toolchain".format(name, os, cpu) @@ -537,7 +363,7 @@ def carbon_cc_toolchain_suite( native.toolchain( name = name + "_toolchain", - target_settings = [":is_bootstrap_stage_{}".format(build_stage), ":not_runtimes_build"], + target_settings = [":not_runtimes_build"] + extra_toolchain_settings, use_target_platform_constraints = True, toolchain = ":" + name + "_cc_toolchain", toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", diff --git a/toolchain/install/BUILD b/toolchain/install/BUILD index 5aef6005f192..73071535a5f3 100644 --- a/toolchain/install/BUILD +++ b/toolchain/install/BUILD @@ -36,8 +36,8 @@ load("@llvm-project//libunwind:libunwind_library.bzl", "libunwind_copts") load("@rules_python//python:defs.bzl", "py_test") load("//bazel/cc_rules:defs.bzl", "cc_binary", "cc_library", "cc_test") load( - "//bazel/cc_toolchains:carbon_cc_toolchain_config.bzl", - "carbon_cc_toolchain_suite", + "//bazel/cc_toolchains:carbon_bootstrapping.bzl", + "carbon_bootstrapped_cc_toolchain", "filegroup_with_stage", "gen_cc_toolchain_paths_with_stage", ) @@ -634,7 +634,7 @@ platforms = { for cpu in cpus ] -carbon_cc_toolchain_suite( +carbon_bootstrapped_cc_toolchain( name = "carbon_stage1", all_hdrs = [ ":clang_hdrs", @@ -653,7 +653,7 @@ carbon_cc_toolchain_suite( runtimes_cfg = ":runtimes_cfg", ) -carbon_cc_toolchain_suite( +carbon_bootstrapped_cc_toolchain( name = "carbon_stage2", all_hdrs = [ ":clang_hdrs", diff --git a/toolchain/install/bazel/install.BUILD b/toolchain/install/bazel/install.BUILD index a17d8c7b0ebc..8d4b39425892 100644 --- a/toolchain/install/bazel/install.BUILD +++ b/toolchain/install/bazel/install.BUILD @@ -2,9 +2,9 @@ # 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_setting") load("@rules_cc//cc:defs.bzl", "cc_library") -load("//bazel:carbon_cc_toolchain_config.bzl", "carbon_cc_toolchain_suite") +load("//bazel:carbon_cc_toolchain_config.bzl", "carbon_cc_toolchain", "filegroup_with_runtimes_build") load("//bazel:carbon_runtimes.bzl", "carbon_runtimes_build", "carbon_runtimes_config") load("//bazel:make_include_copts.bzl", "make_include_copts") load( @@ -56,21 +56,6 @@ config_setting( flag_values = {":runtimes_build": "False"}, ) -int_setting( - name = "bootstrap_stage", - build_setting_default = 1, -) - -config_setting( - name = "is_bootstrap_stage_1", - 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"}, @@ -213,50 +198,6 @@ filegroup( output_group = "archive", ) -carbon_runtimes_config( - name = "runtimes_cfg", - builtins_archive = ":builtins_archive", - clang_hdrs_prefix = "llvm/lib/clang/{0}/include/".format(llvm_version_major), - crt_copts = crt_copts, - crtbegin_src = select({ - "@platforms//os:linux": crtbegin_src, - "//conditions:default": None, - }), - crtend_src = select({ - "@platforms//os:linux": crtend_src, - "//conditions:default": None, - }), - darwin_os_suffix = select({ - # TODO: Add support for tvOS, watchOS, and iOS variants with the - # relevant Bazel constraints. - ":is_macos_arm64": "osx", - ":is_macos_x86_64": "osx", - "//conditions:default": None, - }), - libcxx_archive = ":libcxx_archive", - libunwind_archive = ":libunwind_archive", - target_compatible_with = select({ - ":is_runtimes_build": [], - "//conditions:default": ["@platforms//:incompatible"], - }), - target_triple = select({ - # TODO: Add other triples (and if needed, constraints) so that we can - # build the correct Clang resource-dir structure for each. - ":is_freebsd_x86_64": "x86_64-unknown-freebsd", - ":is_linux_aarch64": "aarch64-unknown-linux-gnu", - ":is_linux_x86_64": "x86_64-unknown-linux-gnu", - - # Note that Darwin OSes are handled by the `darwin_os_suffix` attribute. - "//conditions:default": None, - }), -) - -carbon_runtimes_build( - name = "runtimes", - clang_hdrs = [":clang_hdrs"], - config = ":runtimes_cfg", -) - filegroup( name = "carbon_install_digest_file", srcs = ["install_digest.txt"], @@ -296,20 +237,93 @@ platforms = { for cpu in cpus ] -carbon_cc_toolchain_suite( - name = "carbon", - all_hdrs = [ - ":clang_hdrs", - ":libunwind_hdrs", - ":libcxx_hdrs", - ], - base_files = [ +filegroup( + name = "base_files", + srcs = [ + ":carbon_busybox_file", ":carbon_install_digest_file", ":carbon_install_marker_file", - ":carbon_busybox_file", ":llvm_bins", ], +) + +filegroup( + name = "runtimes_compile_files", + srcs = [ + ":base_files", + ":clang_hdrs", + ], +) + +filegroup( + name = "compile_files", + srcs = [ + ":base_files", + ":clang_hdrs", + ":libcxx_hdrs", + ":libunwind_hdrs", + ], +) + +carbon_runtimes_config( + name = "runtimes_cfg", + builtins_archive = ":builtins_archive", + clang_hdrs_prefix = "llvm/lib/clang/{0}/include/".format(llvm_version_major), + crt_copts = crt_copts, + crtbegin_src = select({ + "@platforms//os:linux": crtbegin_src, + "//conditions:default": None, + }), + crtend_src = select({ + "@platforms//os:linux": crtend_src, + "//conditions:default": None, + }), + darwin_os_suffix = select({ + # TODO: Add support for tvOS, watchOS, and iOS variants with the + # relevant Bazel constraints. + ":is_macos_arm64": "osx", + ":is_macos_x86_64": "osx", + "//conditions:default": None, + }), + libcxx_archive = ":libcxx_archive", + libunwind_archive = ":libunwind_archive", + target_compatible_with = select({ + ":is_runtimes_build": [], + "//conditions:default": ["@platforms//:incompatible"], + }), + target_triple = select({ + # TODO: Add other triples (and if needed, constraints) so that we can + # build the correct Clang resource-dir structure for each. + ":is_freebsd_x86_64": "x86_64-unknown-freebsd", + ":is_linux_aarch64": "aarch64-unknown-linux-gnu", + ":is_linux_x86_64": "x86_64-unknown-linux-gnu", + + # Note that Darwin OSes are handled by the `darwin_os_suffix` attribute. + "//conditions:default": None, + }), +) + +carbon_runtimes_build( + name = "carbon_runtimes_build", clang_hdrs = [":clang_hdrs"], + config = ":runtimes_cfg", + tags = ["manual"], + target_compatible_with = select({ + ":is_runtimes_build": [], + "//conditions:default": ["@platforms//:incompatible"], + }), +) + +filegroup_with_runtimes_build( + name = "runtimes", + srcs = [":carbon_runtimes_build"], +) + +carbon_cc_toolchain( + name = "carbon", + base_files_target = ":base_files", + compile_files_target = ":compile_files", platforms = platforms, - runtimes_cfg = ":runtimes_cfg", + runtimes_compile_files_target = ":runtimes_compile_files", + runtimes_target = ":runtimes", )