Skip to content

Commit ec2411c

Browse files
committed
fix: use generated binary path from cargo instead
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.
1 parent 62ab39c commit ec2411c

File tree

4 files changed

+98
-51
lines changed

4 files changed

+98
-51
lines changed

src/bindgen.rs

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,10 @@ pub fn wasm_bindgen_build(
2121
reference_types: bool,
2222
target: Target,
2323
profile: BuildProfile,
24-
extra_options: &Vec<String>,
24+
wasm_path: &Path,
2525
) -> Result<()> {
26-
let release_or_debug = match profile {
27-
BuildProfile::Release | BuildProfile::Profiling => "release",
28-
BuildProfile::Dev => "debug",
29-
};
30-
3126
let out_dir = out_dir.to_str().unwrap();
3227

33-
let target_directory = {
34-
let mut has_target_dir_iter = extra_options.iter();
35-
has_target_dir_iter
36-
.find(|&it| it == "--target-dir")
37-
.and_then(|_| has_target_dir_iter.next())
38-
.map(Path::new)
39-
.unwrap_or(data.target_directory())
40-
};
41-
42-
let wasm_path = target_directory
43-
.join("wasm32-unknown-unknown")
44-
.join(release_or_debug)
45-
.join(data.crate_name())
46-
.with_extension("wasm");
47-
4828
let dts_arg = if disable_dts {
4929
"--no-typescript"
5030
} else {

src/build/mod.rs

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ use crate::emoji;
66
use crate::manifest::Crate;
77
use crate::PBAR;
88
use anyhow::{anyhow, bail, Context, Result};
9-
use std::path::Path;
10-
use std::process::Command;
9+
use cargo_metadata::Message;
10+
use std::io::BufReader;
11+
use std::path::{Path, PathBuf};
12+
use std::process::{Command, Stdio};
1113
use std::str;
1214

1315
pub mod wasm_target;
@@ -77,12 +79,16 @@ pub fn cargo_build_wasm(
7779
path: &Path,
7880
profile: BuildProfile,
7981
extra_options: &[String],
80-
) -> Result<()> {
82+
) -> Result<PathBuf> {
8183
let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE);
8284
PBAR.info(&msg);
8385

8486
let mut cmd = Command::new("cargo");
85-
cmd.current_dir(path).arg("build").arg("--lib");
87+
cmd.current_dir(path)
88+
.stdout(Stdio::piped())
89+
.arg("build")
90+
.arg("--lib")
91+
.arg("--message-format=json-render-diagnostics");
8692

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

132-
child::run(cmd, "cargo build").context("Compiling your crate to WebAssembly failed")?;
133-
Ok(())
138+
let mut last_artifact = None;
139+
140+
child::run_with_handler(cmd, "cargo build", |child| {
141+
let stdout = child.stdout.take().unwrap();
142+
let reader = BufReader::new(stdout);
143+
144+
for message in cargo_metadata::Message::parse_stream(reader) {
145+
match message? {
146+
Message::CompilerArtifact(artifact) => last_artifact = Some(artifact),
147+
Message::CompilerMessage(msg) => {
148+
if let Some(rendered) = msg.message.rendered {
149+
println!("{}", rendered);
150+
}
151+
}
152+
_ => (),
153+
}
154+
}
155+
156+
Ok(())
157+
})
158+
.context("Compiling your crate to WebAssembly failed")?;
159+
160+
let last_artifact = last_artifact
161+
.ok_or_else(|| anyhow!("No artifacts were generated by cargo build"))?
162+
.filenames
163+
.into_iter()
164+
.next()
165+
.ok_or_else(|| anyhow!("No artifact filenames were generated by cargo build"))?;
166+
167+
Ok(PathBuf::from(last_artifact))
134168
}
135169

136170
/// Runs `cargo build --tests` targeting `wasm32-unknown-unknown`.

src/child.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use crate::install::Tool;
77
use anyhow::{bail, Result};
88
use log::info;
9-
use std::process::{Command, Stdio};
9+
use std::process::{Child, Command, Stdio};
1010

1111
/// Return a new Command object
1212
pub fn new_command(program: &str) -> Command {
@@ -62,3 +62,29 @@ pub fn run_capture_stdout(mut command: Command, command_name: &Tool) -> Result<S
6262
)
6363
}
6464
}
65+
66+
/// Run the command and handle child, return on success.
67+
pub fn run_with_handler<T>(
68+
mut command: Command,
69+
command_name: &str,
70+
handle: impl FnOnce(&mut Child) -> Result<T>,
71+
) -> Result<T> {
72+
info!("Running {:?}", command);
73+
74+
let mut child = command.spawn()?;
75+
76+
let ret = handle(&mut child)?;
77+
78+
let status = child.wait()?;
79+
80+
if status.success() {
81+
Ok(ret)
82+
} else {
83+
bail!(
84+
"failed to execute `{}`: exited with {}\n full command: {:?}",
85+
command_name,
86+
status,
87+
command,
88+
)
89+
}
90+
}

src/command/build.rs

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,13 @@ impl Default for BuildOptions {
203203
}
204204
}
205205

