about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2024-08-01 11:59:47 -0700
committerAlex Crichton <alex@alexcrichton.com>2024-08-01 11:59:47 -0700
commite65a48efd9b711281c70667c5392de70a9e1f7c3 (patch)
treee9024523418df2bc4317b853139c6daa9870b89b
parente60ebb2f2c1facba87e7971798f3cbdfd309cd23 (diff)
downloadrust-e65a48efd9b711281c70667c5392de70a9e1f7c3.tar.gz
rust-e65a48efd9b711281c70667c5392de70a9e1f7c3.zip
Document WebAssembly target feature expectations
This commit is a result of the discussion on #128475 and incorporates
parts of #109807 as well. This is all done as a new page of
documentation for the `wasm32-unknown-unknown` target which previously
did not exist. This new page goes into details about the preexisting
target and additionally documents the expectations for WebAssembly
features and code generation.

The tl;dr is that LLVM will enable features over time after most engines
have had support for awhile. Compiling without features requires
`-Ctarget-cpu=mvp` to rustc plus `-Zbuild-std` to Cargo.

Closes #109807
Closes #128475
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md154
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-wasip1.md7
-rw-r--r--src/doc/rustc/src/platform-support/wasm32-wasip2.md7
4 files changed, 169 insertions, 1 deletions
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index cbb338f4811..1fb7d2d1503 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -190,7 +190,7 @@ target | std | notes
 [`thumbv8m.main-none-eabi`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline
 [`thumbv8m.main-none-eabihf`](platform-support/thumbv8m.main-none-eabi.md) | * | Bare Armv8-M Mainline, hardfloat
 `wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten
-`wasm32-unknown-unknown` | ✓ | WebAssembly
+[`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly
 `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename])
 [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI
 [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads
diff --git a/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md
new file mode 100644
index 00000000000..03126eaa50c
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/wasm32-unknown-unknown.md
@@ -0,0 +1,154 @@
+# `wasm32-unknown-unknown`
+
+**Tier: 2**
+
+The `wasm32-unknown-unknown` target is a WebAssembly compilation target which
+does not import any functions from the host for the standard library. This is
+the "minimal" WebAssembly in the sense of making the fewest assumptions about
+the host environment. This target is often used when compiling to the web or
+JavaScript environments as there is not standard for what functions can be
+imported on the web. This target can also be useful for creating minimal or
+bare-bones WebAssembly binaries.
+
+The `wasm32-unknown-unknown` target has support for the Rust standard library
+but many parts of the standard library do not work and return errors. For
+example `println!` does nothing, `std::fs` always return errors, and
+`std::thread::spawn` will panic. There is no means by which this can be
+overridden. For a WebAssembly target that more fully supports the standard
+library see the [`wasm32-wasip1`](./wasm32-wasip1.md) or
+[`wasm32-wasip2`](./wasm32-wasip2.md) targets.
+
+The `wasm32-unknown-unknown` target has full support for the `core` and `alloc`
+crates. It additionally supports the `HashMap` type in the `std` crate, although
+hash maps are not randomized like they are on other platforms.
+
+One existing user of this target (please feel free to edit and expand this list
+too) is the [`wasm-bindgen` project](https://github.com/rustwasm/wasm-bindgen)
+which facilitates Rust code interoperating with JavaScript code. Note, though,
+that not all uses of `wasm32-unknown-unknown` are using JavaScript and the web.
+
+## Target maintainers
+
+When this target was added to the compiler platform-specific documentation here
+was not maintained at that time. This means that the list below is not
+exhaustive and there are more interested parties in this target. That being
+said since when this document was last updated those interested in maintaining
+this target are:
+
+- Alex Crichton, https://github.com/alexcrichton
+
+## Requirements
+
+This target is cross-compiled. The target includes support for `std` itself,
+but as mentioned above many pieces of functionality that require an operating
+system do not work and will return errors.
+
+This target currently has no equivalent in C/C++. There is no C/C++ toolchain
+for this target. While interop is theoretically possible it's recommended to
+instead use one of:
+
+* `wasm32-unknown-emscripten` - for web-based use cases the Emscripten
+  toolchain is typically chosen for running C/C++.
+* [`wasm32-wasip1`](./wasm32-wasip1.md) - the wasi-sdk toolchain is used to
+  compile C/C++ on this target and can interop with Rust code. WASI works on
+  the web so far as there's no blocker, but an implementation of WASI APIs
+  must be either chosen or reimplemented.
+
+This target has no build requirements beyond what's in-tree in the Rust
+repository. Linking binaries requires LLD to be enabled for the `wasm-ld`
+driver. This target uses the `dlmalloc` crate as the default global allocator.
+
+## Building the target
+
+Building this target can be done by:
+
+* Configure the `wasm32-unknown-unknown` target to get built.
+* Configure LLD to be built.
+* Ensure the `WebAssembly` target backend is not disabled in LLVM.
+
+These are all controlled through `config.toml` options. It should be possible
+to build this target on any platform.
+
+## Building Rust programs
+
+Rust programs can be compiled by adding this target via rustup:
+
+```sh
+$ rustup target add wasm32-unknown-unknown
+```
+
+and then compiling with the target:
+
+```sh
+$ rustc foo.rs --target wasm32-unknown-unknown
+$ file foo.wasm
+```
+
+## Cross-compilation
+
+This target can be cross-compiled from any hosts.
+
+## Testing
+
+This target is not tested in CI for the rust-lang/rust repository. Many tests
+must be disabled to run on this target and failures are non-obvious because
+println doesn't work in the standard library. It's recommended to test the
+`wasm32-wasip1` target instead for WebAssembly compatibility.
+
+## Conditionally compiling code
+
+It's recommended to conditionally compile code for this target with:
+
+```text
+#[cfg(all(target_family = "wasm", target_os = "unknown"))]
+```
+
+Note that there is no way to tell via `#[cfg]` whether code will be running on
+the web or not.
+
+## Enabled WebAssembly features
+
+WebAssembly is an evolving standard which adds new features such as new
+instructions over time. This target's default set of supported WebAssembly
+features will additionally change over time. The `wasm32-unknown-unknown` target
+inherits the default settings of LLVM which typically matches the default
+settings of Emscripten as well.
+
+Changes to WebAssembly go through a [proposals process][proposals] but reaching
+the final stage (stage 5) does not automatically mean that the feature will be
+enabled in LLVM and Rust by default. At this time the general guidance is that
+features must be present in most engines for a "good chunk of time" before
+they're enabled in LLVM by default. There is currently not exact number of
+months or engines that are required to enable features by default.
+
+[proposals]: https://github.com/WebAssembly/proposals
+
+If you're compiling WebAssembly code for an engine that does not support a
+feature in LLVM's default feature set then the feature must be disabled at
+compile time. Note, though, that enabled features may be used in the standard
+library or precompiled libraries shipped via rustup. This means that not only
+does your own code need to be compiled with the correct set of flags but the
+Rust standard library additionally must be recompiled.
+
+Compiling all code for the initial release of WebAssembly looks like:
+
+```sh
+$ export RUSTFLAG=-Ctarget-cpu=mvp
+$ cargo +nightly build -Zbuild-std=panic_abort,std --target wasm32-unknown-unknown
+```
+
+Here the `mvp` "cpu" is a placeholder in LLVM for disabling all supported
+features by default. Cargo's `-Zbuild-std` feature, a Nightly Rust feature, is
+then used to recompile the standard library in addition to your own code. This
+will produce a binary that uses only the original WebAssembly features by
+default and no proposals since its inception.
+
+To enable individual features it can be done with `-Ctarget-feature=+foo`.
+Available features can be found through:
+
+```sh
+$ rustc -Ctarget-feature=help --target wasm32-unknown-unknown
+```
+
+You'll need to consult your WebAssembly engine's documentation to learn more
+about the supported WebAssembly features the engine has.
diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip1.md b/src/doc/rustc/src/platform-support/wasm32-wasip1.md
index fb70bbdc2b4..7a7cac9aeeb 100644
--- a/src/doc/rustc/src/platform-support/wasm32-wasip1.md
+++ b/src/doc/rustc/src/platform-support/wasm32-wasip1.md
@@ -132,3 +132,10 @@ It's recommended to conditionally compile code for this target with:
 
 Note that the `target_env = "p1"` condition first appeared in Rust 1.80. Prior
 to Rust 1.80 the `target_env` condition was not set.
+
+## Enabled WebAssembly features
+
+The default set of WebAssembly features enabled for compilation is currently the
+same across all WebAssembly targets. For more information on WebAssembly
+features see the documentation for
+[`wasm32-unknown-unknokwn`](./wasm32-unknown-unknown.md)
diff --git a/src/doc/rustc/src/platform-support/wasm32-wasip2.md b/src/doc/rustc/src/platform-support/wasm32-wasip2.md
index 1e53fbc178e..e4ef65bcfec 100644
--- a/src/doc/rustc/src/platform-support/wasm32-wasip2.md
+++ b/src/doc/rustc/src/platform-support/wasm32-wasip2.md
@@ -61,3 +61,10 @@ It's recommended to conditionally compile code for this target with:
 ```text
 #[cfg(all(target_os = "wasi", target_env = "p2"))]
 ```
+
+## Enabled WebAssembly features
+
+The default set of WebAssembly features enabled for compilation is currently the
+same across all WebAssembly targets. For more information on WebAssembly
+features see the documentation for
+[`wasm32-unknown-unknokwn`](./wasm32-unknown-unknown.md)