Skip to content

Commit

Permalink
fix: use generated binary path from cargo instead
Browse files Browse the repository at this point in the history
Previously when we'd invoke wasm-bindgen we'd assume that the binary we wanted
to process was `target/wasm32-unknown-unknown{debug|release}/crate.wasm`, which
isn't the case for all flags that Cargo accepts.
  • Loading branch information
zebp committed Aug 18, 2024
1 parent 62ab39c commit ec2411c
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 51 deletions.
22 changes: 1 addition & 21 deletions src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,10 @@ pub fn wasm_bindgen_build(
reference_types: bool,
target: Target,
profile: BuildProfile,
extra_options: &Vec<String>,
wasm_path: &Path,
) -> Result<()> {
let release_or_debug = match profile {
BuildProfile::Release | BuildProfile::Profiling => "release",
BuildProfile::Dev => "debug",
};

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(release_or_debug)
.join(data.crate_name())
.with_extension("wasm");

let dts_arg = if disable_dts {
"--no-typescript"
} else {
Expand Down
46 changes: 40 additions & 6 deletions src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ use crate::emoji;
use crate::manifest::Crate;
use crate::PBAR;
use anyhow::{anyhow, bail, Context, Result};
use std::path::Path;
use std::process::Command;
use cargo_metadata::Message;
use std::io::BufReader;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::str;

pub mod wasm_target;
Expand Down Expand Up @@ -77,12 +79,16 @@ pub fn cargo_build_wasm(
path: &Path,
profile: BuildProfile,
extra_options: &[String],
) -> Result<()> {
) -> Result<PathBuf> {
let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE);
PBAR.info(&msg);

let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build").arg("--lib");
cmd.current_dir(path)
.stdout(Stdio::piped())
.arg("build")
.arg("--lib")
.arg("--message-format=json-render-diagnostics");

if PBAR.quiet() {
cmd.arg("--quiet");
Expand Down Expand Up @@ -129,8 +135,36 @@ pub fn cargo_build_wasm(
.collect::<Result<Vec<_>>>()?;
cmd.args(extra_options_with_absolute_paths);

child::run(cmd, "cargo build").context("Compiling your crate to WebAssembly failed")?;
Ok(())
let mut last_artifact = None;

child::run_with_handler(cmd, "cargo build", |child| {
let stdout = child.stdout.take().unwrap();
let reader = BufReader::new(stdout);

for message in cargo_metadata::Message::parse_stream(reader) {
match message? {
Message::CompilerArtifact(artifact) => last_artifact = Some(artifact),
Message::CompilerMessage(msg) => {
if let Some(rendered) = msg.message.rendered {
println!("{}", rendered);
}
}
_ => (),
}
}

Ok(())
})
.context("Compiling your crate to WebAssembly failed")?;

let last_artifact = last_artifact
.ok_or_else(|| anyhow!("No artifacts were generated by cargo build"))?
.filenames
.into_iter()
.next()
.ok_or_else(|| anyhow!("No artifact filenames were generated by cargo build"))?;

Ok(PathBuf::from(last_artifact))
}

/// Runs `cargo build --tests` targeting `wasm32-unknown-unknown`.
Expand Down
28 changes: 27 additions & 1 deletion src/child.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use crate::install::Tool;
use anyhow::{bail, Result};
use log::info;
use std::process::{Command, Stdio};
use std::process::{Child, Command, Stdio};

/// Return a new Command object
pub fn new_command(program: &str) -> Command {
Expand Down Expand Up @@ -62,3 +62,29 @@ pub fn run_capture_stdout(mut command: Command, command_name: &Tool) -> Result<S
)
}
}

/// Run the command and handle child, return on success.
pub fn run_with_handler<T>(
mut command: Command,
command_name: &str,
handle: impl FnOnce(&mut Child) -> Result<T>,
) -> Result<T> {
info!("Running {:?}", command);

let mut child = command.spawn()?;

let ret = handle(&mut child)?;

let status = child.wait()?;

if status.success() {
Ok(ret)
} else {
bail!(
"failed to execute `{}`: exited with {}\n full command: {:?}",
command_name,
status,
command,
)
}
}
53 changes: 30 additions & 23 deletions src/command/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,13 @@ impl Default for BuildOptions {
}
}

type BuildStep = fn(&mut Build) -> Result<()>;
type BuildStep = fn(&mut Build, _state: &mut State) -> Result<()>;

#[derive(Default)]
struct State {
// step state
cargo_artifact: Option<PathBuf>,
}

