`uucore` and `env` do not build for `wasm32-wasip2` when used as a library / standalone
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 24.1k
- Forks
- 2k
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 365
Description
Since #12653 the workspace builds for wasm32-wasip2, and that is great I run most of the
common utilities inside a WebAssembly component today. But three things still break for anyone
who consumes the crates rather than building the whole workspace, and I would like to contribute
the fixes (PR to follow soon).
1. uucore with its fs feature does not compile on wasm32-wasip2 on its own.
$ cargo check --target wasm32-wasip2 -p uu_cat -p uu_cp -p uu_printf # any subset of the workspace
error[E0277]: the trait bound `impl AsFd: rustix::fd::AsFd` is not satisfied --> src/uucore/src/lib/features/fs.rs:65:38
error[E0277]: `?` couldn't convert the error to `std::io::Error` --> src/uucore/src/lib/features/fs.rs:65:43
error[E0277]: the trait bound `&Path: rustix::path::Arg` is not satisfied --> src/uucore/src/lib/features/fs.rs:88:34
error[E0277]: the trait bound `&Path: rustix::path::Arg` is not satisfied --> src/uucore/src/lib/features/fs.rs:90:35
error[E0277]: `?` couldn't convert the error to `std::io::Error` --> src/uucore/src/lib/features/fs.rs:92:25
error[E0277]: the trait bound `Stdin: rustix::fd::AsFd` is not satisfied --> src/uucore/src/lib/features/fs.rs:922:45
error[E0277]: the trait bound `T: rustix::fd::AsFd` is not satisfied --> src/uucore/src/lib/mods/io.rs:39:27
error[E0277]: the trait bound `std::io::Error: From<Errno>` is not satisfied --> src/uucore/src/lib/mods/io.rs:39:46
error[E0277]: the trait bound `std::io::Error: From<Errno>` is not satisfied --> src/uucore/src/lib/mods/io.rs:39:9
error[E0277]: the trait bound `T: rustix::fd::AsFd` is not satisfied --> src/uucore/src/lib/mods/io.rs:49:28
error[E0277]: the trait bound `std::io::Error: From<Errno>` is not satisfied --> src/uucore/src/lib/mods/io.rs:49:47
error[E0277]: the trait bound `std::io::Error: From<Errno>` is not satisfied --> src/uucore/src/lib/mods/io.rs:49:9
error: could not compile `uucore` (lib) due to 12 previous errors
Why: the workspace declares rustix = { version = "1.1.4", default-features = false } and
uucore's features turn on rustix/fs, rustix/process, rustix/pipe — but never rustix/std.
rustix::fd::AsFd, rustix::path::Arg for &Path and From<Errno> for io::Error all live behind
rustix's std feature, so without it those impls do not exist and every call site fails to
type-check.
Why it passes on unix and not here: uucore → clap → clap_builder → terminal_size depends on
rustix with its default features, std among them, so feature unification switches std on
for the whole graph and uucore's own rustix/fs-only edge compiles anyway. On wasm32-wasip2
terminal_size is not in the graph, nothing else enables std, and the same code stops compiling.
So the gap only shows on this target, and only for a build that does not happen to include a
crate pulling rustix's defaults.
Note when reproducing: cargo check -p uucore alone succeeds, but not because std is on —
uucore's rustix dependency is optional = true and is activated only by fs, entries,
mode, pipes, process, checksum and uptime, so with none of them selected there is no
rustix-using code to compile. (The rustix that shows up in cargo tree there is tempfile's,
a dev-dependency, which the lib build never sees.) Use -p uucore --features fs, or any uu_*
crate as above.
2. env does not compile on wasm32-wasip2, and it has just been dropped from the wasm build
because of it.
Using the same flags the wasip2 CI job uses (CICD.yml:391), plus env:
$ cargo check --target wasm32-wasip2 --no-default-features --features feat_wasm,env -p coreutils
error[E0658]: use of unstable library feature `wasip2`
--> src/uu/env/src/native_int_str.rs:19:14
|
19 | use std::os::wasi::ffi::{OsStrExt, OsStringExt};
| ^^^^
error: could not compile `uu_env` (lib) due to 2 previous errors
uucore solved this same import in #12653 by gating std::os::wasi::ffi to target_env = "p1"
and using the stable encoded-bytes API on p2; env's native_int_str.rs predates that and still
has the unconditional import. I see that c9077c764 ("reconsider feat_{wasm,common_core,Tier1}
for wasi", yesterday) worked around it from the other side — feat_wasm became
["feat_common_core", "nproc"] and env moved out of feat_common_core into feat_Tier1, so
the wasip2 job no longer builds it. The fix below makes env compile on the target, and its last
commit puts env back into feat_common_core so the two wasm CI jobs cover it; with the patch,
the command above succeeds, as does plain --features feat_wasm on wasip1 and wasip2.
3. Embedding uucore where argv is empty aborts the component.
EXECUTION_PHRASE (lib.rs) does ARGV[0], and util_name() indexes ARGV[argv_index]. On a
CLI that is always fine. In a WebAssembly component — a library linked into a host program, or a
guest whose host supplies no command line — std::env::args_os() is empty, and the first
uucore::util_name() call panics, which on wasm is a trap that takes the whole instance down. We
hit this running cat/ls/… as in-process library calls from a shell compiled to a component.
What I would like: uucore (with fs) and every utility in feat_wasm plus env to build on
wasm32-wasip2 standalone, and uucore not to trap when there is no argv. All three fixes are
small and confined to this target — one feature flag on uucore's own optional rustix
dependency, one cfg-gated module in env, one cfg(target_os = "wasi") guard in uucore.
Native behaviour does not change. Happy to add a CI step that builds one uu_* crate with -p
on the target so (1) cannot regress.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/uucore/src/lib/features/fs.rs and src/uucore/src/lib/mods/io.rs, then inspect the optional rustix dependency features. Read src/uu/env/src/native_int_str.rs and the wasm feature definitions around CICD.yml:391, and inspect uucore's lib.rs for the argv indexing. Done means standalone wasm32-wasip2 builds cover uucore and env, and empty argv no longer traps; verify with the cargo checks shown in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, wasm
- Domain
- build-system, cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100