Skip to content

Update how WASI toolchains are used in CI and bootstrap #123978

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 9 additions & 16 deletions src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,16 +394,13 @@ fn copy_self_contained_objects(
target_deps.push((libunwind_path, DependencyType::TargetSelfContained));
}
} else if target.contains("-wasi") {
let srcdir = builder
.wasi_root(target)
.unwrap_or_else(|| {
panic!(
"Target {:?} does not have a \"wasi-root\" key in Config.toml",
target.triple
)
})
.join("lib")
.join(target.to_string().replace("-preview1", "").replace("p2", "").replace("p1", ""));
let srcdir = builder.wasi_libdir(target).unwrap_or_else(|| {
panic!(
"Target {:?} does not have a \"wasi-root\" key in Config.toml \
or `$WASI_SDK_PATH` set",
target.triple
)
});
for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] {
copy_and_stamp(
builder,
Expand Down Expand Up @@ -514,12 +511,8 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
}

if target.contains("-wasi") {
if let Some(p) = builder.wasi_root(target) {
let root = format!(
"native={}/lib/{}",
p.to_str().unwrap(),
target.to_string().replace("-preview1", "")
);
if let Some(dir) = builder.wasi_libdir(target) {
let root = format!("native={}", dir.to_str().unwrap());
cargo.rustflag("-L").rustflag(&root);
}
}
Expand Down
21 changes: 18 additions & 3 deletions src/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,9 +1351,24 @@ impl Build {
self.musl_root(target).map(|root| root.join("lib"))
}

/// Returns the sysroot for the wasi target, if defined
fn wasi_root(&self, target: TargetSelection) -> Option<&Path> {
self.config.target_config.get(&target).and_then(|t| t.wasi_root.as_ref()).map(|p| &**p)
/// Returns the `lib` directory for the WASI target specified, if
/// configured.
///
/// This first consults `wasi-root` as configured in per-target
/// configuration, and failing that it assumes that `$WASI_SDK_PATH` is
/// set in the environment, and failing that `None` is returned.
fn wasi_libdir(&self, target: TargetSelection) -> Option<PathBuf> {
let configured =
self.config.target_config.get(&target).and_then(|t| t.wasi_root.as_ref()).map(|p| &**p);
if let Some(path) = configured {
return Some(path.join("lib").join(target.to_string()));
}
let mut env_root = PathBuf::from(std::env::var_os("WASI_SDK_PATH")?);
env_root.push("share");
env_root.push("wasi-sysroot");
env_root.push("lib");
env_root.push(target.to_string());
Some(env_root)
}

/// Returns `true` if this is a no-std `target`, if defined
Expand Down
12 changes: 11 additions & 1 deletion src/bootstrap/src/utils/cc_detect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> {
Some(PathBuf::from("ar"))
} else if target.contains("vxworks") {
Some(PathBuf::from("wr-ar"))
} else if target.contains("android") {
} else if target.contains("android") || target.contains("-wasi") {
Some(cc.parent().unwrap().join(PathBuf::from("llvm-ar")))
} else {
let parent = cc.parent().unwrap();
Expand Down Expand Up @@ -223,6 +223,16 @@ fn default_compiler(
}
}

t if t.contains("-wasi") => {
let root = PathBuf::from(std::env::var_os("WASI_SDK_PATH")?);
let compiler = match compiler {
Language::C => format!("{t}-clang"),
Language::CPlusPlus => format!("{t}-clang++"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of interest, why is clang/clang++ prefixed with the target? That seems like an odd choice for the usually cross-compiling nature of clang/LLVM?

(Obviously not blocking here since it's not something we can change on the Rust side :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not necessarily required but it helps configure clang with the --target value. Clang has a feature that a target-prefixed executable doesn't need --target passed, and the wasi-sdk sysroot has a bunch of symlinks for wasi targets that all point at a single clang executable, so it's all the same executable just a name-based-dispatch executable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I didn't know about that feature. Sounds good.

};
let compiler = root.join("bin").join(compiler);
Some(compiler)
}

_ => None,
}
}
Expand Down
11 changes: 3 additions & 8 deletions src/ci/docker/host-x86_64/dist-various-2/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,9 @@ RUN /tmp/build-solaris-toolchain.sh sparcv9 sparcv9 solaris-sparc sun
COPY host-x86_64/dist-various-2/build-x86_64-fortanix-unknown-sgx-toolchain.sh /tmp/
RUN /tmp/build-x86_64-fortanix-unknown-sgx-toolchain.sh

COPY host-x86_64/dist-various-2/build-wasi-toolchain.sh /tmp/
RUN /tmp/build-wasi-toolchain.sh

COPY host-x86_64/dist-various-2/build-wasi-threads-toolchain.sh /tmp/
RUN /tmp/build-wasi-threads-toolchain.sh
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sdk-22.0-linux.tar.gz | \
tar -xz
ENV WASI_SDK_PATH=/tmp/wasi-sdk-22.0

COPY scripts/freebsd-toolchain.sh /tmp/
RUN /tmp/freebsd-toolchain.sh i686
Expand Down Expand Up @@ -136,9 +134,6 @@ ENV TARGETS=$TARGETS,x86_64-unknown-uefi
RUN ln -s /usr/include/x86_64-linux-gnu/asm /usr/local/include/asm

ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-llvm-bitcode-linker --disable-docs \
--set target.wasm32-wasi.wasi-root=/wasm32-wasip1 \
--set target.wasm32-wasip1.wasi-root=/wasm32-wasip1 \
--set target.wasm32-wasip1-threads.wasi-root=/wasm32-wasip1-threads \
--musl-root-armv7=/musl-armv7

ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS

This file was deleted.

23 changes: 0 additions & 23 deletions src/ci/docker/host-x86_64/dist-various-2/build-wasi-toolchain.sh

This file was deleted.

11 changes: 4 additions & 7 deletions src/ci/docker/host-x86_64/test-various/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ WORKDIR /
COPY scripts/sccache.sh /scripts/
RUN sh /scripts/sccache.sh

COPY host-x86_64/dist-various-2/build-wasi-toolchain.sh /tmp/
RUN /tmp/build-wasi-toolchain.sh
RUN curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-22/wasi-sdk-22.0-linux.tar.gz | \
tar -xz
ENV WASI_SDK_PATH=/wasi-sdk-22.0

ENV RUST_CONFIGURE_ARGS \
--musl-root-x86_64=/usr/local/x86_64-linux-musl \
--set build.nodejs=/node-v18.12.0-linux-x64/bin/node \
--set rust.lld \
--set target.wasm32-wasip1.wasi-root=/wasm32-wasip1
--set rust.lld

# Some run-make tests have assertions about code size, and enabling debug
# assertions in libstd causes the binary to be much bigger than it would
Expand All @@ -68,9 +68,6 @@ ENV WASM_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $WASM_T
tests/codegen \
tests/assembly \
library/core
ENV CC_wasm32_wasip1=clang-11 \
CFLAGS_wasm32_wasip1="--sysroot /wasm32-wasip1" \
AR_wasm32_wasip1=llvm-ar-11

ENV NVPTX_TARGETS=nvptx64-nvidia-cuda
ENV NVPTX_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $NVPTX_TARGETS \
Expand Down
36 changes: 20 additions & 16 deletions src/doc/rustc/src/platform-support/wasm32-wasip1.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,21 @@ be used instead.

## Building the target

To build this target a compiled version of [`wasi-libc`] is required to be
present at build time. This can be installed through
[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk) as well. This is the
configured with:

```toml
[target.wasm32-wasip1]
wasi-root = ".../wasi-libc/sysroot"
To build this target first acquire a copy of
[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk/). At this time version 22
is the minimum needed.

Next configure the `WASI_SDK_PATH` environment variable to point to where this
is installed. For example:

```text
export WASI_SDK_PATH=/path/to/wasi-sdk-22.0
```

Additionally users will need to enable LLD when building Rust from source as
LLVM's `wasm-ld` driver for LLD is required when linking WebAssembly code
together.
Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld`
driver for LLD is required when linking WebAssembly code together. Rust's build
system will automatically pick up any necessary binaries and programs from
`WASI_SDK_PATH`.

## Building Rust programs

Expand All @@ -112,8 +114,10 @@ This target can be cross-compiled from any hosts.

## Testing

Currently the WASI target is not tested in rust-lang/rust CI. This means that
tests in the repository are not guaranteed to pass. This is theoretically
possibly by installing a standalone WebAssembly runtime and using it as a
"runner" for all tests, but there are various failures that will need to be
waded through to adjust tests to work on the WASI target.
This target is tested in rust-lang/rust CI on all merges. A subset of tests are
run in the `test-various` builder such as the UI tests and libcore tests. This
can be tested locally, for example, with:

```text
./x.py test --target wasm32-wasip1 tests/ui
```
33 changes: 29 additions & 4 deletions src/doc/rustc/src/platform-support/wasm32-wasip2.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,34 @@ This target is cross-compiled. The target supports `std` fully.

## Platform requirements

The WebAssembly runtime should support the wasi preview 2 API set.
The WebAssembly runtime should support the wasi preview 2 API set. Runtimes also
are required to support components since this target outputs a component as
opposed to a core wasm module. As of the time of this writing Wasmtime 17 and
above is able to run this target natively with no extra flags.

This target is not a stable target. This means that there are only a few engines
which implement wasi preview 2, for example:
## Building the target

* Wasmtime - `-W component-model`
To build this target first acquire a copy of
[`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk/). At this time version 22
is the minimum needed.

Next configure the `WASI_SDK_PATH` environment variable to point to where this
is installed. For example:

```text
export WASI_SDK_PATH=/path/to/wasi-sdk-22.0
```

Next be sure to enable LLD when building Rust from source as LLVM's `wasm-ld`
driver for LLD is required when linking WebAssembly code together. Rust's build
system will automatically pick up any necessary binaries and programs from
`WASI_SDK_PATH`.

## Testing

This target is not tested in CI at this time. Locally it can be tested with a
`wasmtime` binary in `PATH` like so:

```text
./x.py test --target wasm32-wasip2 tests/ui
```
Loading