From cf95a4d24b9deade97dd818920ce1d031211d2c8 Mon Sep 17 00:00:00 2001 From: Arjun Ramesh Date: Tue, 2 Jul 2024 18:19:42 -0400 Subject: [PATCH] Target definition for `wasm32-wali-linux-musl` to support the Wasm Linux Interface This commit does not patch libc, stdarch, or cc --- .../rustc_target/src/spec/base/linux_wasm.rs | 159 ++++++++++++++++++ compiler/rustc_target/src/spec/base/mod.rs | 1 + compiler/rustc_target/src/spec/mod.rs | 1 + .../spec/targets/wasm32_wali_linux_musl.rs | 29 ++++ library/core/src/ffi/primitives.rs | 5 +- library/unwind/src/libunwind.rs | 3 + src/bootstrap/configure.py | 5 + src/bootstrap/src/core/build_steps/compile.rs | 48 ++++-- src/bootstrap/src/core/sanity.rs | 1 + src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 1 + .../src/platform-support/wasm32-wali-linux.md | 98 +++++++++++ tests/assembly/targets/targets-elf.rs | 3 + tests/run-make/musl-default-linking/rmake.rs | 15 +- 14 files changed, 351 insertions(+), 19 deletions(-) create mode 100644 compiler/rustc_target/src/spec/base/linux_wasm.rs create mode 100644 compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs create mode 100644 src/doc/rustc/src/platform-support/wasm32-wali-linux.md diff --git a/compiler/rustc_target/src/spec/base/linux_wasm.rs b/compiler/rustc_target/src/spec/base/linux_wasm.rs new file mode 100644 index 0000000000000..a8c137c22a97c --- /dev/null +++ b/compiler/rustc_target/src/spec/base/linux_wasm.rs @@ -0,0 +1,159 @@ +//! This target is a confluence of Linux and Wasm models, inheriting most +//! aspects from their respective base targets + +use crate::spec::{ + Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel, + add_link_args, crt_objects, cvs, +}; + +pub(crate) fn opts() -> TargetOptions { + macro_rules! args { + ($prefix:literal) => { + &[ + // By default LLD only gives us one page of stack (64k) which is a + // little small. Default to a larger stack closer to other PC platforms + // (1MB) and users can always inject their own link-args to override this. + concat!($prefix, "-z"), + concat!($prefix, "stack-size=1048576"), + // By default LLD's memory layout is: + // + // 1. First, a blank page + // 2. Next, all static data + // 3. Finally, the main stack (which grows down) + // + // This has the unfortunate consequence that on stack overflows you + // corrupt static data and can cause some exceedingly weird bugs. To + // help detect this a little sooner we instead request that the stack is + // placed before static data. + // + // This means that we'll generate slightly larger binaries as references + // to static data will take more bytes in the ULEB128 encoding, but + // stack overflow will be guaranteed to trap as it underflows instead of + // corrupting static data. + concat!($prefix, "--stack-first"), + // FIXME we probably shouldn't pass this but instead pass an explicit list + // of symbols we'll allow to be undefined. We don't currently have a + // mechanism of knowing, however, which symbols are intended to be imported + // from the environment and which are intended to be imported from other + // objects linked elsewhere. This is a coarse approximation but is sure to + // hide some bugs and frustrate someone at some point, so we should ideally + // work towards a world where we can explicitly list symbols that are + // supposed to be imported and have all other symbols generate errors if + // they remain undefined. + concat!($prefix, "--allow-undefined"), + // LLD only implements C++-like demangling, which doesn't match our own + // mangling scheme. Tell LLD to not demangle anything and leave it up to + // us to demangle these symbols later. Currently rustc does not perform + // further demangling, but tools like twiggy and wasm-bindgen are intended + // to do so. + concat!($prefix, "--no-demangle"), + ] + }; + } + + let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!("")); + add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")); + + TargetOptions { + is_like_wasm: true, + families: cvs!["wasm", "unix"], + os: "linux".into(), + env: "musl".into(), + + // we allow dynamic linking, but only cdylibs. Basically we allow a + // final library artifact that exports some symbols (a wasm module) but + // we don't allow intermediate `dylib` crate types + dynamic_linking: true, + only_cdylib: true, + + // relatively self-explanatory! + exe_suffix: ".wasm".into(), + dll_prefix: "".into(), + dll_suffix: ".wasm".into(), + eh_frame_header: false, + + max_atomic_width: Some(64), + + // Unwinding doesn't work right now, so the whole target unconditionally + // defaults to panic=abort. Note that this is guaranteed to change in + // the future once unwinding is implemented. Don't rely on this as we're + // basically guaranteed to change it once WebAssembly supports + // exceptions. + panic_strategy: PanicStrategy::Abort, + + // Symbol visibility takes care of this for the WebAssembly. + // Additionally the only known linker, LLD, doesn't support the script + // arguments just yet + limit_rdylib_exports: false, + + // we use the LLD shipped with the Rust toolchain by default + linker: Some("rust-lld".into()), + linker_flavor: LinkerFlavor::WasmLld(Cc::No), + + pre_link_args, + + // FIXME: Figure out cases in which WASM needs to link with a native toolchain. + // + // rust-lang/rust#104137: cannot blindly remove this without putting in + // some other way to compensate for lack of `-nostartfiles` in linker + // invocation. + link_self_contained: LinkSelfContainedDefault::True, + pre_link_objects_self_contained: crt_objects::pre_wasi_self_contained(), + post_link_objects_self_contained: crt_objects::post_wasi_self_contained(), + + // This has no effect in LLVM 8 or prior, but in LLVM 9 and later when + // PIC code is implemented this has quite a drastic effect if it stays + // at the default, `pic`. In an effort to keep wasm binaries as minimal + // as possible we're defaulting to `static` for now, but the hope is + // that eventually we can ship a `pic`-compatible standard library which + // works with `static` as well (or works with some method of generating + // non-relative calls and such later on). + relocation_model: RelocModel::Static, + + // When the atomics feature is activated then these two keys matter, + // otherwise they're basically ignored by the standard library. In this + // mode, however, the `#[thread_local]` attribute works (i.e. + // `has_thread_local`) and we need to get it to work by specifying + // `local-exec` as that's all that's implemented in LLVM today for wasm. + has_thread_local: true, + tls_model: TlsModel::LocalExec, + + // Supporting Linux requires multithreading supported by Wasm's thread + // proposal + singlethread: false, + + // gdb scripts don't work on wasm blobs + emit_debug_gdb_scripts: false, + + // There's more discussion of this at + // https://bugs.llvm.org/show_bug.cgi?id=52442 but the general result is + // that this isn't useful for wasm and has tricky issues with + // representation, so this is disabled. + generate_arange_section: false, + + // Right now this is a bit of a workaround but we're currently saying that + // the target by default has a static crt which we're taking as a signal + // for "use the bundled crt". If that's turned off then the system's crt + // will be used, but this means that default usage of this target doesn't + // need an external compiler but it's still interoperable with an external + // compiler if configured correctly. + crt_static_default: true, + crt_static_respected: true, + + // Allow `+crt-static` to create a "cdylib" output which is just a wasm file + // without a main function. + crt_static_allows_dylibs: true, + + // Wasm start ignores arguments -- relies on API call from interface. + main_needs_argc_argv: false, + + // Wasm toolchains mangle the name of "main" to distinguish between different + // signatures. + entry_name: "__main_void".into(), + + // Wasm Feature flags for supporting Linux + features: "+atomics,+bulk-memory,+mutable-globals,+sign-ext".into(), + + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/base/mod.rs b/compiler/rustc_target/src/spec/base/mod.rs index 6f88be5d37f16..e8fdc87178539 100644 --- a/compiler/rustc_target/src/spec/base/mod.rs +++ b/compiler/rustc_target/src/spec/base/mod.rs @@ -18,6 +18,7 @@ pub(crate) mod linux_gnu; pub(crate) mod linux_musl; pub(crate) mod linux_ohos; pub(crate) mod linux_uclibc; +pub(crate) mod linux_wasm; pub(crate) mod msvc; pub(crate) mod netbsd; pub(crate) mod nto_qnx; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index cc8162a2f27ea..47044ce9321b0 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1925,6 +1925,7 @@ supported_targets! { ("wasm32-wasip1", wasm32_wasip1), ("wasm32-wasip2", wasm32_wasip2), ("wasm32-wasip1-threads", wasm32_wasip1_threads), + ("wasm32-wali-linux-musl", wasm32_wali_linux_musl), ("wasm64-unknown-unknown", wasm64_unknown_unknown), ("thumbv6m-none-eabi", thumbv6m_none_eabi), diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs b/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs new file mode 100644 index 0000000000000..663c17b05e5ef --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/wasm32_wali_linux_musl.rs @@ -0,0 +1,29 @@ +//! The `wasm32-wali-linux-musl` target is a wasm32 target compliant with the +//! [WebAssembly Linux Interface](https://github.com/arjunr2/WALI). + +use crate::spec::{Cc, LinkerFlavor, Target, TargetMetadata, base}; + +pub(crate) fn target() -> Target { + let mut options = base::linux_wasm::opts(); + + options + .add_pre_link_args(LinkerFlavor::WasmLld(Cc::No), &["--export-memory", "--shared-memory"]); + options.add_pre_link_args( + LinkerFlavor::WasmLld(Cc::Yes), + &["--target=wasm32-wasi-threads", "-Wl,--export-memory,", "-Wl,--shared-memory"], + ); + + Target { + llvm_target: "wasm32-wasi".into(), + metadata: TargetMetadata { + description: Some("WebAssembly Linux Interface with musl-libc".into()), + tier: Some(3), + host_tools: Some(false), + std: None, + }, + pointer_width: 32, + data_layout: "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20".into(), + arch: "wasm32".into(), + options, + } +} diff --git a/library/core/src/ffi/primitives.rs b/library/core/src/ffi/primitives.rs index ece3c7538dabb..df9a6bb81c8bc 100644 --- a/library/core/src/ffi/primitives.rs +++ b/library/core/src/ffi/primitives.rs @@ -129,7 +129,10 @@ mod c_char_definition { mod c_long_definition { cfg_if! { - if #[cfg(all(target_pointer_width = "64", not(windows)))] { + if #[cfg(any( + all(target_pointer_width = "64", not(windows)), + // wasm32 Linux ABI uses 64-bit long + all(target_arch = "wasm32", target_os = "linux")))] { pub(super) type c_long = i64; pub(super) type c_ulong = u64; } else { diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 1a640bbde71d7..7b752af96b083 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -81,6 +81,9 @@ pub const unwinder_private_data_size: usize = 35; #[cfg(target_arch = "loongarch64")] pub const unwinder_private_data_size: usize = 2; +#[cfg(target_arch = "wasm32")] +pub const unwinder_private_data_size: usize = 2; + #[repr(C)] pub struct _Unwind_Exception { pub exception_class: _Unwind_Exception_Class, diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index e3f58d97cbc4c..fdf8d1d6d972f 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -269,6 +269,11 @@ def v(*args): "target.loongarch64-unknown-linux-musl.musl-root", "loongarch64-unknown-linux-musl install directory", ) +v( + "musl-root-wali-wasm32", + "target.wasm32-wali-linux-musl.musl-root", + "wasm32-wali-linux-musl install directory", +) v( "qemu-armhf-rootfs", "target.arm-unknown-linux-gnueabihf.qemu-rootfs", diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 7821950073742..5eebba56f8784 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -390,24 +390,38 @@ fn copy_self_contained_objects( let srcdir = builder.musl_libdir(target).unwrap_or_else(|| { panic!("Target {:?} does not have a \"musl-libdir\" key", target.triple) }); - for &obj in &["libc.a", "crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] { - copy_and_stamp( - builder, - &libdir_self_contained, - &srcdir, - obj, - &mut target_deps, - DependencyType::TargetSelfContained, - ); - } - let crt_path = builder.ensure(llvm::CrtBeginEnd { target }); - for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { - let src = crt_path.join(obj); - let target = libdir_self_contained.join(obj); - builder.copy_link(&src, &target); - target_deps.push((target, DependencyType::TargetSelfContained)); + if !target.starts_with("wasm32") { + for &obj in &["libc.a", "crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] { + copy_and_stamp( + builder, + &libdir_self_contained, + &srcdir, + obj, + &mut target_deps, + DependencyType::TargetSelfContained, + ); + } + let crt_path = builder.ensure(llvm::CrtBeginEnd { target }); + for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { + let src = crt_path.join(obj); + let target = libdir_self_contained.join(obj); + builder.copy_link(&src, &target); + target_deps.push((target, DependencyType::TargetSelfContained)); + } + } else { + // For wasm32 targets, we need to copy the libc.a and crt1-command.o files from the + // musl-libdir, but we don't need the other files. + for &obj in &["libc.a", "crt1-command.o"] { + copy_and_stamp( + builder, + &libdir_self_contained, + &srcdir, + obj, + &mut target_deps, + DependencyType::TargetSelfContained, + ); + } } - if !target.starts_with("s390x") { let libunwind_path = copy_llvm_libunwind(builder, target, &libdir_self_contained); target_deps.push((libunwind_path, DependencyType::TargetSelfContained)); diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index fdac7f3cb179d..583b8e1198ae3 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -34,6 +34,7 @@ pub struct Finder { // Targets can be removed from this list once they are present in the stage0 compiler (usually by updating the beta compiler of the bootstrap). const STAGE0_MISSING_TARGETS: &[&str] = &[ // just a dummy comment so the list doesn't get onelined + "wasm32-wali-linux-musl", ]; /// Minimum version threshold for libstdc++ required when using prebuilt LLVM diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 6c7cdec348024..bc1a12fa76013 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -95,6 +95,7 @@ - [wasm32-wasip1](platform-support/wasm32-wasip1.md) - [wasm32-wasip1-threads](platform-support/wasm32-wasip1-threads.md) - [wasm32-wasip2](platform-support/wasm32-wasip2.md) + - [wasm32-wali-linux-musl](platform-support/wasm32-wali-linux.md) - [wasm32-unknown-emscripten](platform-support/wasm32-unknown-emscripten.md) - [wasm32-unknown-unknown](platform-support/wasm32-unknown-unknown.md) - [wasm32v1-none](platform-support/wasm32v1-none.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c4e5c1aac2f5d..c404d116db886 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -405,6 +405,7 @@ target | std | host | notes [`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX [`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | ✓ | | ARMv8M Mainline with NuttX, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly +[`wasm32-wali-linux-musl`](platform-support/wasm32-wali-linux.md) | ? | | WebAssembly with [WALI](https://github.com/arjunr2/WALI) [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator [`x86_64-pc-cygwin`](platform-support/x86_64-pc-cygwin.md) | ? | | 64-bit x86 Cygwin | diff --git a/src/doc/rustc/src/platform-support/wasm32-wali-linux.md b/src/doc/rustc/src/platform-support/wasm32-wali-linux.md new file mode 100644 index 0000000000000..0c46ea2c01dad --- /dev/null +++ b/src/doc/rustc/src/platform-support/wasm32-wali-linux.md @@ -0,0 +1,98 @@ +# `wasm32-wali-linux-*` + +**Tier: 3** + +WebAssembly targets that use the [WebAssembly Linux Interface (WALI)](https://github.com/arjunr2/WALI) with 32-bit memory. The latest status of the WALI specification and support are documented within the repo. + +WALI offers seamless targetability of traditional Linux applications to Wasm by exposing Linux syscalls strategically into the sandbox. Numerous applications and build system work unmodified over WALI, including complex low-level system libraries -- a list of applications are included in the research paper linked in the main repo. + +From the wider Wasm ecosystem perspective, implementing WALI within engines allows layering of high-level security policies (e.g. WASI) above it, arming the latter's implementations with sandboxing and portability. + +## Target maintainers + +- Arjun Ramesh [@arjunr2](https://github.com/arjunr2) + +## Requirements + +### Compilation +This target is cross-compiled and requires an installation of the [WALI compiler/sysroot](https://github.com/arjunr2/WALI). This produces standard `wasm32` binaries with the WALI interface methods as module imports that need to be implemented by a supported engine (see the "Execution" section below). + +`wali` targets *minimally require* the following LLVM feature flags: + +* [Bulk memory] - `+bulk-memory` +* Mutable imported globals - `+mutable-globals` +* [Sign-extending operations] - `+sign-ext` +* [Threading/Atomics] - `+atomics` + +[Bulk memory]: https://github.com/WebAssembly/spec/blob/main/proposals/bulk-memory-operations/Overview.md +[Sign-extending operations]: https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md +[Threading/Atomics]: https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md + +> **Note**: Users can expect that new enabled-by-default Wasm features for LLVM are transitively incorporatable into this target -- see [wasm32-unknown-unknown](wasm32-unknown-unknown.md) for detailed information on WebAssembly features. + + +> **Note**: The WALI ABI is similar to default Clang wasm32 ABIs but *not identical*. The primary difference is 64-bit `long` types as opposed to 32-bit for wasm32. This is required to mantain minimum source code changes for 64-bit host platforms currently supported. This may change in the future as the spec evolves. + +### Execution +Running generated WALI binaries also requires a supported compliant engine implementation -- a working implementation in the [WebAssembly Micro-Runtime (WAMR)](https://github.com/arjunr2/WALI) is included in the repo. + +> **Note**: WALI is still somewhat experimental and bugs may exist in the Rust support, WALI toolchain, or the LLVM compiler. The former can be filed in Rust repos while the latter two in the WALI repo. + +## Building the target + +You can build Rust with support for the target by adding it to the `target` +list in `config.toml`, and pointing to the toolchain artifacts from the previous section ("Requirements->Compilation"). A sample `config.toml` for the `musl` environment will look like this, where `` is the absolute path to the root directory of the [WALI repo](https://github.com/arjunr2/WALI): + +```toml +[build] +target = ["wasm32-wali-linux-musl"] + +[target.wasm32-wali-linux-musl] +musl-root = "/wali-musl/sysroot" +llvm-config = "/llvm-project/build/bin/llvm-config" +cc = "/llvm-project/build/bin/clang-18" +cxx = "/llvm-project/build/bin/clang-18" +ar = "/llvm-project/build/bin/llvm-ar" +ranlib = "/llvm-project/build/bin/llvm-ranlib" +llvm-libunwind = "system" +crt-static = true +``` + +> The `llvm-config` settings are only temporary, and the changes will eventually be upstreamed into LLVM + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +Rust program builds can use this target normally. Currently, linking WALI programs may require pointing the `linker` to the llvm build in the [Cargo config](https://doc.rust-lang.org/cargo/reference/config.html) (until LLVM is upstreamed). A `config.toml` for Cargo will look like the following: + +```toml +[target.wasm32-wali-linux-musl] +linker = "/llvm-project/build/bin/lld" +``` + +Note that the following `cfg` directives are set for `wasm32-wali-linux-*`: + +* `cfg(target_arch = "wasm32")` +* `cfg(target_family = {"wasm", "unix"})` +* `cfg(target_r = "wasm")` +* `cfg(target_os = "linux")` +* `cfg(target_env = *)` + +### Restrictions + +Hardware or platform-specific support, besides `syscall` is mostly unsupported in WALI for ISA portability (these tend to be uncommon). + +## Testing + +Currently testing is not supported for `wali` targets and the Rust project doesn't run any tests for this target. + +However, standard ISA-agnostic tests for Linux should be thereotically reusable for WALI targets and minor changes. Testing integration will be continually incorporated as support evolves. + + +## Cross-compilation toolchains and C code + +Most fully featured C code is compilable with the WALI toolchain -- examples can be seen in the repo. diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs index dc564c60f8073..5a72b57195053 100644 --- a/tests/assembly/targets/targets-elf.rs +++ b/tests/assembly/targets/targets-elf.rs @@ -556,6 +556,9 @@ //@ revisions: wasm32_wasip1_threads //@ [wasm32_wasip1_threads] compile-flags: --target wasm32-wasip1-threads //@ [wasm32_wasip1_threads] needs-llvm-components: webassembly +//@ revisions: wasm32_wali_linux_musl +//@ [wasm32_wali_linux_musl] compile-flags: --target wasm32-wali-linux-musl +//@ [wasm32_wali_linux_musl] needs-llvm-components: webassembly //@ revisions: wasm32_wasip2 //@ [wasm32_wasip2] compile-flags: --target wasm32-wasip2 //@ [wasm32_wasip2] needs-llvm-components: webassembly diff --git a/tests/run-make/musl-default-linking/rmake.rs b/tests/run-make/musl-default-linking/rmake.rs index d203595a44741..017444cfcddcb 100644 --- a/tests/run-make/musl-default-linking/rmake.rs +++ b/tests/run-make/musl-default-linking/rmake.rs @@ -45,8 +45,21 @@ fn main() { let target_spec: serde_json::Value = serde_json::from_str(&target_spec_json).expect("failed to parse target-spec-json"); - let default = &target_spec["crt-static-default"]; + let target_families = &target_spec["target-family"]; + // WebAssembly doesn't support dynamic linking yet; all musl targets + // need to be statically linked. + if target_families + .as_array() + .expect("target-family wasn't an array") + .iter() + .filter_map(|x| x.as_str()) + .any(|family| family == "wasm") + { + continue; + } + + let default = &target_spec["crt-static-default"]; // If the value is `null`, then the default to dynamically link from // musl_base was not overridden. if default.is_null() {