about summary refs log tree commit diff
path: root/compiler/rustc_target/src/spec
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2024-01-24 15:43:12 +0100
committerGitHub <noreply@github.com>2024-01-24 15:43:12 +0100
commite0a4f43903ac155e7a14bb947f26f0b4f04e587d (patch)
tree5f13d003b5d04d5c6fa614ecd4bdb431fbec1881 /compiler/rustc_target/src/spec
parent5a38754d23ef2d5b6ce16dcafdb9ac434726c7d9 (diff)
parent31ecf341250a889ac1154b2cbe3f0b97f9d008c1 (diff)
downloadrust-e0a4f43903ac155e7a14bb947f26f0b4f04e587d.tar.gz
rust-e0a4f43903ac155e7a14bb947f26f0b4f04e587d.zip
Rollup merge of #119616 - rylev:wasm32-wasi-preview2, r=petrochenkov,m-ou-se
Add a new `wasm32-wasi-preview2` target

This is the initial implementation of the MCP https://github.com/rust-lang/compiler-team/issues/694 creating a new tier 3 target `wasm32-wasi-preview2`. That MCP has been seconded and will most likely be approved in a little over a week from now. For more information on the need for this target, please read the [MCP](https://github.com/rust-lang/compiler-team/issues/694).

There is one aspect of this PR that will become insta-stable once these changes reach a stable compiler:
* A new `target_family` named `wasi` is introduced. This target family incorporates all wasi targets including `wasm32-wasi` and its derivative `wasm32-wasi-preview1-threads`. The difference between `target_family = wasi` and `target_os = wasi` will become much clearer when `wasm32-wasi` is renamed to `wasm32-wasi-preview1` and the `target_os` becomes `wasm32-wasi-preview1`. You can read about this target rename in [this MCP](https://github.com/rust-lang/compiler-team/issues/695) which has also been seconded and will hopefully be officially approved soon.

Additional technical details include:
* Both `std::sys::wasi_preview2` and `std::os::wasi_preview2` have been created and mostly use `#[path]` annotations on their submodules to reach into the existing `wasi` (soon to be `wasi_preview1`) modules. Over time the differences between `wasi_preview1` and `wasi_preview2` will grow and most like all `#[path]` based module aliases will fall away.
* Building `wasi-preview2` relies on a [`wasi-sdk`](https://github.com/WebAssembly/wasi-sdk) in the same way that `wasi-preview1` does (one must include a `wasi-root` path in the `Config.toml` pointing to sysroot included in the wasi-sdk). The target should build against [wasi-sdk v21](https://github.com/WebAssembly/wasi-sdk/releases/tag/wasi-sdk-21) without modifications. However, the wasi-sdk itself is growing [preview2 support](https://github.com/WebAssembly/wasi-sdk/pull/370) so this might shift rapidly. We will be following along quickly to make sure that building the target remains possible as the wasi-sdk changes.
* This requires a [patch to libc](https://github.com/rylev/rust-libc/tree/wasm32-wasi-preview2) that we'll need to land in conjunction with this change. Until that patch lands the target won't actually build.
Diffstat (limited to 'compiler/rustc_target/src/spec')
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/wasm32_wasi_preview2.rs64
3 files changed, 67 insertions, 1 deletions
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 884bd23e8cc..ead3be7fd52 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1574,6 +1574,7 @@ supported_targets! {
     ("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
     ("wasm32-unknown-unknown", wasm32_unknown_unknown),
     ("wasm32-wasi", wasm32_wasi),
+    ("wasm32-wasi-preview2", wasm32_wasi_preview2),
     ("wasm32-wasi-preview1-threads", wasm32_wasi_preview1_threads),
     ("wasm64-unknown-unknown", wasm64_unknown_unknown),
 
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs
index 28ea4cc9ece..389c67f8ae9 100644
--- a/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs
+++ b/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview1_threads.rs
@@ -72,11 +72,12 @@
 //! best we can with this target. Don't start relying on too much here unless
 //! you know what you're getting in to!
 
-use crate::spec::{base, crt_objects, Cc, LinkSelfContainedDefault, LinkerFlavor, Target};
+use crate::spec::{base, crt_objects, cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, Target};
 
 pub fn target() -> Target {
     let mut options = base::wasm::options();
 
+    options.families = cvs!["wasm", "wasi"];
     options.os = "wasi".into();
 
     options.add_pre_link_args(
diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview2.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview2.rs
new file mode 100644
index 00000000000..fc44e5d4cbc
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/wasm32_wasi_preview2.rs
@@ -0,0 +1,64 @@
+//! The `wasm32-wasi-preview2` target is the next evolution of the
+//! wasm32-wasi target. While the wasi specification is still under
+//! active development, the {review 2 iteration is considered an "island
+//! of stability" that should allow users to rely on it indefinitely.
+//!
+//! The `wasi` target is a proposal to define a standardized set of WebAssembly
+//! component imports that allow it to interoperate with the host system in a
+//! standardized way. This set of imports is intended to empower WebAssembly
+//! binaries with host capabilities such as filesystem access, network access, etc.
+//!
+//! Wasi Preview 2 relies on the WebAssembly component model which is an extension of
+//! the core WebAssembly specification which allows interoperability between WebAssembly
+//! modules (known as "components") through high-level, shared-nothing APIs instead of the
+//! low-level, shared-everything linear memory model of the core WebAssembly specification.
+//!
+//! You can see more about wasi at <https://wasi.dev> and the component model at
+//! <https://github.com/WebAssembly/component-model>.
+
+use crate::spec::crt_objects;
+use crate::spec::LinkSelfContainedDefault;
+use crate::spec::{base, Target};
+
+pub fn target() -> Target {
+    let mut options = base::wasm::options();
+
+    options.os = "wasi".into();
+    options.env = "preview2".into();
+    options.linker = Some("wasm-component-ld".into());
+
+    options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
+    options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained();
+
+    // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
+    options.link_self_contained = LinkSelfContainedDefault::True;
+
+    // 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.
+    options.crt_static_default = true;
+    options.crt_static_respected = true;
+
+    // Allow `+crt-static` to create a "cdylib" output which is just a wasm file
+    // without a main function.
+    options.crt_static_allows_dylibs = true;
+
+    // WASI's `sys::args::init` function ignores its arguments; instead,
+    // `args::args()` makes the WASI API calls itself.
+    options.main_needs_argc_argv = false;
+
+    // And, WASI mangles the name of "main" to distinguish between different
+    // signatures.
+    options.entry_name = "__main_void".into();
+
+    Target {
+        llvm_target: "wasm32-unknown-unknown".into(),
+        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,
+    }
+}