impl Build {
/// Construct a build command from the given options.
Expand Down Expand Up @@ -260,9 +266,10 @@ impl Build {
let process_steps = Build::get_process_steps(self.mode, self.no_pack, self.no_opt);

let started = Instant::now();
let mut state = State::default();

for (_, process_step) in process_steps {
process_step(self)?;
process_step(self, &mut state)?;
}

let duration = crate::command::utils::elapsed(started.elapsed());
Expand Down Expand Up @@ -331,51 +338,48 @@ impl Build {
steps
}

fn step_check_rustc_version(&mut self) -> Result<()> {
fn step_check_rustc_version(&mut self, _state: &mut State) -> Result<()> {
info!("Checking rustc version...");
let version = build::check_rustc_version()?;
let msg = format!("rustc version is {}.", version);
info!("{}", &msg);
Ok(())
}

fn step_check_crate_config(&mut self) -> Result<()> {
fn step_check_crate_config(&mut self, _state: &mut State) -> Result<()> {
info!("Checking crate configuration...");
self.crate_data.check_crate_config()?;
info!("Crate is correctly configured.");
Ok(())
}

fn step_check_for_wasm_target(&mut self) -> Result<()> {
fn step_check_for_wasm_target(&mut self, _state: &mut State) -> Result<()> {
info!("Checking for wasm-target...");
build::wasm_target::check_for_wasm32_target()?;
info!("Checking for wasm-target was successful.");
Ok(())
}

fn step_build_wasm(&mut self) -> Result<()> {
fn step_build_wasm(&mut self, state: &mut State) -> Result<()> {
info!("Building wasm...");
build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?;
let cargo_artifact =
build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?;

info!("wasm built at {:#?}.", cargo_artifact);

state.cargo_artifact = Some(cargo_artifact);

info!(
"wasm built at {:#?}.",
&self
.crate_path
.join("target")
.join("wasm32-unknown-unknown")
.join("release")
);
Ok(())
}

fn step_create_dir(&mut self) -> Result<()> {
fn step_create_dir(&mut self, _state: &mut State) -> Result<()> {
info!("Creating a pkg directory...");
create_pkg_dir(&self.out_dir)?;
info!("Created a pkg directory at {:#?}.", &self.crate_path);
Ok(())
}

fn step_create_json(&mut self) -> Result<()> {
fn step_create_json(&mut self, _state: &mut State) -> Result<()> {
self.crate_data.write_package_json(
&self.out_dir,
&self.scope,
Expand All @@ -389,21 +393,21 @@ impl Build {
Ok(())
}

fn step_copy_readme(&mut self) -> Result<()> {
fn step_copy_readme(&mut self, _state: &mut State) -> Result<()> {
info!("Copying readme from crate...");
readme::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;
info!("Copied readme from crate to {:#?}.", &self.out_dir);
Ok(())
}

fn step_copy_license(&mut self) -> Result<()> {
fn step_copy_license(&mut self, _state: &mut State) -> Result<()> {
info!("Copying license from crate...");
license::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;
info!("Copied license from crate to {:#?}.", &self.out_dir);
Ok(())
}

fn step_install_wasm_bindgen(&mut self) -> Result<()> {
fn step_install_wasm_bindgen(&mut self, _state: &mut State) -> Result<()> {
info!("Identifying wasm-bindgen dependency...");
let lockfile = Lockfile::new(&self.crate_data)?;
let bindgen_version = lockfile.require_wasm_bindgen()?;
Expand All @@ -419,7 +423,7 @@ impl Build {
Ok(())
}

fn step_run_wasm_bindgen(&mut self) -> Result<()> {
fn step_run_wasm_bindgen(&mut self, state: &mut State) -> Result<()> {
info!("Building the wasm bindings...");
bindgen::wasm_bindgen_build(
&self.crate_data,
Expand All @@ -431,13 +435,16 @@ impl Build {
self.reference_types,
self.target,
self.profile,
&self.extra_options,
state
.cargo_artifact
.as_ref()
.expect("bindgen ran before cargo build"),
)?;
info!("wasm bindings were built at {:#?}.", &self.out_dir);
Ok(())
}

fn step_run_wasm_opt(&mut self) -> Result<()> {
fn step_run_wasm_opt(&mut self, _state: &mut State) -> Result<()> {
let mut args = match self
.crate_data
.configured_profile(self.profile)
Expand Down

0 comments on commit ec2411c

Please sign in to comment.