Skip to content

Commit

Permalink
Re-enable testing of WASI on CI
Browse files Browse the repository at this point in the history
This commit updates CI to resume testing WASI. This updates the
container and testing scripts from historical processes to more modern
ones, e.g. downloading wasi-sdk instead of compiling a custom toolchain.
This should make it easier to update in the future and keep it in sync
with rust-lang/rust as well.

This also required a few minor fixes such as:

* The `S_IFIFO` and `S_IFMT` constants had incorrect values.
* The `CLOCK_*` definitions cause `ctest2`'s parsing to panic to they're
  skipped with a new `#[cfg]`.
* A new `langinfo.h` header was added to the list to include.
* Some historically skipped checks were removed since they're no longer
  necessary.
* Checks for `__errno_location` are disabled since that doesn't actually
  exist in headers.
* Checks for `select` are disabled because the Rust definition got the
  `const`-ness swapped for the final `timeval` argument.
  • Loading branch information
alexcrichton committed Aug 27, 2024
1 parent 72cb7aa commit 7c10562
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 71 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/full_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,7 @@ jobs:
powerpc64le-unknown-linux-gnu,
s390x-unknown-linux-gnu,
riscv64gc-unknown-linux-gnu,
# FIXME: A recent nightly causes a linker failure:
# https://github.com/rust-lang/rust/issues/76679
# See this comment for more details:
# https://github.com/rust-lang/libc/pull/2225#issuecomment-880696737
#wasm32-wasi,
wasm32-wasip1,
sparc64-unknown-linux-gnu,
wasm32-unknown-emscripten,
x86_64-linux-android,
Expand Down
1 change: 1 addition & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const ALLOWED_CFGS: &'static [&'static str] = &[
"libc_const_extern_fn",
"libc_const_extern_fn_unstable",
"libc_deny_warnings",
"libc_ctest",
];

// Extra values to allow for check-cfg.
Expand Down
40 changes: 0 additions & 40 deletions ci/docker/wasm32-wasi/Dockerfile

This file was deleted.

2 changes: 0 additions & 2 deletions ci/docker/wasm32-wasi/clang.sh

This file was deleted.

32 changes: 32 additions & 0 deletions ci/docker/wasm32-wasip1/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
FROM ubuntu:24.04

RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
clang \
xz-utils

# Wasmtime is used to execute tests and wasi-sdk is used to compile tests.
# Download appropriate versions here and configure various flags below.
ENV WASMTIME 24.0.0
ENV WASI_SDK 24

RUN curl -L https://github.com/bytecodealliance/wasmtime/releases/download/v$WASMTIME/wasmtime-v$WASMTIME-x86_64-linux.tar.xz | \
tar xJf -
ENV PATH=$PATH:/wasmtime-v$WASMTIME-x86_64-linux

RUN curl -LO https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$WASI_SDK/wasi-sdk-$WASI_SDK.0-x86_64-linux.deb
RUN dpkg -i ./wasi-sdk-*.deb

