diff --git a/examples/rust-wasm-cross/.test.js b/examples/rust-wasm-cross/.test.js new file mode 100644 index 000000000..1d5c2f1ea --- /dev/null +++ b/examples/rust-wasm-cross/.test.js @@ -0,0 +1 @@ +import("./app/pkg/app.js").then((app) => app.main()); diff --git a/examples/rust-wasm-cross/.test.sh b/examples/rust-wasm-cross/.test.sh new file mode 100755 index 000000000..cfe2f4e0a --- /dev/null +++ b/examples/rust-wasm-cross/.test.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -ex +cargo --version +rustc --version + +if [[ "$(uname)" == "Darwin" ]]; then + echo "$RUSTFLAGS" | grep -- "-L framework=$DEVENV_PROFILE/Library/Frameworks" + echo "$RUSTDOCFLAGS" | grep -- "-L framework=$DEVENV_PROFILE/Library/Frameworks" + echo "$CFLAGS" | grep -- "-iframework $DEVENV_PROFILE/Library/Frameworks" +fi + +[[ "$CARGO_INSTALL_ROOT" == "$DEVENV_STATE/cargo-install" ]] +echo "$PATH" | grep -- "$CARGO_INSTALL_ROOT/bin" + +wasm-pack build ./app --target nodejs + +node .test.js diff --git a/examples/rust-wasm-cross/app/Cargo.lock b/examples/rust-wasm-cross/app/Cargo.lock new file mode 100644 index 000000000..a546e9e9f --- /dev/null +++ b/examples/rust-wasm-cross/app/Cargo.lock @@ -0,0 +1,123 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "app" +version = "0.1.0" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" diff --git a/examples/rust-wasm-cross/app/Cargo.toml b/examples/rust-wasm-cross/app/Cargo.toml new file mode 100644 index 000000000..ad5d442c3 --- /dev/null +++ b/examples/rust-wasm-cross/app/Cargo.toml @@ -0,0 +1,18 @@ +[lib] +crate-type = ["cdylib", "rlib"] + +[package] +name = "app" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +wasm-bindgen = "0.2.84" + +[profile.release] +# Tell `rustc` to optimize for small code size. +opt-level = "s" + +[workspace] diff --git a/examples/rust-wasm-cross/app/src/lib.rs b/examples/rust-wasm-cross/app/src/lib.rs new file mode 100644 index 000000000..944625b31 --- /dev/null +++ b/examples/rust-wasm-cross/app/src/lib.rs @@ -0,0 +1,36 @@ +use wasm_bindgen::prelude::*; + +// First up let's take a look of binding `console.log` manually, without the +// help of `web_sys`. Here we're writing the `#[wasm_bindgen]` annotations +// manually ourselves, and the correctness of our program relies on the +// correctness of these annotations! + +#[wasm_bindgen] +extern "C" { + // Use `js_namespace` here to bind `console.log(..)` instead of just + // `log(..)` + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); + + // The `console.log` is quite polymorphic, so we can bind it with multiple + // signatures. Note that we need to use `js_name` to ensure we always call + // `log` in JS. + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn log_u32(a: u32); + + // Multiple arguments too! + #[wasm_bindgen(js_namespace = console, js_name = log)] + fn log_many(a: &str, b: &str); +} + +macro_rules! console_log { + // Note that this is using the `log` function imported above during + // `bare_bones` + ($($t:tt)*) => (log(&format_args!($($t)*).to_string())) +} + +// Called by our JS entry point to run the example. +#[wasm_bindgen] +pub fn main() { + console_log!("Hello, from devenv!"); +} diff --git a/examples/rust-wasm-cross/devenv.nix b/examples/rust-wasm-cross/devenv.nix new file mode 100644 index 000000000..4d3780957 --- /dev/null +++ b/examples/rust-wasm-cross/devenv.nix @@ -0,0 +1,26 @@ +{ pkgs, lib, ... }: + +{ + languages.rust = { + enable = true; + # https://devenv.sh/reference/options/#languagesrustchannel + channel = "nightly"; + + targets = [ "wasm32-unknown-unknown" ]; + + components = [ "rustc" "cargo" "clippy" "rustfmt" "rust-analyzer" "rust-std" ]; + }; + + # These break us + # pre-commit.hooks = { + # rustfmt.enable = true; + # clippy.enable = true; + # }; + + packages = [ + pkgs.wasm-pack + pkgs.nodejs + ] ++ lib.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk; [ + frameworks.Security + ]); +} diff --git a/examples/rust-wasm-cross/devenv.yaml b/examples/rust-wasm-cross/devenv.yaml new file mode 100644 index 000000000..aecda8b76 --- /dev/null +++ b/examples/rust-wasm-cross/devenv.yaml @@ -0,0 +1,6 @@ +inputs: + fenix: + url: github:nix-community/fenix + inputs: + nixpkgs: + follows: nixpkgs diff --git a/src/modules/languages/rust.nix b/src/modules/languages/rust.nix index 4499f5217..c5a8af43a 100644 --- a/src/modules/languages/rust.nix +++ b/src/modules/languages/rust.nix @@ -29,6 +29,16 @@ in ''; }; + targets = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + defaultText = lib.literalExpression ''[ ]''; + description = '' + List of extra [targets](https://github.com/nix-community/fenix#supported-platforms-and-targets) + to install. Defaults to only the native target. + ''; + }; + channel = lib.mkOption { type = lib.types.enum [ "nixpkgs" "stable" "beta" "nightly" ]; default = "nixpkgs"; @@ -76,7 +86,10 @@ in export PATH="$PATH:$CARGO_INSTALL_ROOT/bin" ''; - packages = (builtins.map (c: cfg.toolchain.${c} or (throw "toolchain.${c}")) cfg.components) + packages = + # If there are targets we want to add the whole toolchain instead + # TODO: It might always be fine to add the whole toolchain when not using `nixpkgs` + lib.optionals (cfg.targets == [ ]) (builtins.map (c: cfg.toolchain.${c} or (throw "toolchain.${c}")) cfg.components) ++ lib.optional pkgs.stdenv.isDarwin pkgs.libiconv; # enable compiler tooling by default to expose things like cc @@ -108,10 +121,33 @@ in let toolchain = if cfg.channel == "nightly" - then rustPackages.latest - else rustPackages.${cfg.channel}; + then + rustPackages.latest + else + rustPackages.${cfg.channel} + ; in (builtins.mapAttrs (_: pkgs.lib.mkDefault) toolchain); + + packages = [ + (rustPackages.combine + ( + (map (c: config.languages.rust.toolchain.${c}) cfg.components) ++ + (map + (t: + let + target_toolchain = + if cfg.channel == "nightly" + then + rustPackages.targets.${t}.latest + else + rustPackages.targets.${t}.${cfg.channel} + ; + in + target_toolchain.rust-std) + cfg.targets) + )) + ]; } )) ];