Skip to content

Feature flags: wasm_js #574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jan 24, 2025
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: "" },
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
29 changes: 17 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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 = [
Expand Down
25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand Down
32 changes: 21 additions & 11 deletions src/backends.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -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: \
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
6 changes: 1 addition & 5 deletions tests/mod.rs
Original file line number Diff line number Diff line change
@@ -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]
Expand Down