From f67a943e45a4de9531d194597b3bd96b28122c02 Mon Sep 17 00:00:00 2001 From: Anthony Dodd Date: Thu, 25 Mar 2021 22:23:51 -0500 Subject: [PATCH] Add rust link opts keep-debug & no-demangle. These new data-* options for influence the way that Trunk invokes wasm-bindgen, invoking the --keep-debug & --no-demangle options respectively. closes #135 --- README.md | 2 + site/content/assets.md | 2 + src/pipelines/rust_app.rs | 143 +++++++++++++++++++++----------------- 3 files changed, 84 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index e9b79263..d432d44c 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,8 @@ Currently supported asset types: - `href`: (optional) the path to the `Cargo.toml` of the Rust project. If a directory is specified, then Trunk will look for the `Cargo.toml` in the given directory. If no value is specified, then Trunk will look for a `Cargo.toml` in the parent directory of the source HTML file. - `data-bin`: (optional) the name of the binary to compile and use as the main WASM application. If the Cargo project has multiple binaries, this value will be required for proper functionality. - `data-wasm-opt`: (optional) run wasm-opt with the set optimization level. wasm-opt is **turned off by default** but that may change in the future. The possible values are `0`, `1`, `2`, `3`, `4`, `s`, `z` or an _empty value_ for wasm-opt's default. Set this option to `0` to disable wasm-opt explicitly. The values `1-4` are increasingly stronger optimization levels for speed. `s` and `z` (z means more optimization) optimize for binary size instead. + - `data-keep-debug`: (optional) instruct `wasm-bindgen` to preserve debug info in the final WASM output, even for `--release` mode. + - `data-no-demangle`: (optional) instruct `wasm-bindgen` to not demangle Rust symbol names. - ✅ `sass`, `scss`: Trunk ships with a [built-in sass/scss compiler](https://github.com/compass-rs/sass-rs). Just link to your sass files from your source HTML, and Trunk will handle the rest. This content is hashed for cache control. The `href` attribute must be included in the link pointing to the sass/scss file to be processed. - ✅ `css`: Trunk will copy linked css files found in the source HTML without content modification. This content is hashed for cache control. The `href` attribute must be included in the link pointing to the css file to be processed. - In the future, Trunk will resolve local `@imports`, will handle minification (see [trunk#7](https://github.com/thedodd/trunk/issues/3)), and we may even look into a pattern where any CSS found in the source tree will be bundled, which would enable a nice zero-config "component styles" pattern. See [trunk#3](https://github.com/thedodd/trunk/issues/3) for more details. diff --git a/site/content/assets.md b/site/content/assets.md index 4c6803ea..d5f870c6 100644 --- a/site/content/assets.md +++ b/site/content/assets.md @@ -17,6 +17,8 @@ This will typically look like: `, + /// An option to instruct wasm-bindgen to preserve debug info in the final WASM output, even + /// for `--release` mode. + keep_debug: bool, + /// An option to instruct wasm-bindgen to not demangle Rust symbol names. + no_demangle: bool, /// An optional optimization setting that enables wasm-opt. Can be nothing, `0` (default), `1`, /// `2`, `3`, `4`, `s or `z`. Using `0` disables wasm-opt completely. wasm_opt: WasmOptLevel, } -/// Different optimization levels that can be configured with `wasm-opt`. -#[derive(PartialEq, Eq)] -enum WasmOptLevel { - /// Default optimization passes. - Default, - /// No optimization passes, skipping the wasp-opt step. - Off, - /// Run quick & useful optimizations. useful for iteration testing. - One, - /// Most optimizations, generally gets most performance. - Two, - /// Spend potentially a lot of time optimizing. - Three, - /// Also flatten the IR, which can take a lot more time and memory, but is useful on more nested - /// / complex / less-optimized input. - Four, - /// Default optimizations, focus on code size. - S, - /// Default optimizations, super-focusing on code size. - Z, -} - -impl FromStr for WasmOptLevel { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - Ok(match s { - "" => Self::Default, - "0" => Self::Off, - "1" => Self::One, - "2" => Self::Two, - "3" => Self::Three, - "4" => Self::Four, - "s" | "S" => Self::S, - "z" | "Z" => Self::Z, - _ => bail!("unknown wasm-opt level `{}`", s), - }) - } -} - -impl AsRef for WasmOptLevel { - fn as_ref(&self) -> &str { - match self { - Self::Default => "", - Self::Off => "0", - Self::One => "1", - Self::Two => "2", - Self::Three => "3", - Self::Four => "4", - Self::S => "s", - Self::Z => "z", - } - } -} - -impl Default for WasmOptLevel { - fn default() -> Self { - // Current default is off until automatic download of wasm-opt is implemented. - Self::Off - } -} - impl RustApp { pub const TYPE_RUST_APP: &'static str = "rust"; @@ -117,6 +60,8 @@ impl RustApp { }) .unwrap_or_else(|| html_dir.join("Cargo.toml")); let bin = attrs.get("data-bin").map(|val| val.to_string()); + let keep_debug = attrs.contains_key("data-keep-debug"); + let no_demangle = attrs.contains_key("data-no-demangle"); let wasm_opt = attrs.get("data-wasm-opt").map(|val| val.parse()).transpose()?.unwrap_or_default(); let manifest = CargoMetadata::new(&manifest_href).await?; let id = Some(id); @@ -127,6 +72,8 @@ impl RustApp { manifest, ignore_chan, bin, + keep_debug, + no_demangle, wasm_opt, }) } @@ -140,6 +87,8 @@ impl RustApp { manifest, ignore_chan, bin: None, + keep_debug: false, + no_demangle: false, wasm_opt: WasmOptLevel::default(), }) } @@ -245,7 +194,13 @@ impl RustApp { let arg_out_path = format!("--out-dir={}", bindgen_out.display()); let arg_out_name = format!("--out-name={}", &hashed_name); let target_wasm = wasm.to_string_lossy().to_string(); - let args = vec!["--target=web", &arg_out_path, &arg_out_name, "--no-typescript", &target_wasm]; + let mut args = vec!["--target=web", &arg_out_path, &arg_out_name, "--no-typescript", &target_wasm]; + if self.keep_debug { + args.push("--keep-debug"); + } + if self.no_demangle { + args.push("--no-demangle"); + } // Invoke wasm-bindgen. run_command("wasm-bindgen", &args).await?; @@ -360,3 +315,65 @@ async fn run_command(name: &str, args: &[impl AsRef]) -> Result<()> { } Ok(()) } + +/// Different optimization levels that can be configured with `wasm-opt`. +#[derive(PartialEq, Eq)] +enum WasmOptLevel { + /// Default optimization passes. + Default, + /// No optimization passes, skipping the wasp-opt step. + Off, + /// Run quick & useful optimizations. useful for iteration testing. + One, + /// Most optimizations, generally gets most performance. + Two, + /// Spend potentially a lot of time optimizing. + Three, + /// Also flatten the IR, which can take a lot more time and memory, but is useful on more nested + /// / complex / less-optimized input. + Four, + /// Default optimizations, focus on code size. + S, + /// Default optimizations, super-focusing on code size. + Z, +} + +impl FromStr for WasmOptLevel { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + Ok(match s { + "" => Self::Default, + "0" => Self::Off, + "1" => Self::One, + "2" => Self::Two, + "3" => Self::Three, + "4" => Self::Four, + "s" | "S" => Self::S, + "z" | "Z" => Self::Z, + _ => bail!("unknown wasm-opt level `{}`", s), + }) + } +} + +impl AsRef for WasmOptLevel { + fn as_ref(&self) -> &str { + match self { + Self::Default => "", + Self::Off => "0", + Self::One => "1", + Self::Two => "2", + Self::Three => "3", + Self::Four => "4", + Self::S => "s", + Self::Z => "z", + } + } +} + +impl Default for WasmOptLevel { + fn default() -> Self { + // Current default is off until automatic download of wasm-opt is implemented. + Self::Off + } +}