From bdf8d3b63ffb6dee0e6c3ab7d27f818584253882 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Wed, 4 Feb 2026 10:51:43 -0800 Subject: [PATCH] Set crt_static_allow_dylibs to true for Emscripten target And add a test. This is followup work to PR 151704. It introduced a regression where cargo is now unwilling to build cdylibs for Emscripten because `crt_static_default` is `true` but `crt_static_allows_dylibs` is `false`. Unfortunately the added test does not fail without the change because the validation logic is in Cargo, not in rustc. But it's good to have some coverage of this anyways. --- .../spec/targets/wasm32_unknown_emscripten.rs | 7 ++++++ .../src/directives/directive_names.rs | 1 + tests/run-make/wasm-emscripten-cdylib/foo.rs | 4 +++ .../run-make/wasm-emscripten-cdylib/rmake.rs | 25 +++++++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 tests/run-make/wasm-emscripten-cdylib/foo.rs create mode 100644 tests/run-make/wasm-emscripten-cdylib/rmake.rs diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs index fb735b54dd82c..4b6f5b655760b 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs @@ -19,8 +19,15 @@ pub(crate) fn target() -> Target { pre_link_args, post_link_args, relocation_model: RelocModel::Pic, + // crt_static should always be true for an executable and always false + // for a shared library. There is no easy way to indicate this and it + // doesn't seem to matter much so we set crt_static_allows_dylibs to + // true and leave crt_static as true when linking dynamic libraries. + // wasi also sets crt_static_allows_dylibs: true so this is at least + // aligned between wasm targets. crt_static_respected: true, crt_static_default: true, + crt_static_allows_dylibs: true, panic_strategy: PanicStrategy::Unwind, no_default_libraries: false, families: cvs!["unix", "wasm"], diff --git a/src/tools/compiletest/src/directives/directive_names.rs b/src/tools/compiletest/src/directives/directive_names.rs index 9813ac7ff500d..230578d79ffbe 100644 --- a/src/tools/compiletest/src/directives/directive_names.rs +++ b/src/tools/compiletest/src/directives/directive_names.rs @@ -249,6 +249,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "only-unix", "only-visionos", "only-wasm32", + "only-wasm32-unknown-emscripten", "only-wasm32-unknown-unknown", "only-wasm32-wasip1", "only-watchos", diff --git a/tests/run-make/wasm-emscripten-cdylib/foo.rs b/tests/run-make/wasm-emscripten-cdylib/foo.rs new file mode 100644 index 0000000000000..08ad8e7b5c616 --- /dev/null +++ b/tests/run-make/wasm-emscripten-cdylib/foo.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn foo() -> i32 { + 42 +} diff --git a/tests/run-make/wasm-emscripten-cdylib/rmake.rs b/tests/run-make/wasm-emscripten-cdylib/rmake.rs new file mode 100644 index 0000000000000..ef5fc17c2bbe2 --- /dev/null +++ b/tests/run-make/wasm-emscripten-cdylib/rmake.rs @@ -0,0 +1,25 @@ +//! Check that cdylib crate type is supported for the wasm32-unknown-emscripten +//! target and produces a valid Emscripten dynamic library. + +//@ only-wasm32-unknown-emscripten + +use run_make_support::{bare_rustc, rfs, wasmparser}; + +fn main() { + bare_rustc().input("foo.rs").target("wasm32-unknown-emscripten").crate_type("cdylib").run(); + + // Verify the output is a valid wasm file with a dylink.0 section + let file = rfs::read("foo.wasm"); + let mut has_dylink = false; + + for payload in wasmparser::Parser::new(0).parse_all(&file) { + let payload = payload.unwrap(); + if let wasmparser::Payload::CustomSection(s) = payload { + if s.name() == "dylink.0" { + has_dylink = true; + } + } + } + + assert!(has_dylink, "expected dylink.0 section in emscripten cdylib output"); +}