|
|
@@ -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,63 @@ 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.
|
|
|
- """,
|
|
|
-)
|
|
|
-
|
|
|
-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"),
|
|
|
- },
|
|
|
+ doc = "A filegroup whose sources are built with or without runtimes building enabled.",
|
|
|
)
|
|
|
|
|
|
-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.
|
|
|
"""
|
|
|
+ impl_tags = tags if "manual" in tags else tags + ["manual"]
|
|
|
|
|
|
- # 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,73 +277,42 @@ def carbon_cc_toolchain_suite(
|
|
|
"@platforms//os:{}".format(os): os
|
|
|
for os in platforms.keys()
|
|
|
}),
|
|
|
- bins = ":{}_base_files".format(name),
|
|
|
- tags = tags,
|
|
|
+ bins = base_files_target,
|
|
|
+ tags = impl_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)
|
|
|
for os, cpus in platforms.items()
|
|
|
for cpu in cpus
|
|
|
}),
|
|
|
- tags = tags,
|
|
|
+ tags = impl_tags,
|
|
|
)
|
|
|
|
|
|
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,51 +321,51 @@ def carbon_cc_toolchain_suite(
|
|
|
"@platforms//os:{}".format(os): os
|
|
|
for os in platforms.keys()
|
|
|
}),
|
|
|
- runtimes = ":{}_runtimes".format(name),
|
|
|
- bins = ":{}_base_files".format(name),
|
|
|
- tags = tags,
|
|
|
+ runtimes = runtimes_target,
|
|
|
+ bins = base_files_target,
|
|
|
+ tags = impl_tags,
|
|
|
)
|
|
|
|
|
|
native.filegroup(
|
|
|
name = "{}_linker_files".format(name),
|
|
|
srcs = [
|
|
|
- ":{}_base_files".format(name),
|
|
|
- ":{}_runtimes".format(name),
|
|
|
+ base_files_target,
|
|
|
+ runtimes_target,
|
|
|
],
|
|
|
- tags = tags,
|
|
|
+ tags = impl_tags,
|
|
|
)
|
|
|
|
|
|
native.filegroup(
|
|
|
name = "{}_all_files".format(name),
|
|
|
srcs = [
|
|
|
- ":{}_compile_files".format(name),
|
|
|
+ compile_files_target,
|
|
|
":{}_linker_files".format(name),
|
|
|
],
|
|
|
- tags = tags,
|
|
|
+ tags = impl_tags,
|
|
|
)
|
|
|
|
|
|
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)
|
|
|
for os, cpus in platforms.items()
|
|
|
for cpu in cpus
|
|
|
}),
|
|
|
- tags = tags,
|
|
|
+ tags = impl_tags,
|
|
|
)
|
|
|
|
|
|
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",
|