wasm_pack/
bindgen.rs

1//! Functionality related to running `wasm-bindgen`.
2
3use crate::child;
4use crate::command::build::{BuildProfile, Target};
5use crate::install::{self, Tool};
6use crate::manifest::CrateData;
7use anyhow::{bail, Context, Result};
8use semver;
9use std::path::Path;
10use std::process::Command;
11
12/// Run the `wasm-bindgen` CLI to generate bindings for the current crate's
13/// `.wasm`.
14pub fn wasm_bindgen_build(
15    wasm_path: &str,
16    data: &CrateData,
17    install_status: &install::Status,
18    out_dir: &Path,
19    out_name: &Option<String>,
20    disable_dts: bool,
21    weak_refs: bool,
22    reference_types: bool,
23    target: Target,
24    profile: BuildProfile,
25) -> Result<()> {
26    let out_dir = out_dir.to_str().unwrap();
27
28    let dts_arg = if disable_dts {
29        "--no-typescript"
30    } else {
31        "--typescript"
32    };
33    let bindgen_path = install::get_tool_path(install_status, Tool::WasmBindgen)?
34        .binary(&Tool::WasmBindgen.to_string())?;
35
36    let mut cmd = Command::new(&bindgen_path);
37    cmd.arg(&wasm_path)
38        .arg("--out-dir")
39        .arg(out_dir)
40        .arg(dts_arg);
41
42    if weak_refs {
43        cmd.arg("--weak-refs");
44    }
45
46    if reference_types {
47        cmd.arg("--reference-types");
48    }
49
50    let target_arg = build_target_arg(target, &bindgen_path)?;
51    if supports_dash_dash_target(&bindgen_path)? {
52        cmd.arg("--target").arg(target_arg);
53    } else {
54        cmd.arg(target_arg);
55    }
56
57    if let Some(value) = out_name {
58        cmd.arg("--out-name").arg(value);
59    }
60
61    let profile = data.configured_profile(profile);
62    if profile.wasm_bindgen_debug_js_glue() {
63        cmd.arg("--debug");
64    }
65    if !profile.wasm_bindgen_demangle_name_section() {
66        cmd.arg("--no-demangle");
67    }
68    if profile.wasm_bindgen_dwarf_debug_info() {
69        cmd.arg("--keep-debug");
70    }
71    if profile.wasm_bindgen_omit_default_module_path() {
72        cmd.arg("--omit-default-module-path");
73    }
74    if profile.wasm_bindgen_split_linked_modules() {
75        cmd.arg("--split-linked-modules");
76    }
77
78    child::run(cmd, "wasm-bindgen").context("Running the wasm-bindgen CLI")?;
79    Ok(())
80}
81
82/// Check if the `wasm-bindgen` dependency is locally satisfied for the web target
83fn supports_web_target(cli_path: &Path) -> Result<bool> {
84    let cli_version = semver::Version::parse(&install::get_cli_version(
85        &install::Tool::WasmBindgen,
86        cli_path,
87    )?)?;
88    let expected_version = semver::Version::parse("0.2.39")?;
89    Ok(cli_version >= expected_version)
90}
91
92/// Check if the `wasm-bindgen` dependency is locally satisfied for the --target flag
93fn supports_dash_dash_target(cli_path: &Path) -> Result<bool> {
94    let cli_version = semver::Version::parse(&install::get_cli_version(
95        &install::Tool::WasmBindgen,
96        cli_path,
97    )?)?;
98    let expected_version = semver::Version::parse("0.2.40")?;
99    Ok(cli_version >= expected_version)
100}
101
102fn build_target_arg(target: Target, cli_path: &Path) -> Result<String> {
103    if !supports_dash_dash_target(cli_path)? {
104        Ok(build_target_arg_legacy(target, cli_path)?)
105    } else {
106        Ok(target.to_string())
107    }
108}
109
110fn build_target_arg_legacy(target: Target, cli_path: &Path) -> Result<String> {
111    log::info!("Your version of wasm-bindgen is out of date. You should consider updating your Cargo.toml to a version >= 0.2.40.");
112    let target_arg = match target {
113        Target::Nodejs => "--nodejs",
114        Target::NoModules => "--no-modules",
115        Target::Web => {
116            if supports_web_target(cli_path)? {
117                "--web"
118            } else {
119                bail!("Your current version of wasm-bindgen does not support the 'web' target. Please update your project to wasm-bindgen version >= 0.2.39.")
120            }
121        }
122        Target::Bundler => "--browser",
123        Target::Deno => "--deno",
124    };
125    Ok(target_arg.to_string())
126}