206-
type BuildStep = fn(&mut Build) -> Result<()>;
206+
type BuildStep = fn(&mut Build, _state: &mut State) -> Result<()>;
207+
208+
#[derive(Default)]
209+
struct State {
210+
// step state
211+
cargo_artifact: Option<PathBuf>,
212+
}
207213

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

262268
let started = Instant::now();
269+
let mut state = State::default();
263270

264271
for (_, process_step) in process_steps {
265-
process_step(self)?;
272+
process_step(self, &mut state)?;
266273
}
267274

268275
let duration = crate::command::utils::elapsed(started.elapsed());
@@ -331,51 +338,48 @@ impl Build {
331338
steps
332339
}
333340

334-
fn step_check_rustc_version(&mut self) -> Result<()> {
341+
fn step_check_rustc_version(&mut self, _state: &mut State) -> Result<()> {
335342
info!("Checking rustc version...");
336343
let version = build::check_rustc_version()?;
337344
let msg = format!("rustc version is {}.", version);
338345
info!("{}", &msg);
339346
Ok(())
340347
}
341348

342-
fn step_check_crate_config(&mut self) -> Result<()> {
349+
fn step_check_crate_config(&mut self, _state: &mut State) -> Result<()> {
343350
info!("Checking crate configuration...");
344351
self.crate_data.check_crate_config()?;
345352
info!("Crate is correctly configured.");
346353
Ok(())
347354
}
348355

349-
fn step_check_for_wasm_target(&mut self) -> Result<()> {
356+
fn step_check_for_wasm_target(&mut self, _state: &mut State) -> Result<()> {
350357
info!("Checking for wasm-target...");
351358
build::wasm_target::check_for_wasm32_target()?;
352359
info!("Checking for wasm-target was successful.");
353360
Ok(())
354361
}
355362

356-
fn step_build_wasm(&mut self) -> Result<()> {
363+
fn step_build_wasm(&mut self, state: &mut State) -> Result<()> {
357364
info!("Building wasm...");
358-
build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?;
365+
let cargo_artifact =
366+
build::cargo_build_wasm(&self.crate_path, self.profile, &self.extra_options)?;
367+
368+
info!("wasm built at {:#?}.", cargo_artifact);
369+
370+
state.cargo_artifact = Some(cargo_artifact);
359371

360-
info!(
361-
"wasm built at {:#?}.",
362-
&self
363-
.crate_path
364-
.join("target")
365-
.join("wasm32-unknown-unknown")
366-
.join("release")
367-
);
368372
Ok(())
369373
}
370374

371-
fn step_create_dir(&mut self) -> Result<()> {
375+
fn step_create_dir(&mut self, _state: &mut State) -> Result<()> {
372376
info!("Creating a pkg directory...");
373377
create_pkg_dir(&self.out_dir)?;
374378
info!("Created a pkg directory at {:#?}.", &self.crate_path);
375379
Ok(())
376380
}
377381

378-
fn step_create_json(&mut self) -> Result<()> {
382+
fn step_create_json(&mut self, _state: &mut State) -> Result<()> {
379383
self.crate_data.write_package_json(
380384
&self.out_dir,
381385
&self.scope,
@@ -389,21 +393,21 @@ impl Build {
389393
Ok(())
390394
}
391395

392-
fn step_copy_readme(&mut self) -> Result<()> {
396+
fn step_copy_readme(&mut self, _state: &mut State) -> Result<()> {
393397
info!("Copying readme from crate...");
394398
readme::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;
395399
info!("Copied readme from crate to {:#?}.", &self.out_dir);
396400
Ok(())
397401
}
398402

399-
fn step_copy_license(&mut self) -> Result<()> {
403+
fn step_copy_license(&mut self, _state: &mut State) -> Result<()> {
400404
info!("Copying license from crate...");
401405
license::copy_from_crate(&self.crate_data, &self.crate_path, &self.out_dir)?;
402406
info!("Copied license from crate to {:#?}.", &self.out_dir);
403407
Ok(())
404408
}
405409

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

422-
fn step_run_wasm_bindgen(&mut self) -> Result<()> {
426+
fn step_run_wasm_bindgen(&mut self, state: &mut State) -> Result<()> {
423427
info!("Building the wasm bindings...");
424428
bindgen::wasm_bindgen_build(
425429
&self.crate_data,
@@ -431,13 +435,16 @@ impl Build {
431435
self.reference_types,
432436
self.target,
433437
self.profile,
434-
&self.extra_options,
438+
state
439+
.cargo_artifact
440+
.as_ref()
441+
.expect("bindgen ran before cargo build"),
435442
)?;
436443
info!("wasm bindings were built at {:#?}.", &self.out_dir);
437444
Ok(())
438445
}
439446

440-
fn step_run_wasm_opt(&mut self) -> Result<()> {
447+
fn step_run_wasm_opt(&mut self, _state: &mut State) -> Result<()> {
441448
let mut args = match self
442449
.crate_data
443450
.configured_profile(self.profile)

0 commit comments

Comments
 (0)