diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 83a4d72e..707ac362 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -142,8 +142,8 @@ jobs: { description: WasmV1, target: wasm32v1-none }, ] feature: [ - { description: no_std, feature: "", build-std: "core,alloc", std: false }, - { feature: --features std, build-std: "panic_abort,std", std: true }, + { description: no_std, feature: "--features wasm_js", build-std: "core,alloc", std: false }, + { feature: "--features wasm_js,std", build-std: "panic_abort,std", std: true }, ] atomic: [ { flags: "" }, diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d0747001..28b91ab9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -237,15 +237,15 @@ jobs: - { description: Web, version: stable, - flags: -Dwarnings --cfg getrandom_backend="wasm_js", - args: --features=std, + flags: '-Dwarnings --cfg getrandom_backend="wasm_js"', + args: '--features=std,wasm_js', } - { description: Web with Atomics, version: nightly, components: rust-src, flags: '-Dwarnings --cfg getrandom_backend="wasm_js" -Ctarget-feature=+atomics,+bulk-memory', - args: '--features=std -Zbuild-std=panic_abort,std', + args: '--features=std,wasm_js -Zbuild-std=panic_abort,std', } steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index f57b91c4..14b37dd9 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -48,11 +48,11 @@ jobs: - name: Web WASM (wasm_js.rs) env: RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" - run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown + run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown --features wasm_js - name: Web WASM with atomics (wasm_js.rs) env: RUSTFLAGS: -Dwarnings --cfg getrandom_backend="wasm_js" -Ctarget-feature=+atomics,+bulk-memory - run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown + run: cargo clippy -Zbuild-std --target wasm32-unknown-unknown --features wasm_js - name: Linux (linux_android.rs) env: RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_getrandom" diff --git a/Cargo.toml b/Cargo.toml index de8866a6..8e6d0e6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,18 @@ repository = "https://github.com/rust-random/getrandom" categories = ["os", "no-std"] exclude = [".*"] +[features] +# Implement std::error::Error for getrandom::Error and +# use std to retrieve OS error descriptions +std = [] +# Unstable feature to support being a libstd dependency +rustc-dep-of-std = ["dep:compiler_builtins", "dep:core"] + +# Optional backend: wasm_js +# This flag enables the backend but does not select it. To use the backend, use +# this flag *and* set getrandom_backend=wasm_js (see README). +wasm_js = ["dep:wasm-bindgen", "dep:js-sys"] + [dependencies] cfg-if = "1" @@ -59,20 +71,13 @@ wasi = { version = "0.13", default-features = false } windows-targets = "0.52" # wasm_js -[target.'cfg(all(getrandom_backend = "wasm_js", target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dependencies] -wasm-bindgen = { version = "0.2.98", default-features = false } -[target.'cfg(all(getrandom_backend = "wasm_js", target_arch = "wasm32", any(target_os = "unknown", target_os = "none"), target_feature = "atomics"))'.dependencies] -js-sys = { version = "0.3.77", default-features = false } -[target.'cfg(all(getrandom_backend = "wasm_js", target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dev-dependencies] +[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dependencies] +wasm-bindgen = { version = "0.2.98", default-features = false, optional = true } +[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"), target_feature = "atomics"))'.dependencies] +js-sys = { version = "0.3.77", default-features = false, optional = true } +[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dev-dependencies] wasm-bindgen-test = "0.3" -[features] -# Implement std::error::Error for getrandom::Error and -# use std to retrieve OS error descriptions -std = [] -# Unstable feature to support being a libstd dependency -rustc-dep-of-std = ["dep:compiler_builtins", "dep:core"] - [lints.rust.unexpected_cfgs] level = "warn" check-cfg = [ diff --git a/README.md b/README.md index ea3b8b01..0007634c 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ of randomness based on their specific needs: | `linux_getrandom` | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call (without `/dev/urandom` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow). | `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`] +| `wasm_js` | Web Browser, Node.js | `wasm32‑unknown‑unknown`, `wasm32v1-none` | [`Crypto.getRandomValues`]. Requires feature `wasm_js` ([see below](#webassembly-support)). | `custom` | All targets | `*` | User-provided custom implementation (see [custom backend]) Opt-in backends can be enabled using the `getrandom_backend` configuration flag. @@ -112,18 +112,19 @@ 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). -Instead, *if the `wasm_js` backend is enabled*, this crate will assume -that you are building for an environment containing JavaScript, and will -call the appropriate Web Crypto methods [described above](#opt-in-backends) using -the [`wasm-bindgen`] toolchain. Both web browser (main window and Web Workers) -and Node.js (v19 or later) environments are supported. +To enable `getrandom`'s functionality on `wasm32-unknown-unknown` using the Web +Crypto methods [described above](#opt-in-backends) via [`wasm-bindgen`], do +*both* of the following: -To enable the `wasm_js` backend, you can add the following lines to your -project's `.cargo/config.toml` file: -```toml -[target.wasm32-unknown-unknown] -rustflags = ['--cfg', 'getrandom_backend="wasm_js"'] -``` +- Use the `wasm_js` feature flag, i.e. + `getrandom = { version = "0.3", features = ["wasm_js"] }`. + On its own, this only makes the backend available. (As a side effect this + will make your `Cargo.lock` significantly larger if you are not already + using [`wasm-bindgen`], but otherwise enabling this feature is harmless.) +- Set `RUSTFLAGS='--cfg getrandom_backend="wasm_js"'` ([see above](#opt-in-backends)). + +This backend supports both web browsers (main window and Web Workers) +and Node.js (v19 or later) environments. ### Custom backend diff --git a/src/backends.rs b/src/backends.rs index 921b7779..1509af11 100644 --- a/src/backends.rs +++ b/src/backends.rs @@ -19,9 +19,19 @@ cfg_if! { } else if #[cfg(getrandom_backend = "rndr")] { mod rndr; pub use rndr::*; - } else if #[cfg(getrandom_backend = "wasm_js")] { - mod wasm_js; - pub use wasm_js::*; + } else if #[cfg(all(getrandom_backend = "wasm_js"))] { + cfg_if! { + if #[cfg(feature = "wasm_js")] { + mod wasm_js; + pub use wasm_js::*; + } else { + compile_error!( + "The \"wasm_js\" backend requires the `wasm_js` feature \ + for `getrandom`. For more information see: \ + https://docs.rs/getrandom/#webassembly-support" + ); + } + } } else if #[cfg(target_os = "espidf")] { mod esp_idf; pub use esp_idf::*; @@ -145,14 +155,14 @@ cfg_if! { } else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] { mod rdrand; pub use rdrand::*; - } else if #[cfg(all( - target_arch = "wasm32", - any(target_os = "unknown", target_os = "none") - ))] { - compile_error!("the wasm32-unknown-unknown targets are not supported \ - by default, you may need to enable the \"wasm_js\" \ - configuration flag. For more information see: \ - https://docs.rs/getrandom/#webassembly-support"); + } else if #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))] { + compile_error!( + "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. \ + For more information see: \ + https://docs.rs/getrandom/#webassembly-support" + ); } else { compile_error!("target is not supported. You may need to define \ a custom backend see: \ diff --git a/src/error.rs b/src/error.rs index e82b5e3a..ccbe7837 100644 --- a/src/error.rs +++ b/src/error.rs @@ -116,7 +116,7 @@ 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(getrandom_backend = "wasm_js")] + #[cfg(all(feature = "wasm_js", getrandom_backend = "wasm_js"))] Error::WEB_CRYPTO => "Web Crypto API is unavailable", #[cfg(target_os = "vxworks")] Error::VXWORKS_RAND_SECURE => "randSecure: VxWorks RNG module is not initialized", diff --git a/tests/mod.rs b/tests/mod.rs index c972e768..9f1e6338 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -1,11 +1,7 @@ use core::mem::MaybeUninit; use getrandom::{fill, fill_uninit}; -#[cfg(all( - getrandom_backend = "wasm_js", - target_arch = "wasm32", - target_os = "unknown" -))] +#[cfg(all(feature = "wasm_js", target_arch = "wasm32", target_os = "unknown"))] use wasm_bindgen_test::wasm_bindgen_test as test; #[test]