//! Functionality related to running `wasm-bindgen`. use crate::child; use crate::command::build::{BuildProfile, Target}; use crate::install::{self, Tool}; use crate::manifest::CrateData; use anyhow::{bail, Context, Result}; use semver; use std::path::Path; use std::process::Command; /// Run the `wasm-bindgen` CLI to generate bindings for the current crate's /// `.wasm`. pub fn wasm_bindgen_build( data: &CrateData, install_status: &install::Status, out_dir: &Path, out_name: &Option, disable_dts: bool, weak_refs: bool, reference_types: bool, target: Target, profile: BuildProfile, extra_options: &Vec, ) -> Result<()> { let profile_name = match profile.clone() { BuildProfile::Release | BuildProfile::Profiling => "release", BuildProfile::Dev => "debug", BuildProfile::Custom(profile_name) => &profile_name.clone(), }; let out_dir = out_dir.to_str().unwrap(); let target_directory = { let mut has_target_dir_iter = extra_options.iter(); has_target_dir_iter .find(|&it| it == "--target-dir") .and_then(|_| has_target_dir_iter.next()) .map(Path::new) .unwrap_or(data.target_directory()) }; let wasm_path = target_directory .join("wasm32-unknown-unknown") .join(profile_name) .join(data.crate_name()) .with_extension("wasm"); let dts_arg = if disable_dts { "--no-typescript" } else { "--typescript" }; let bindgen_path = install::get_tool_path(install_status, Tool::WasmBindgen)? .binary(&Tool::WasmBindgen.to_string())?; let mut cmd = Command::new(&bindgen_path); cmd.arg(&wasm_path) .arg("--out-dir") .arg(out_dir) .arg(dts_arg); if weak_refs { cmd.arg("--weak-refs"); } if reference_types { cmd.arg("--reference-types"); } let target_arg = build_target_arg(target, &bindgen_path)?; if supports_dash_dash_target(&bindgen_path)? { cmd.arg("--target").arg(target_arg); } else { cmd.arg(target_arg); } if let Some(value) = out_name { cmd.arg("--out-name").arg(value); } let profile = data.configured_profile(profile); if profile.wasm_bindgen_debug_js_glue() { cmd.arg("--debug"); } if !profile.wasm_bindgen_demangle_name_section() { cmd.arg("--no-demangle"); } if profile.wasm_bindgen_dwarf_debug_info() { cmd.arg("--keep-debug"); } if profile.wasm_bindgen_omit_default_module_path() { cmd.arg("--omit-default-module-path"); } if profile.wasm_bindgen_split_linked_modules() { cmd.arg("--split-linked-modules"); } child::run(cmd, "wasm-bindgen").context("Running the wasm-bindgen CLI")?; Ok(()) } /// Check if the `wasm-bindgen` dependency is locally satisfied for the web target fn supports_web_target(cli_path: &Path) -> Result { let cli_version = semver::Version::parse(&install::get_cli_version( &install::Tool::WasmBindgen, cli_path, )?)?; let expected_version = semver::Version::parse("0.2.39")?; Ok(cli_version >= expected_version) } /// Check if the `wasm-bindgen` dependency is locally satisfied for the --target flag fn supports_dash_dash_target(cli_path: &Path) -> Result { let cli_version = semver::Version::parse(&install::get_cli_version( &install::Tool::WasmBindgen, cli_path, )?)?; let expected_version = semver::Version::parse("0.2.40")?; Ok(cli_version >= expected_version) } fn build_target_arg(target: Target, cli_path: &Path) -> Result { if !supports_dash_dash_target(cli_path)? { Ok(build_target_arg_legacy(target, cli_path)?) } else { Ok(target.to_string()) } } fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result { log::info!("Your version of wasm-bindgen is out of date. You should consider updating your Cargo.toml to a version >= 0.2.40."); let target_arg = match target { Target::Nodejs => "--nodejs", Target::NoModules => "--no-modules", Target::Web => { if supports_web_target(cli_path)? { "--web" } else { bail!("Your current version of wasm-bindgen does not support the 'web' target. Please update your project to wasm-bindgen version >= 0.2.39.") } } Target::Bundler => "--browser", Target::Deno => "--deno", }; Ok(target_arg.to_string()) }