diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dfdcca7d..9b127f47 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -165,8 +165,6 @@ jobs: web: name: ${{ matrix.target.description }} ${{ matrix.feature.description }} ${{ matrix.atomic.description }} runs-on: ubuntu-24.04 - env: - RUSTFLAGS: --cfg getrandom_backend="wasm_js" ${{ matrix.atomic.flags }} strategy: fail-fast: false matrix: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8d1d0587..40009408 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -275,14 +275,13 @@ jobs: - { description: Web, version: stable, - flags: '-Dwarnings --cfg getrandom_backend="wasm_js"', args: '--features=std,sys_rng,wasm_js', } - { description: Web with Atomics, version: nightly, components: rust-src, - flags: '-Dwarnings --cfg getrandom_backend="wasm_js" -Ctarget-feature=+atomics,+bulk-memory', + flags: '-Dwarnings -Ctarget-feature=+atomics,+bulk-memory', args: '--features=std,sys_rng,wasm_js -Zbuild-std=panic_abort,std', } steps: diff --git a/Cargo.toml b/Cargo.toml index 3037a445..d5920d15 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,10 +20,16 @@ features = ["std", "sys_rng"] std = [] # Optional backend: wasm_js +# # This flag enables the wasm_js backend and uses it by default on wasm32 where # the target_os is unknown. The getrandom_backend cfg may override this. -# WARNING: It is highly recommended to enable this feature only for binary crates and tests, -# i.e. avoid unconditionally enabling it in library crates. +# +# WARNING: This feature SHOULD be enabled ONLY for binary crates and tests. In other words, +# avoid enabling it in library crates whether unconditionally or gated on a crate feature. +# By not following this recommendation you may break builds for users targeting non-Web WASM. +# +# The only exception to this rule: if your crate already unconditionally depends on `wasm-bindgen` +# or `js-sys` on "unknown" WASM targets then it's acceptable to enable this feature unconditionally. wasm_js = ["dep:wasm-bindgen", "dep:js-sys"] # Provide SysRng over rand_core @@ -84,7 +90,7 @@ wasm-bindgen-test = "0.3" [lints.rust.unexpected_cfgs] level = "warn" check-cfg = [ - 'cfg(getrandom_backend, values("custom", "efi_rng", "rdrand", "rndr", "linux_getrandom", "linux_raw", "wasm_js", "windows_legacy", "unsupported"))', + 'cfg(getrandom_backend, values("custom", "efi_rng", "rdrand", "rndr", "linux_getrandom", "linux_raw", "windows_legacy", "unsupported"))', 'cfg(getrandom_msan)', 'cfg(getrandom_test_linux_fallback)', 'cfg(getrandom_test_linux_without_fallback)', diff --git a/README.md b/README.md index 297b5542..c95a0572 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,28 @@ fn get_random_u128() -> Result { Pull Requests that add support for new targets to `getrandom` are always welcome. +### WebAssembly support + +This crate fully supports the [WASI] and [Emscripten] targets. However, +the `wasm32-unknown-unknown` target (i.e. the target used by `wasm-pack`) +is not automatically supported since, from the target name alone, we cannot deduce +which JavaScript interface should be used (or if JavaScript is available at all). + +We do not include support for this target in the default configuration because our JS backend +(supporting web browsers, web workers and Node.js v19 or later) requires [`wasm-bindgen`], +**bloating `Cargo.lock`** and **potentially breaking builds** on non-web WASM platforms. + +To enable `getrandom`'s functionality on `wasm32-unknown-unknown` using +[`Crypto.getRandomValues`] via [`wasm-bindgen`], enable the `wasm_js` crate feature. + +WARNING: This feature SHOULD be enabled ONLY for binary crates and tests. In other words, +avoid enabling it in library crates whether unconditionally or gated on a crate feature. +By not following this recommendation you may break builds for users targeting non-Web WASM +even when a different backend is selected via `getrandom_backend`. + +The only exception to this rule: if your crate already unconditionally depends on `wasm-bindgen` +or `js-sys` on "unknown" WASM targets then it's acceptable to enable this feature unconditionally. + ### Opt-in backends `getrandom` also provides optional (opt-in) backends, which allow users to customize the source @@ -84,7 +106,6 @@ of randomness based on their specific needs: | `linux_raw` | Linux, Android | `*‑linux‑*` | Same as `linux_getrandom`, but uses raw `asm!`-based syscalls instead of `libc`. | `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction | `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register -| `wasm_js` | Web Browser, Node.js | `wasm32‑unknown‑unknown`, `wasm32v1-none` | [`Crypto.getRandomValues`]. Enabled by the `wasm_js` feature ([see below](#webassembly-support)). | `efi_rng` | UEFI | `*-unknown‑uefi` | [`EFI_RNG_PROTOCOL`] with `EFI_RNG_ALGORITHM_RAW` (requires `std` and Nightly compiler) | `windows_legacy` | Windows | `*-windows-*` | [`RtlGenRandom`] | `custom` | All targets | `*` | User-provided custom implementation (see [custom backend]) @@ -94,8 +115,8 @@ Opt-in backends can be enabled using the `getrandom_backend` configuration flag. The flag can be set either by specifying the `rustflags` field in [`.cargo/config.toml`]: ```toml # It's recommended to set the flag on a per-target basis: -[target.wasm32-unknown-unknown] -rustflags = ['--cfg', 'getrandom_backend="wasm_js"'] +[target.'cfg(target_os = "linux")'] +rustflags = ['--cfg', 'getrandom_backend="linux_getrandom"'] ``` Or by using the `RUSTFLAGS` environment variable: @@ -124,29 +145,6 @@ Note that the raw syscall backend may be slower than backends based on `libc::ge e.g. it does not implement vDSO optimizations and on `x86` it uses the infamously slow `int 0x80` instruction to perform syscall. -### WebAssembly support - -This crate fully supports the [WASI] and [Emscripten] targets. However, -the `wasm32-unknown-unknown` target (i.e. the target used by `wasm-pack`) -is not automatically supported since, from the target name alone, we cannot deduce -which JavaScript interface should be used (or if JavaScript is available at all). - -We do not include support for this target in the default configuration because -our JS backend (supporting web browsers, web workers and Node.js v19 or later) -requires [`wasm-bindgen`], **bloating `Cargo.lock`** and -**potentially breaking builds** on non-web WASM platforms. - -To enable `getrandom`'s functionality on `wasm32-unknown-unknown` using the Web -Crypto methods [described above][opt-in] via [`wasm-bindgen`], enable the -`wasm_js` feature flag. Setting `RUSTFLAGS='--cfg getrandom_backend="wasm_js"'` -is allowed but is no longer required and does nothing (it was required in a -prior version of this crate). - -WARNING: enabling the `wasm_js` feature will bloat `Cargo.lock` on all platforms -(where [`wasm-bindgen`] is not an existing dependency) and is known to cause -build issues on some non-web WASM platforms, even when a different backend is -selected via `getrandom_backend`. - ### Custom backend If this crate does not support your target out of the box or you have to use diff --git a/src/backends.rs b/src/backends.rs index e572b8b5..2d21e674 100644 --- a/src/backends.rs +++ b/src/backends.rs @@ -29,19 +29,6 @@ cfg_if! { } else if #[cfg(getrandom_backend = "windows_legacy")] { mod windows_legacy; pub use windows_legacy::*; - } else if #[cfg(getrandom_backend = "wasm_js")] { - cfg_if! { - if #[cfg(feature = "wasm_js")] { - mod wasm_js; - pub use wasm_js::*; - } else { - compile_error!(concat!( - "The \"wasm_js\" backend requires the `wasm_js` feature \ - for `getrandom`. For more information see: \ - https://docs.rs/getrandom/", env!("CARGO_PKG_VERSION"), "/#webassembly-support" - )); - } - } } else if #[cfg(getrandom_backend = "unsupported")] { mod unsupported; pub use unsupported::*; @@ -187,8 +174,7 @@ cfg_if! { } else { compile_error!(concat!( "The wasm32-unknown-unknown targets are not supported by default; \ - you may need to enable the \"wasm_js\" configuration flag. Note \ - that enabling the `wasm_js` feature flag alone is insufficient. \ + you may need to enable the \"wasm_js\" crate feature. \ For more information see: \ https://docs.rs/getrandom/", env!("CARGO_PKG_VERSION"), "/#webassembly-support" )); diff --git a/src/error.rs b/src/error.rs index 7708959c..73a82743 100644 --- a/src/error.rs +++ b/src/error.rs @@ -177,7 +177,11 @@ impl Error { Error::IOS_RANDOM_GEN => "SecRandomCopyBytes: iOS Security framework failure", #[cfg(all(windows, target_vendor = "win7"))] Error::WINDOWS_RTL_GEN_RANDOM => "RtlGenRandom: Windows system function failure", - #[cfg(all(feature = "wasm_js", getrandom_backend = "wasm_js"))] + #[cfg(all( + feature = "wasm_js", + target_arch = "wasm32", + any(target_os = "unknown", target_os = "none") + ))] Error::WEB_CRYPTO => "Web Crypto API is unavailable", #[cfg(target_os = "vxworks")] Error::VXWORKS_RAND_SECURE => "randSecure: VxWorks RNG module is not initialized",