Skip to content

Commit 7c10562

Browse files
committed
Re-enable testing of WASI on CI
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.
1 parent 72cb7aa commit 7c10562

File tree

7 files changed

+80
-71
lines changed

7 files changed

+80
-71
lines changed

.github/workflows/full_ci.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,7 @@ jobs:
118118
powerpc64le-unknown-linux-gnu,
119119
s390x-unknown-linux-gnu,
120120
riscv64gc-unknown-linux-gnu,
121-
# FIXME: A recent nightly causes a linker failure:
122-
# https://github.com/rust-lang/rust/issues/76679
123-
# See this comment for more details:
124-
# https://github.com/rust-lang/libc/pull/2225#issuecomment-880696737
125-
#wasm32-wasi,
121+
wasm32-wasip1,
126122
sparc64-unknown-linux-gnu,
127123
wasm32-unknown-emscripten,
128124
x86_64-linux-android,

build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const ALLOWED_CFGS: &'static [&'static str] = &[
1717
"libc_const_extern_fn",
1818
"libc_const_extern_fn_unstable",
1919
"libc_deny_warnings",
20+
"libc_ctest",
2021
];
2122

2223
// Extra values to allow for check-cfg.

ci/docker/wasm32-wasi/Dockerfile

Lines changed: 0 additions & 40 deletions
This file was deleted.

ci/docker/wasm32-wasi/clang.sh

Lines changed: 0 additions & 2 deletions
This file was deleted.

ci/docker/wasm32-wasip1/Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
FROM ubuntu:24.04
2+
3+
RUN apt-get update && \
4+
apt-get install -y --no-install-recommends \
5+
ca-certificates \
6+
curl \
7+
clang \
8+
xz-utils
9+
10+
# Wasmtime is used to execute tests and wasi-sdk is used to compile tests.
11+
# Download appropriate versions here and configure various flags below.
12+
ENV WASMTIME 24.0.0
13+
ENV WASI_SDK 24
14+
15+
RUN curl -L https://github.com/bytecodealliance/wasmtime/releases/download/v$WASMTIME/wasmtime-v$WASMTIME-x86_64-linux.tar.xz | \
16+
tar xJf -
17+
ENV PATH=$PATH:/wasmtime-v$WASMTIME-x86_64-linux
18+
19+
RUN curl -LO https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-$WASI_SDK/wasi-sdk-$WASI_SDK.0-x86_64-linux.deb
20+
RUN dpkg -i ./wasi-sdk-*.deb
21+
22+
# Note that `-D_WASI_EMULATED_PROCESS_CLOCKS` is used to enable access to
23+
# clock-related defines even though they're emulated. Also note that the usage
24+
# of `-Ctarget-feature=-crt-static` here forces usage of the external wasi-libc
25+
# installed via `wasi-sdk` instead of the version that comes with the standard
26+
# library.
27+
ENV CARGO_TARGET_WASM32_WASIP1_RUNNER=wasmtime \
28+
CARGO_TARGET_WASM32_WASIP1_LINKER=/opt/wasi-sdk/bin/clang \
29+
CARGO_TARGET_WASM32_WASIP1_RUSTFLAGS="-lwasi-emulated-process-clocks -Ctarget-feature=-crt-static" \
30+
CC_wasm32_wasip1=/opt/wasi-sdk/bin/clang \
31+
CFLAGS_wasm32_wasip1=-D_WASI_EMULATED_PROCESS_CLOCKS \
32+
PATH=$PATH:/rust/bin

