Skip to main content

wasm_pack/
wasm_opt.rs

1//! Support for downloading and executing `wasm-opt`
2
3use crate::child;
4use crate::install;
5use crate::PBAR;
6use anyhow::Result;
7use binary_install::Cache;
8use std::path::Path;
9use std::path::PathBuf;
10use std::process::Command;
11
12/// Execute `wasm-opt` over wasm binaries found in `out_dir`, downloading if
13/// necessary into `cache`. Passes `args` to each invocation of `wasm-opt`.
14pub fn run(cache: &Cache, out_dir: &Path, args: &[String], install_permitted: bool) -> Result<()> {
15    let wasm_opt_path = match find_wasm_opt(cache, install_permitted)? {
16        Some(path) => path,
17        // `find_wasm_opt` will have already logged a message about this, so we don't need to here.
18        None => return Ok(()),
19    };
20
21    PBAR.info("Optimizing wasm binaries with `wasm-opt`...");
22
23    for file in out_dir.read_dir()? {
24        let file = file?;
25        let path = file.path();
26        if path.extension().and_then(|s| s.to_str()) != Some("wasm") {
27            continue;
28        }
29
30        let tmp = path.with_extension("wasm-opt.wasm");
31        let mut cmd = Command::new(&wasm_opt_path);
32        cmd.arg(&path).arg("-o").arg(&tmp).args(args);
33        child::run(cmd, "wasm-opt")?;
34        std::fs::rename(&tmp, &path)?;
35    }
36
37    Ok(())
38}
39
40/// Attempts to find `wasm-opt` in `PATH` locally, or failing that downloads a
41/// precompiled binary.
42///
43/// Returns `Some` if a binary was found or it was successfully downloaded.
44/// Returns `None` if a binary wasn't found in `PATH` and this platform doesn't
45/// have precompiled binaries. Returns an error if we failed to download the
46/// binary.
47pub fn find_wasm_opt(cache: &Cache, install_permitted: bool) -> Result<Option<PathBuf>> {
48    // First attempt to look up in PATH. If found assume it works.
49    if let Ok(path) = which::which("wasm-opt") {
50        PBAR.info(&format!("found wasm-opt at {:?}", path));
51        return Ok(Some(path));
52    }
53
54    match install::download_prebuilt(&install::Tool::WasmOpt, cache, "latest", install_permitted)? {
55        install::Status::Found(download) => Ok(Some(download.binary("bin/wasm-opt")?)),
56        install::Status::CannotInstall => {
57            PBAR.info("Skipping wasm-opt as no downloading was requested");
58            Ok(None)
59        }
60        install::Status::PlatformNotSupported => {
61            PBAR.info("Skipping wasm-opt because it is not supported on this platform");
62            Ok(None)
63        }
64    }
65}