Skip to content

Commit

Permalink
Use --message-format=json to fix rustwasm#333
Browse files Browse the repository at this point in the history
  • Loading branch information
konstin committed Sep 27, 2018
1 parent 8e6cc1f commit cc38989
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 65 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ documentation = "https://rustwasm.github.io/wasm-pack/"

[dependencies]
atty = "0.2.11"
cargo_metadata = "0.6.0"
console = "0.6.1"
curl = "0.4.13"
failure = "0.1.2"
Expand All @@ -32,8 +31,7 @@ tar = "0.4.16"
toml = "0.4"
which = "2.0.0"
zip = "0.4.2"

[dev-dependencies]
cargo_metadata = { git = "https://github.com/roblabla/cargo_metadata", rev = "54a24e30864feb7414ca400f65a486d1e01ec474" }
tempfile = "3"

[features]
Expand Down
11 changes: 2 additions & 9 deletions src/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub fn cargo_install_wasm_bindgen(crate_path: &Path, version: &str) -> Result<()
pub fn wasm_bindgen_build(
path: &Path,
out_dir: &Path,
name: &str,
artifact: &Path,
disable_dts: bool,
target: &str,
debug: bool,
Expand All @@ -119,16 +119,9 @@ pub fn wasm_bindgen_build(
let msg = format!("{}Running WASM-bindgen...", emoji::RUNNER);
PBAR.step(step, &msg);

let binary_name = name.replace("-", "_");
let release_or_debug = if debug { "debug" } else { "release" };

let out_dir = out_dir.to_str().unwrap();

if let Some(wasm_bindgen_path) = wasm_bindgen_path(log, path) {
let wasm_path = format!(
"target/wasm32-unknown-unknown/{}/{}.wasm",
release_or_debug, binary_name
);
let dts_arg = if disable_dts {
"--no-typescript"
} else {
Expand All @@ -142,7 +135,7 @@ pub fn wasm_bindgen_build(
let bindgen_path = Path::new(&wasm_bindgen_path);
let mut cmd = Command::new(bindgen_path);
cmd.current_dir(path)
.arg(&wasm_path)
.arg(artifact)
.arg("--out-dir")
.arg(out_dir)
.arg(dts_arg)
Expand Down
140 changes: 105 additions & 35 deletions src/build.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
//! Building a Rust crate into a `.wasm` binary.
use cargo_metadata;
use cargo_metadata::Message;
use emoji;
use error::Error;
use progressbar::Step;
use std::io::Read;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use std::process::Stdio;
use std::str;
use tempfile::NamedTempFile;
use PBAR;

/// Ensure that `rustc` is present and that it is >= 1.30.0
Expand All @@ -16,20 +22,20 @@ pub fn check_rustc_version(step: &Step) -> Result<String, Error> {
match local_minor_version {
Some(mv) => {
if mv < 30 {
return Err(Error::RustcVersion {
message: format!(
"Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.",
mv.to_string()
),
local_minor_version: mv.to_string(),
})
return Err(Error::RustcVersion {
message: format!(
"Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.",
mv.to_string()
),
local_minor_version: mv.to_string(),
});
} else {
Ok(mv.to_string())
Ok(mv.to_string())
}
},
None => Err(Error::RustcMissing {
message: "We can't figure out what your Rust version is- which means you might not have Rust installed. Please install Rust version 1.30.0 or higher.".to_string(),
}),
}
None => Err(Error::RustcMissing {
message: "We can't figure out what your Rust version is- which means you might not have Rust installed. Please install Rust version 1.30.0 or higher.".to_string(),
}),
}
}

Expand Down Expand Up @@ -71,38 +77,102 @@ pub fn rustup_add_wasm_target(step: &Step) -> Result<(), Error> {
}

/// Run `cargo build` targetting `wasm32-unknown-unknown`.
pub fn cargo_build_wasm(path: &Path, debug: bool, step: &Step) -> Result<(), Error> {
///
/// Returns the location of the built wasm file.
pub fn cargo_build_wasm(
path: &Path,
debug: bool,
step: &Step,
crate_name: &str,
) -> Result<PathBuf, Error> {
let msg = format!("{}Compiling to WASM...", emoji::CYCLONE);
PBAR.step(step, &msg);
let output = {
let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build").arg("--lib");
if !debug {
cmd.arg("--release");
}
cmd.arg("--target").arg("wasm32-unknown-unknown");
cmd.output()?
};

if !output.status.success() {
let s = String::from_utf8_lossy(&output.stderr);
Error::cli("Compilation of your program failed", s)
// Since pipes like `Stdio::piped()` have a fixed capacity, we could deadlock with us
// waiting on stdout and cargo blocking on the full stderr pipe. This is why we use a file
// here
let mut stderr = NamedTempFile::new()?;

let mut cmd = Command::new("cargo");
cmd.current_dir(path)
.arg("+nightly")
.arg("build")
.arg("--lib")
.arg("--target=wasm32-unknown-unknown")
.arg("--message-format=json")
.stderr(Stdio::from(stderr.reopen()?))
.stdout(Stdio::piped());
if !debug {
cmd.arg("--release");
}
let mut output = cmd.spawn()?;

let message_stream = output
.stdout
.take()
.expect("cargo child process should always have an stdout");

let mut wasm_file = None;

for message in cargo_metadata::parse_message_stream(message_stream) {
match message.unwrap() {
Message::CompilerArtifact(artifact) => {
if artifact.package_id.name() == crate_name {
let pos = artifact
.target
.crate_types
.iter()
.position(|x| x == "cdylib");

if let Some(pos) = pos {
wasm_file = Some(PathBuf::from(&artifact.filenames[pos]));
};
};
}
Message::CompilerMessage(message) => {
eprintln!(
"{}",
message
.message
.rendered
.unwrap_or_else(|| "Unrendered Message".to_string())
);
}
_ => (),
};
}

let status = output.wait()?;
if !status.success() {
let mut errors = String::new();
stderr.read_to_string(&mut errors)?;
Err(Error::Cli {
message: "Compilation of your program failed".to_string(),
stderr: errors,
})
} else {
Ok(())
if let Some(wasm_file) = wasm_file {
Ok(wasm_file)
} else {
Err(Error::CrateConfig {
message: "Your crate didn't produce a cdylib".to_string(),
})
}
}
}

/// Run `cargo build --tests` targetting `wasm32-unknown-unknown`.
pub fn cargo_build_wasm_tests(path: &Path, debug: bool) -> Result<(), Error> {
let output = {
let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build").arg("--tests");
if !debug {
cmd.arg("--release");
}
cmd.arg("--target").arg("wasm32-unknown-unknown");
cmd.output()?
};
let mut cmd = Command::new("cargo");
cmd.current_dir(path)
.arg("build")
.arg("--tests")
.arg("--target=wasm32-unknown-unknown");
if !debug {
cmd.arg("--release");
}

let output = cmd.output()?;

if !output.status.success() {
let s = String::from_utf8_lossy(&output.stderr);
Expand Down
21 changes: 10 additions & 11 deletions src/command/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub(crate) struct Build {
// build_config: Option<BuildConfig>,
pub crate_name: String,
pub out_dir: PathBuf,
/// This is a workaround to pass the artifact's location from build_wasm to run_wasm_bindgen
pub wasm_file: Option<PathBuf>,
}

/// The `BuildMode` determines which mode of initialization we are running, and
Expand Down Expand Up @@ -113,6 +115,7 @@ impl Build {
// build_config,
crate_name,
out_dir,
wasm_file: None,
})
}

Expand Down Expand Up @@ -212,17 +215,13 @@ impl Build {

fn step_build_wasm(&mut self, step: &Step, log: &Logger) -> Result<(), Error> {
info!(&log, "Building wasm...");
build::cargo_build_wasm(&self.crate_path, self.debug, step)?;
let artifact =
build::cargo_build_wasm(&self.crate_path, self.debug, step, &self.crate_name)?;

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

self.wasm_file = Some(artifact);

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

Expand Down Expand Up @@ -293,7 +292,7 @@ impl Build {
bindgen::wasm_bindgen_build(
&self.crate_path,
&self.out_dir,
&self.crate_name,
&self.wasm_file.clone().unwrap(),
self.disable_dts,
&self.target,
self.debug,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern crate slog;
extern crate slog_async;
extern crate slog_term;
extern crate tar;
extern crate tempfile;
extern crate toml;
extern crate which;
extern crate zip;
Expand Down
18 changes: 18 additions & 0 deletions tests/all/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,21 @@ fn build_in_non_crate_directory_doesnt_panic() {
let err_msg = result.unwrap_err().to_string();
assert!(err_msg.contains("missing a `Cargo.toml`"));
}

#[test]
fn build_in_nested_workspace() {
let fixture = utils::fixture::nested_workspace();
let cli = Cli::from_iter_safe(vec![
"wasm-pack",
"build",
"--debug",
"--mode=no-install",
&fixture.path.join("sub-crate").display().to_string(),
]).unwrap();
let logger = logger::new(&cli.cmd, cli.verbosity).unwrap();
let result = command::run_wasm_pack(cli.cmd, &logger);
assert!(
result.is_ok(),
"Building with wasm-pack in nested workspace should succeed"
);
}
Loading

0 comments on commit cc38989

Please sign in to comment.