libc-test/build.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,7 @@ fn test_wasi(target: &str) {
14371437
"dirent.h",
14381438
"errno.h",
14391439
"fcntl.h",
1440+
"langinfo.h",
14401441
"limits.h",
14411442
"locale.h",
14421443
"malloc.h",
@@ -1448,6 +1449,7 @@ fn test_wasi(target: &str) {
14481449
"stdio.h",
14491450
"stdlib.h",
14501451
"string.h",
1452+
"sys/ioctl.h",
14511453
"sys/resource.h",
14521454
"sys/select.h",
14531455
"sys/socket.h",
@@ -1456,16 +1458,20 @@ fn test_wasi(target: &str) {
14561458
"sys/types.h",
14571459
"sys/uio.h",
14581460
"sys/utsname.h",
1459-
"sys/ioctl.h",
14601461
"time.h",
14611462
"unistd.h",
14621463
"wasi/api.h",
1463-
"wasi/libc.h",
14641464
"wasi/libc-find-relpath.h",
14651465
"wasi/libc-nocwd.h",
1466+
"wasi/libc.h",
14661467
"wchar.h",
14671468
}
14681469

1470+
// Currently `ctest2` doesn't support macros-in-static-expressions and will
1471+
// panic on them. That affects `CLOCK_*` defines in wasi to set this here
1472+
// to omit them.
1473+
cfg.cfg("libc_ctest", None);
1474+
14691475
cfg.type_name(move |ty, is_struct, is_union| match ty {
14701476
"FILE" | "fd_set" | "DIR" => ty.to_string(),
14711477
t if is_union => format!("union {}", t),
@@ -1484,20 +1490,27 @@ fn test_wasi(target: &str) {
14841490
}
14851491
});
14861492

1487-
// Looks like LLD doesn't merge duplicate imports, so if the Rust
1488-
// code imports from a module and the C code also imports from a
1489-
// module we end up with two imports of function pointers which
1490-
// import the same thing but have different function pointers
1491-
cfg.skip_fn_ptrcheck(|f| f.starts_with("__wasi"));
1493+
// These have a different and internal type in header files and are only
1494+
// used here to generate a pointer to them in bindings so skip these tests.
1495+
cfg.skip_static(|c| c.starts_with("_CLOCK_"));
1496+
1497+
cfg.skip_fn(|f| match f {
1498+
// This function doesn't actually exist in libc's header files
1499+
"__errno_location" => true,
1500+
1501+
// The `timeout` argument to this function is `*const` in Rust but
1502+
// mutable in C which causes a mismatch. Avoiding breakage by changing
1503+
// this in wasi-libc and instead accepting that this is slightly
1504+
// different.
1505+
"select" => true,
1506+
1507+
_ => false,
1508+
});
14921509

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

1497-
// Currently Rust/clang disagree on function argument ABI, so skip these
1498-
// tests. For more info see WebAssembly/tool-conventions#88
1499-
cfg.skip_roundtrip(|_| true);
1500-
15011514
cfg.generate("../src/lib.rs", "main.rs");
15021515
}
15031516

src/wasi.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,14 @@ pub const AT_SYMLINK_FOLLOW: c_int = 0x2;
248248
pub const AT_REMOVEDIR: c_int = 0x4;
249249
pub const UTIME_OMIT: c_long = 0xfffffffe;
250250
pub const UTIME_NOW: c_long = 0xffffffff;
251-
pub const S_IFIFO: mode_t = 0o14_0000;
251+
pub const S_IFIFO: mode_t = 0o1_0000;
252252
pub const S_IFCHR: mode_t = 0o2_0000;
253253
pub const S_IFBLK: mode_t = 0o6_0000;
254254
pub const S_IFDIR: mode_t = 0o4_0000;
255255
pub const S_IFREG: mode_t = 0o10_0000;
256256
pub const S_IFLNK: mode_t = 0o12_0000;
257257
pub const S_IFSOCK: mode_t = 0o14_0000;
258-
pub const S_IFMT: mode_t = 0o16_0000;
258+
pub const S_IFMT: mode_t = 0o17_0000;
259259
pub const S_IRWXO: mode_t = 0o0007;
260260
pub const S_IXOTH: mode_t = 0o0001;
261261
pub const S_IWOTH: mode_t = 0o0002;
@@ -375,17 +375,26 @@ pub const _SC_PAGE_SIZE: ::c_int = _SC_PAGESIZE;
375375
pub const _SC_IOV_MAX: c_int = 60;
376376
pub const _SC_SYMLOOP_MAX: c_int = 173;
377377

378-
// unsafe code here is required in the stable, but not in nightly
379-
#[allow(unused_unsafe)]
380-
pub static CLOCK_MONOTONIC: clockid_t = unsafe { clockid_t(ptr_addr_of!(_CLOCK_MONOTONIC)) };
381-
#[allow(unused_unsafe)]
382-
pub static CLOCK_PROCESS_CPUTIME_ID: clockid_t =
383-
unsafe { clockid_t(ptr_addr_of!(_CLOCK_PROCESS_CPUTIME_ID)) };
384-
#[allow(unused_unsafe)]
385-
pub static CLOCK_REALTIME: clockid_t = unsafe { clockid_t(ptr_addr_of!(_CLOCK_REALTIME)) };
386-
#[allow(unused_unsafe)]
387-
pub static CLOCK_THREAD_CPUTIME_ID: clockid_t =
388-
unsafe { clockid_t(ptr_addr_of!(_CLOCK_THREAD_CPUTIME_ID)) };
378+
cfg_if! {
379+
if #[cfg(libc_ctest)] {
380+
// skip these constants when this is active because `ctest` currently
381+
// panics on parsing the constants below
382+
} else {
383+
// unsafe code here is required in the stable, but not in nightly
384+
#[allow(unused_unsafe)]
385+
pub static CLOCK_MONOTONIC: clockid_t =
386+
unsafe { clockid_t(ptr_addr_of!(_CLOCK_MONOTONIC)) };
387+
#[allow(unused_unsafe)]
388+
pub static CLOCK_PROCESS_CPUTIME_ID: clockid_t =
389+
unsafe { clockid_t(ptr_addr_of!(_CLOCK_PROCESS_CPUTIME_ID)) };
390+
#[allow(unused_unsafe)]
391+
pub static CLOCK_REALTIME: clockid_t =
392+
unsafe { clockid_t(ptr_addr_of!(_CLOCK_REALTIME)) };
393+
#[allow(unused_unsafe)]
394+
pub static CLOCK_THREAD_CPUTIME_ID: clockid_t =
395+
unsafe { clockid_t(ptr_addr_of!(_CLOCK_THREAD_CPUTIME_ID)) };
396+
}
397+
}
389398

390399
pub const ABDAY_1: ::nl_item = 0x20000;
391400
pub const ABDAY_2: ::nl_item = 0x20001;

0 commit comments

Comments
 (0)