wasip2: build uucore and env standalone, don't trap on empty argv - #14562
Open
Aditya1404Sal wants to merge 4 commits into
Open
Aditya1404Sal wants to merge 4 commits into
Aditya1404Sal wants to merge 4 commits into
Conversation
…encoded-bytes conversions)
Aditya1404Sal
force-pushed
the
wasip2-fixes
branch
from
September 14, 2026 14:52
b7b4796 to
c4058d7
Compare
Aditya1404Sal
marked this pull request as ready for review
September 14, 2026 19:20
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Add WASI Preview 2 coverage and regression tests for the new conversion and empty-argv paths.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Enables standalone wasm32-wasip2 builds for uucore and env, while preventing empty-WASI-argv traps.
Changes:
- Enables
rustix/stdforuucore. - Adds WASI Preview 2 encoded-byte conversions for
env. - Restores
envto common/WASI features and adds an empty-argv fallback.
File summaries
| File | Description |
|---|---|
src/uucore/src/lib/lib.rs |
Prevents empty-argv indexing on WASI. |
src/uucore/Cargo.toml |
Enables required rustix standard-library APIs. |
src/uu/env/src/native_int_str.rs |
Adds WASI Preview 2 string conversions. |
Cargo.toml |
Includes env in common/WASI features. |
Review details
Suppressed comments (1)
Cargo.toml:140
- This move does not provide the wasip2 CI coverage claimed in the PR description:
.github/workflows/wasi.ymlgates thefeat_wasmbuild to wasip1 and excludesenvfrom the wasip2 package-test list. Add a wasip2 compile/test step or correct the description before relying on this feature move for regression protection.
"env",
- Files reviewed: 4/4 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+31
to
+32
| #[cfg(all(target_os = "wasi", not(target_env = "p1")))] | ||
| mod wasip2_ffi { |
Comment on lines
+377
to
+381
| #[cfg(all(not(windows), target_os = "wasi"))] | ||
| static ARGV: LazyLock<Vec<OsString>> = LazyLock::new(|| { | ||
| let argv: Vec<OsString> = std::env::args_os().collect(); | ||
| if argv.is_empty() { | ||
| vec![OsString::from("uu")] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fixes #14561
Four commits
uucore: enable rustix/std so its fs and io modules compile on wasm32-wasip2One line in
src/uucore/Cargo.toml: the optionalrustixdependency gainsfeatures = ["std"].stdis a rustix default feature the graph already ends up with on unixvia
clap→clap_builder→terminal_size, which depends on rustix with its defaults;terminal_sizeis absent onwasm32-wasip2, so nothing enables it there and the std-backedAPI those modules use (
AsFd,Arg for &Path,From<Errno> for io::Error) is not compiled.The requirement is put on the dependency rather than repeated across the seven features that
activate it (
fs,entries,mode,pipes,process,checksum,uptime), all of whichuse that API. Deliberately scoped to
uucore: settingfeatures = ["std"]on the workspacerustixworks too, but changes rustix for every member. The narrow version is enough for thewhole wasm build — including
uu_tee, the one other crate whose ownrustixdependency islive on
target_os = "wasi", which picks upstdthroughuucorein any build that containsboth (and every
uu_*crate depends onuucore).env: build on wasm32-wasip2 without the unstable std::os::wasi::ffi (encoded-bytes conversions)native_int_str.rskeeps thestd::os::wasi::ffiimport fortarget_env = "p1"and gains asmall
wasip2_ffimodule for p2:as_bytes→as_encoded_bytes,into_vec→into_encoded_bytes, andfrom_vecthroughString::from_utf8(lossy only for bytes thatcannot have come from the host — the component model defines strings as UTF-8). No
unsafe,matching the module's stated rule and the approach
uucore::os_str_from_bytes/os_string_from_vecalready take on this target. One consequence:from_native_int_representationreturns an owned
OsStron p2 where it could borrow before, because bytes →OsStrhas to gothrough
str.env: return to feat_common_core now that it builds on wasm32-wasip1 and wasip2Reverts the
envhalf ofc9077c764:envgoes back intofeat_common_core(so back intofeat_wasm, which is now["feat_common_core", "nproc"]) and out offeat_Tier1, where it hadbeen moved to keep it out of the wasm build. This is what gives commit 2 CI coverage — the
existing wasip1 and wasip2 jobs both build
feat_wasm, so a regression in theenvconversionsfails the build rather than going unnoticed. The other four utilities that commit moved out stay
where they are:
df,duandmoregenuinely do not compile for wasip2, andtacdoes butnothing in this PR changed it, so restoring it is your call, not mine. Drop this commit if you
would rather keep
envout of the wasm set for reasons beyond the build failure.uucore: don't index an empty argv on wasip2 (guests embedded as libraries have none)On
target_os = "wasi",ARGVis initialised with a single fallback element whenstd::env::args_os()is empty, soUTIL_NAME/EXECUTION_PHRASEresolve to a stable nameinstead of panicking. Other targets are unchanged. If you prefer this unconditional (a library
consumer on any OS can have an empty argv), it is a one-line
cfgchange — I kept it to wasi tomatch where it was observed.
Testing
cargo check --target wasm32-wasip2 --no-default-features --features feat_wasm,env -p coreutils— the wasip2 CI job's own flags plus
env:E0658onmain, clean with the patch. With commit3 the same holds for plain
--features feat_wasm(no explicitenv) on bothwasm32-wasip1and
wasm32-wasip2, which is what the two CI jobs run;--features feat_os_unixstill buildsnatively.
cargo check --target wasm32-wasip2 -p uucore -p uu_cat -p uu_ls -p uu_wc -p uu_head -p uu_sort -p uu_mkdir -p uu_rm -p uu_mv -p uu_cp -p uu_env -p uu_cut -p uu_tr -p uu_uniq -p uu_tail -p uu_tee -p uu_touch -p uu_sleep -p uu_printf— clean (12 errors → 0;envbuilds).cargo clippy -p uu_env --all-targets -- -D warnings, native and--target wasm32-wasip2— clean;cargo fmt --checkclean;cargo test -p uucore --libpasses.env.wasmbehaves:wasmtime --env X=1 env.wasmprints
X=1, andenv -u Xdrops it.eighteen
uu_*crates as library functions.