This project provides an example of what it might look like to configure a bootstrapping toolchain and construct a different toolchain using an artifact built with the former.
In order to differentiate between a regular toolchain and a bootstrap toolchain, we introduce a new constraint setting config//bootstrap:bootstrap
and a corresponding constraint value config//bootstrap:use_bootstrap
.
constraint_setting(
name = "bootstrap",
)
constraint_value(
name = "use_bootstrap",
constraint_setting = ":bootstrap",
)
We then define a new platform config//platform:bootstrap_platforms
, which inherits everything from the default platform config//platform:default_platforms
and adds the extra bootstrap
constraint defined above.
platform(
name = "bootstrap_platforms",
deps = [":default_platforms"],
constraint_values = ["config//bootstrap:use_bootstrap"],
)
We are using Rust for this example, but the concept is not specific to Rust. Our goal is to build a Rust compiler with the bootstrap toolchain, construct a new toolchain with the compiler, then build a Rust binary with the newly built Rust compiler. For simplicity, we are not building an actual Rust compiler, but using a small wrapper Rust binary that execs into the compiler picked from the system.
First, we setup a bootstrap toolchain using the system_rust_toolchain
provided in the prelude.
system_rust_toolchain(
name = "rust_bootstrap_toolchain",
)
Then, we configure a build for our "rustc".
rust_binary(
name = "rustc_wrapper",
srcs = ["rustc_wrapper.rs"],
)
To construct a new toolchain that uses the new "rustc", we use configured_alias
to tack on the bootstrap_platforms
to the binary.
rust_toolchain(
name = "rust_toolchain_with_compiled_rustc",
compiler = ":rustc_with_bootstrap_toolchain",
)
configured_alias(
name = "rustc_with_bootstrap_toolchain",
actual = ":rustc_wrapper",
platform = "config//platform:bootstrap_platforms"
)
Now that we have both toolchains constructed, we can create our final Rust toolchain that switches between the two based on the use_bootstrap
constraint.
toolchain_alias(
name = "rust",
actual = select({
"config//bootstrap:use_bootstrap": ":rust_bootstrap_toolchain",
"DEFAULT": ":rust_toolchain_with_compiled_rustc",
}),
visibility = ["PUBLIC"],
)