fix: skip importing `memfd` and `rustix` if `std` feature is disabled by HoKim98 · Pull Request #12520 · bytecodealliance/wasmtime

@HoKim98

We do not need to import memfd and rustix crates if we have disabled the std feature.
This PR just excludes these packages on fiber and wasmtime if std feature is disabled.

If we don't do this, libstd.rmeta will be forcibly linked when building a package that links wasmtime in a #![no_std] environment.

@alexcrichton

Thanks! Do you know if this is something we can check in CI? For example are there cfg(unix) targets in Rust where the standard library is not available?

@HoKim98

I think one easy way to find the std dependency is to create a new package in a separate workspace and link wasmtime against it.

Suggested CI-Only Package

# Cargo.toml
[package]
name = "foo"
version = "0.1.0"
edition = "2024"
rust-version = "1.94"  # rustc 1.94.0-nightly (fcd630976 2026-01-01)

[lib]
crate-type = ["cdylib"]

[profile.dev]
panic = "abort"

[dependencies]
dlmalloc = { version = "0.2", default-features = false, features = ["global"] }
wasmtime = { version = "41.0", default-features = false, features = [
    "runtime",
] }
// src/lib.rs
#![no_std]

extern crate dlmalloc;
extern crate wasmtime;

#[global_allocator]
static GLOBAL: ::dlmalloc::GlobalDlmalloc = ::dlmalloc::GlobalDlmalloc;

#[panic_handler]
fn panic_handler(_info: &::core::panic::PanicInfo<'_>) -> ! {
    loop {}
}

Current Outputs

error[E0152]: found duplicate lang item `panic_impl`
  --> src/lib.rs:10:1
   |
10 | / fn panic_handler(_info: &::core::panic::PanicInfo<'_>) -> ! {
11 | |     loop {}
12 | | }
   | |_^
   |
   = note: the lang item is first defined in crate `std` (which `bitflags` depends on)
   = note: first definition in `std` loaded from /opt/rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-ad248a6e6fe48fd9.rlib
   = note: second definition in the local crate (`foo`)

For more information about this error, try `rustc --explain E0152`.
error: could not compile `foo` (lib) due to 1 previous error

Expected Outputs

$ cargo build -p foo
$ ldd target/debug/libfoo.so
        statically linked

@HoKim98

…isabled

Signed-off-by: Ho Kim <ho.kim@ulagbulag.io>

@HoKim98

I've added a simple no_std validation package for PoC purposes. While the package name, description, and location are currently placeholders, I can confirm the functionality is solid.

This new commit will help proactively detect and prevent no_std related issues, such as #1158. In fact, it has already identified a case in cranelift-frontend where the std package was being used in a no_std environment.

Additionally, it detected a std dependency in cranelift-codegen caused by the use of std::sync::OnceCell. I believe this can be resolved using a pattern similar to Wasmtime’s sync_nostd.rs.

alexcrichton

alexcrichton

Choose a reason for hiding this comment

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

Thanks!

@alexcrichton

Hm ok seeing that CI is failing... this is unfortunately going to be a bit tricky. The problem is that this is a workspace member which means that when testing/linting/etc the entire workspace all features for wasmtime are union'd. That means that despite this crate not asking for the std feature, for example, it's still enabled and then when the std feature is enabled it predictably causes the test to fail to build.

The easiest thing to do would probably be to exclude this as a workspace member. That would generate a separate Cargo.lock though and would be a pain to update both this second Cargo.lock and the main one. The second easiest thing to do would be to pass --exclude to various command lines (e.g. in ./ci/run-tests.py and in the CI config for running clippy). That's also a bit unfortunate though since it now requires passing --exclude locally as well when running the commands manually.

All-in-all I might say that we should forgo the test on this one. I apologize for the runaround here but I didn't realize the effect that this would have on CI and local development. If you agree I'm happy to flag-for-merge with the test removed from this PR

@HoKim98

How about doing the first method but ignoring Cargo.lock?

@alexcrichton

The risk of that is that then we're not insulated against new publications of crates accidentally breaking us in CI. In general we want CI to be as reprodcible as possible across runs, which is one of the primary reason to include Cargo.lock here. It's in theory possible to start with the workspace's Cargo.lock and have that get automatically trimmed down, but that's where I feel the infrastructure here isn't really buying too too much and I think it's reasonable to skip the test.

@HoKim98

I’m sorry to hear that this might not be the best news. In that case, I will personally set up a separate repository for CI to manage no_std compatibility for these changes. I’ll go ahead and roll back the commits related to the no_std CI implementation.

alexcrichton