Skip to content

Commit

Permalink
Bootrapping rust toolchain to rebuild std for custom platforms
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinh Tran committed Nov 9, 2023
1 parent d680d81 commit d2e0420
Show file tree
Hide file tree
Showing 17 changed files with 964 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/examples/cargo_manifest_dir/external_crate/bazel-*
/examples/crate_universe/bazel-*
/examples/crate_universe/*/bazel-*
/examples/toolchain-to-rebuild-std/bazel-*
/test/cc_common_link/bazel-*
/test/cc_common_link/with_global_alloc/bazel-*
/test/no_std/bazel-*
Expand Down
10 changes: 10 additions & 0 deletions examples/toolchain-to-rebuild-std/.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# new feature
build --@rules_rust//rust/settings:experimental_toolchain_generated_sysroot=True

# enable toolchain debugging by default
build --toolchain_resolution_debug='@rules_rust//rust:toolchain_type'

# for toolchain debugging purposes
build:beta --@rules_rust//rust/toolchain/channel:channel=beta
build:stable --@rules_rust//rust/toolchain/channel:channel=stable
build:nightly --@rules_rust//rust/toolchain/channel:channel=nightly
15 changes: 15 additions & 0 deletions examples/toolchain-to-rebuild-std/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
platform(
name = "aarch64-apple-darwin",
constraint_values = [
"@platforms//os:osx",
"@platforms//cpu:aarch64",
],
)

platform(
name = "wasm32-wasi",
constraint_values = [
"@platforms//os:wasi",
"@platforms//cpu:wasm32",
],
)
34 changes: 34 additions & 0 deletions examples/toolchain-to-rebuild-std/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

This directory demonstrates an example of how to rebuild the standard library
for an arbitrary platform and custom configurations.

TODO: Write up on how the toolchain bootrapping process works.

To build an end-user rust_library target for specific target, run

```
bazel build //hello_lib --platforms=//:aarch64-apple-darwin
```

for `aarch64-apple-darwin` or

```
bazel build //hello_lib --platforms=//:wasm32-wasi
```

for `wasm32-wasi`.

The toolchains orderly registered in WORKSPACE and _beta_channel_transition ensure
that the standard library is rebuilt for the given platform.

To only rebuild std, run

```
bazel build @stdlbs//:std --platforms=//:aarch64-apple-darwin
```

or

```
bazel build @stdlbs//:std --platforms=//:wasm32-wasi
```
69 changes: 69 additions & 0 deletions examples/toolchain-to-rebuild-std/WORKSPACE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
workspace(name = "rebuild_std_example")

# Users of `rules_rust` will commonly be unable to load it
# using a `local_repository`. Instead, to setup the rules,
# please see https://bazelbuild.github.io/rules_rust/#setup
local_repository(
name = "rules_rust",
path = "../..",
)

load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains")

rules_rust_dependencies()

register_toolchains(
"//dummy_cc_toolchain:dummy_cc_aarch64_toolchain",
"//dummy_cc_toolchain:dummy_cc_wasm32_toolchain",
)

# # The dates need to be sequential so that the stdlibs are built
# # using the previous beta rustc
[
previous_beta_date,
current_beta_date,
] = [
"2023-08-22",
"2023-09-18",
]

rust_register_toolchains(
edition = "2021",
extra_rustc_flags = {
"aarch64-apple-darwin": ["--cap-lints=allow"],
},
extra_target_triples = [
"wasm32-wasi",
"aarch64-apple-darwin",
],
versions = [
# beta toolchain to rebuild stdlibs
"beta/" + previous_beta_date,
# stable toolchain to build process_wrapper and tinyjson
"1.73.0",
],
)

# http_archive(
# name = "wasi",
# build_file = "@rules_rust//util/import/3rdparty/crates:BUILD.wasi-0.11.0+wasi-snapshot-preview1.bazel",
# strip_prefix = "wasi-0.11.0",
# # sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
# url = "https://github.com/bytecodealliance/wasi/archive/refs/tags/0.11.0.zip",
# )

load(":stdlibs.bzl", "stdlibs")

# # Run
# # bazel build @stage2_stdlibs//:std --@rules_rust//rust/toolchain/channel:channel=beta --platforms=//:aarch64-apple-darwin
# # To rebuild standard library for aarch64-apple-darwin
stdlibs(
name = "stdlibs",
beta_date = current_beta_date,
build_file = "//:stdlibs.BUILD.bazel",
)

register_toolchains(
"//toolchain:toolchain_aarch64-apple-darwin",
"//toolchain:toolchain_wasm32-wasi",
)
41 changes: 41 additions & 0 deletions examples/toolchain-to-rebuild-std/dummy_cc_toolchain/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
load("@rules_cc//cc:defs.bzl", "cc_toolchain")
load(":dummy_cc_toolchain.bzl", "dummy_cc_config", "dummy_cc_toolchain")

dummy_cc_toolchain(name = "dummy_cc_aarch64")

toolchain(
name = "dummy_cc_aarch64_toolchain",
target_compatible_with = ["@platforms//cpu:aarch64"],
toolchain = ":dummy_cc_aarch64_toolchain_cc",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)

toolchain(
name = "dummy_cc_wasm32_toolchain",
target_compatible_with = ["@platforms//cpu:wasm32"],
toolchain = ":dummy_cc_aarch64_toolchain_cc",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)

cc_toolchain(
name = "dummy_cc_aarch64_toolchain_cc",
all_files = ":empty",
compiler_files = ":empty",
dwp_files = ":empty",
linker_files = ":empty",
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 0,
toolchain_config = ":cc_toolchain_config",
toolchain_identifier = ":dummy_cc_aarch64",
)

dummy_cc_config(
name = "cc_toolchain_config",
)

filegroup(
name = "empty",
srcs = [],
visibility = ["//:__subpackages__"],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Cc toolchain definitions for use on wasm platforms"""

def _dummy_cc_toolchain_impl(_ctx):
# The `all_files` attribute is referenced by rustc_compile_action().
return [platform_common.ToolchainInfo(all_files = depset([]))]

dummy_cc_toolchain = rule(
implementation = _dummy_cc_toolchain_impl,
attrs = {},
)

# dummy values from https://bazel.build/tutorials/ccp-toolchain-config#configuring_the_c_toolchain
def _config_impl(ctx):
return cc_common.create_cc_toolchain_config_info(
ctx = ctx,
toolchain_identifier = "dummy-aarch64-cc-toolchain",
host_system_name = "unknown",
target_system_name = "unknown",
target_cpu = "unknown",
target_libc = "unknown",
compiler = "unknown",
abi_version = "unknown",
abi_libc_version = "unknown",
)

dummy_cc_config = rule(
implementation = _config_impl,
attrs = {},
provides = [CcToolchainConfigInfo],
)
17 changes: 17 additions & 0 deletions examples/toolchain-to-rebuild-std/hello_lib/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
load(
"@rules_rust//rust:defs.bzl",
"rust_library",
)

package(default_visibility = ["//visibility:public"])

# bazel build //hello_lib:hello_lib --platforms=//:aarch64-apple-darwin
rust_library(
name = "hello_lib",
srcs = [
"src/greeter.rs",
"src/lib.rs",
],
crate_features = ["default"],
rustc_flags = ["--cap-lints=allow"],
)
75 changes: 75 additions & 0 deletions examples/toolchain-to-rebuild-std/hello_lib/src/greeter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Object that displays a greeting.
pub struct Greeter {
greeting: String,
}

/// Implementation of Greeter.
impl Greeter {
/// Constructs a new `Greeter`.
///
/// # Examples
///
/// ```
/// use hello_lib::greeter::Greeter;
///
/// let greeter = Greeter::new("Hello");
/// ```
pub fn new(greeting: &str) -> Greeter {
Greeter {
greeting: greeting.to_string(),
}
}

/// Returns the greeting as a string.
///
/// # Examples
///
/// ```
/// use hello_lib::greeter::Greeter;
///
/// let greeter = Greeter::new("Hello");
/// let greeting = greeter.greeting("World");
/// ```
pub fn greeting(&self, thing: &str) -> String {
format!("{} {}", &self.greeting, thing)
}

/// Prints the greeting.
///
/// # Examples
///
/// ```
/// use hello_lib::greeter::Greeter;
///
/// let greeter = Greeter::new("Hello");
/// greeter.greet("World");
/// ```
pub fn greet(&self, thing: &str) {
println!("{} {}", &self.greeting, thing);
}
}

#[cfg(test)]
mod test {
use super::Greeter;

#[test]
fn test_greeting() {
let hello = Greeter::new("Hi");
assert_eq!("Hi Rust", hello.greeting("Rust"));
}
}
15 changes: 15 additions & 0 deletions examples/toolchain-to-rebuild-std/hello_lib/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod greeter;
27 changes: 27 additions & 0 deletions examples/toolchain-to-rebuild-std/hello_lib/tests/greeting.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2015 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate hello_lib;

// test gate is not usually required in an integration test, but the BUILD
// script is using this file to test cdylib compilation as well, and when
// compiled in that mode, greeter is an unused import.
#[cfg(test)]
use hello_lib::greeter;

#[test]
fn test_greeting() {
let hello = greeter::Greeter::new("Hello");
assert_eq!("Hello world", hello.greeting("world"));
}
Loading

0 comments on commit d2e0420

Please sign in to comment.