# Note that `-D_WASI_EMULATED_PROCESS_CLOCKS` is used to enable access to
# clock-related defines even though they're emulated. Also note that the usage
# of `-Ctarget-feature=-crt-static` here forces usage of the external wasi-libc
# installed via `wasi-sdk` instead of the version that comes with the standard
# library.
ENV CARGO_TARGET_WASM32_WASIP1_RUNNER=wasmtime \
CARGO_TARGET_WASM32_WASIP1_LINKER=/opt/wasi-sdk/bin/clang \
CARGO_TARGET_WASM32_WASIP1_RUSTFLAGS="-lwasi-emulated-process-clocks -Ctarget-feature=-crt-static" \
CC_wasm32_wasip1=/opt/wasi-sdk/bin/clang \
CFLAGS_wasm32_wasip1=-D_WASI_EMULATED_PROCESS_CLOCKS \
PATH=$PATH:/rust/bin
35 changes: 24 additions & 11 deletions libc-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,7 @@ fn test_wasi(target: &str) {
"dirent.h",
"errno.h",
"fcntl.h",
"langinfo.h",
"limits.h",
"locale.h",
"malloc.h",
Expand All @@ -1448,6 +1449,7 @@ fn test_wasi(target: &str) {
"stdio.h",
"stdlib.h",
"string.h",
"sys/ioctl.h",
"sys/resource.h",
"sys/select.h",
"sys/socket.h",
Expand All @@ -1456,16 +1458,20 @@ fn test_wasi(target: &str) {
"sys/types.h",
"sys/uio.h",
"sys/utsname.h",
"sys/ioctl.h",
"time.h",
"unistd.h",
"wasi/api.h",
"wasi/libc.h",
"wasi/libc-find-relpath.h",
"wasi/libc-nocwd.h",
"wasi/libc.h",
"wchar.h",
}

// Currently `ctest2` doesn't support macros-in-static-expressions and will
// panic on them. That affects `CLOCK_*` defines in wasi to set this here
// to omit them.
cfg.cfg("libc_ctest", None);

cfg.type_name(move |ty, is_struct, is_union| match ty {
"FILE" | "fd_set" | "DIR" => ty.to_string(),
t if is_union => format!("union {}", t),
Expand All @@ -1484,20 +1490,27 @@ fn test_wasi(target: &str) {
}
});

// Looks like LLD doesn't merge duplicate imports, so if the Rust
// code imports from a module and the C code also imports from a
// module we end up with two imports of function pointers which
// import the same thing but have different function pointers
cfg.skip_fn_ptrcheck(|f| f.starts_with("__wasi"));
// These have a different and internal type in header files and are only
// used here to generate a pointer to them in bindings so skip these tests.
cfg.skip_static(|c| c.starts_with("_CLOCK_"));

cfg.skip_fn(|f| match f {
// This function doesn't actually exist in libc's header files
"__errno_location" => true,

// The `timeout` argument to this function is `*const` in Rust but
// mutable in C which causes a mismatch. Avoiding breakage by changing
// this in wasi-libc and instead accepting that this is slightly
// different.
"select" => true,

_ => false,
});

// d_name is declared as a flexible array in WASI libc, so it
// doesn't support sizeof.
cfg.skip_field(|s, field| s == "dirent" && field == "d_name");

// Currently Rust/clang disagree on function argument ABI, so skip these
// tests. For more info see WebAssembly/tool-conventions#88
cfg.skip_roundtrip(|_| true);

cfg.generate("../src/lib.rs", "main.rs");
}

Expand Down
35 changes: 22 additions & 13 deletions src/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,14 @@ pub const AT_SYMLINK_FOLLOW: c_int = 0x2;
pub const AT_REMOVEDIR: c_int = 0x4;
pub const UTIME_OMIT: c_long = 0xfffffffe;
pub const UTIME_NOW: c_long = 0xffffffff;
pub const S_IFIFO: mode_t = 0o14_0000;
pub const S_IFIFO: mode_t = 0o1_0000;
pub const S_IFCHR: mode_t = 0o2_0000;
pub const S_IFBLK: mode_t = 0o6_0000;
pub const S_IFDIR: mode_t = 0o4_0000;
pub const S_IFREG: mode_t = 0o10_0000;
pub const S_IFLNK: mode_t = 0o12_0000;
pub const S_IFSOCK: mode_t = 0o14_0000;
pub const S_IFMT: mode_t = 0o16_0000;
pub const S_IFMT: mode_t = 0o17_0000;
pub const S_IRWXO: mode_t = 0o0007;
pub const S_IXOTH: mode_t = 0o0001;
pub const S_IWOTH: mode_t = 0o0002;
Expand Down Expand Up @@ -375,17 +375,26 @@ pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE;
pub const _SC_IOV_MAX: c_int = 60;
pub const _SC_SYMLOOP_MAX: c_int = 173;

// unsafe code here is required in the stable, but not in nightly
#[allow(unused_unsafe)]
pub static CLOCK_MONOTONIC: clockid_t = unsafe { clockid_t(ptr_addr_of!(_CLOCK_MONOTONIC)) };
#[allow(unused_unsafe)]
pub static CLOCK_PROCESS_CPUTIME_ID: clockid_t =
unsafe { clockid_t(ptr_addr_of!(_CLOCK_PROCESS_CPUTIME_ID)) };
#[allow(unused_unsafe)]
pub static CLOCK_REALTIME: clockid_t = unsafe { clockid_t(ptr_addr_of!(_CLOCK_REALTIME)) };
#[allow(unused_unsafe)]
pub static CLOCK_THREAD_CPUTIME_ID: clockid_t =
unsafe { clockid_t(ptr_addr_of!(_CLOCK_THREAD_CPUTIME_ID)) };
cfg_if! {
if #[cfg(libc_ctest)] {
// skip these constants when this is active because `ctest` currently
// panics on parsing the constants below
} else {
// unsafe code here is required in the stable, but not in nightly
#[allow(unused_unsafe)]
pub static CLOCK_MONOTONIC: clockid_t =
unsafe { clockid_t(ptr_addr_of!(_CLOCK_MONOTONIC)) };
#[allow(unused_unsafe)]
pub static CLOCK_PROCESS_CPUTIME_ID: clockid_t =
unsafe { clockid_t(ptr_addr_of!(_CLOCK_PROCESS_CPUTIME_ID)) };
#[allow(unused_unsafe)]
pub static CLOCK_REALTIME: clockid_t =
unsafe { clockid_t(ptr_addr_of!(_CLOCK_REALTIME)) };
#[allow(unused_unsafe)]
pub static CLOCK_THREAD_CPUTIME_ID: clockid_t =
unsafe { clockid_t(ptr_addr_of!(_CLOCK_THREAD_CPUTIME_ID)) };
}
}

pub const ABDAY_1: ::nl_item = 0x20000;
pub const ABDAY_2: ::nl_item = 0x20001;
Expand Down

0 comments on commit 7c10562

Please sign in to comment.