refactor: Move wasm32 checking to it's own file

master
Jesper Håkansson 6 years ago
parent 12fcdad8b4
commit 735c5865a2
  1. 97
      src/build/mod.rs
  2. 183
      src/build/wasm_target.rs
  3. 2
      src/command/build.rs
  4. 2
      src/command/test.rs

@ -0,0 +1,97 @@
//! Building a Rust crate into a `.wasm` binary.
use child;
use command::build::BuildProfile;
use emoji;
use failure::{Error, ResultExt};
use std::path::Path;
use std::process::Command;
use std::str;
use PBAR;
pub mod wasm_target;
/// Ensure that `rustc` is present and that it is >= 1.30.0
pub fn check_rustc_version() -> Result<String, Error> {
let local_minor_version = rustc_minor_version();
match local_minor_version {
Some(mv) => {
if mv < 30 {
bail!(
"Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.",
mv.to_string()
)
} else {
Ok(mv.to_string())
}
}
None => bail!("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."),
}
}
// from https://github.com/alexcrichton/proc-macro2/blob/79e40a113b51836f33214c6d00228934b41bd4ad/build.rs#L44-L61
fn rustc_minor_version() -> Option<u32> {
macro_rules! otry {
($e:expr) => {
match $e {
Some(e) => e,
None => return None,
}
};
}
let output = otry!(Command::new("rustc").arg("--version").output().ok());
let version = otry!(str::from_utf8(&output.stdout).ok());
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
otry!(pieces.next()).parse().ok()
}
/// Run `cargo build` targetting `wasm32-unknown-unknown`.
pub fn cargo_build_wasm(
path: &Path,
profile: BuildProfile,
extra_options: &Vec<String>,
) -> Result<(), Error> {
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");
match profile {
BuildProfile::Profiling => {
// Once there are DWARF debug info consumers, force enable debug
// info, because builds that use the release cargo profile disables
// debug info.
//
// cmd.env("RUSTFLAGS", "-g");
cmd.arg("--release");
}
BuildProfile::Release => {
cmd.arg("--release");
}
BuildProfile::Dev => {
// Plain cargo builds use the dev cargo profile, which includes
// debug info by default.
}
}
cmd.arg("--target").arg("wasm32-unknown-unknown");
cmd.args(extra_options);
child::run(cmd, "cargo build").context("Compiling your crate to WebAssembly failed")?;
Ok(())
}
/// Run `cargo build --tests` targetting `wasm32-unknown-unknown`.
///
/// This generates the `Cargo.lock` file that we use in order to know which version of
/// wasm-bindgen-cli to use when running tests.
pub fn cargo_build_wasm_tests(path: &Path, debug: bool) -> Result<(), Error> {
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");
child::run(cmd, "cargo build").context("Compilation of your program failed")?;
Ok(())
}

@ -1,51 +1,67 @@
//! Building a Rust crate into a `.wasm` binary. //! Checking for the wasm32 target
use child; use child;
use command::build::BuildProfile;
use emoji; use emoji;
use failure::{Error, ResultExt}; use failure::{Error, ResultExt};
use log::info; use log::info;
use std::fmt; use std::fmt;
use std::path::{Path, PathBuf}; use std::path::PathBuf;
use std::process::Command; use std::process::Command;
use std::str;
use PBAR; use PBAR;
/// Ensure that `rustc` is present and that it is >= 1.30.0 struct Wasm32Check {
pub fn check_rustc_version() -> Result<String, Error> { rustc_path: PathBuf,
let local_minor_version = rustc_minor_version(); sysroot: PathBuf,
match local_minor_version { found: bool,
Some(mv) => { is_rustup: bool,
if mv < 30 { }
bail!(
"Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.", impl fmt::Display for Wasm32Check {
mv.to_string() fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let target = "wasm32-unknown-unknown";
if self.found {
let rustup_string = if self.is_rustup {
"It looks like Rustup is being used.".to_owned()
} else {
format!("It looks like Rustup is not being used. For non-Rustup setups, the {} target needs to be installed manually. See https://rustwasm.github.io/wasm-pack/book/prerequisites/index.html#target-wasm32-unknown-unknown on how to do this.", target)
};
writeln!(
f,
"{} target not found in sysroot: {:?}",
target, self.sysroot
) )
.and_then(|_| {
writeln!(
f,
"\nUsed rustc from the following path: {:?}",
self.rustc_path
)
})
.and_then(|_| writeln!(f, "{}", rustup_string))
} else { } else {
Ok(mv.to_string()) write!(
} f,
"sysroot: {:?}, rustc path: {:?}, was found: {}, isRustup: {}",
self.sysroot, self.rustc_path, self.found, self.is_rustup
)
} }
None => bail!("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."),
} }
} }
// from https://github.com/alexcrichton/proc-macro2/blob/79e40a113b51836f33214c6d00228934b41bd4ad/build.rs#L44-L61 /// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for
fn rustc_minor_version() -> Option<u32> { /// current toolchain
macro_rules! otry { pub fn check_for_wasm32_target() -> Result<(), Error> {
($e:expr) => { let msg = format!("{}Checking for the Wasm target...", emoji::TARGET);
match $e { PBAR.info(&msg);
Some(e) => e,
None => return None, // Check if wasm32 target is present, otherwise bail.
} match check_wasm32_target() {
}; Ok(ref wasm32_check) if wasm32_check.found => Ok(()),
} Ok(wasm32_check) => bail!("{}", wasm32_check),
let output = otry!(Command::new("rustc").arg("--version").output().ok()); Err(err) => Err(err),
let version = otry!(str::from_utf8(&output.stdout).ok());
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
} }
otry!(pieces.next()).parse().ok()
} }
/// Get rustc's sysroot as a PathBuf /// Get rustc's sysroot as a PathBuf
@ -81,47 +97,6 @@ fn is_wasm32_target_in_sysroot(sysroot: &PathBuf) -> bool {
} }
} }
struct Wasm32Check {
rustc_path: PathBuf,
sysroot: PathBuf,
found: bool,
is_rustup: bool,
}
impl fmt::Display for Wasm32Check {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let target = "wasm32-unknown-unknown";
if self.found {
let rustup_string = if self.is_rustup {
"It looks like Rustup is being used.".to_owned()
} else {
format!("It looks like Rustup is not being used. For non-Rustup setups, the {} target needs to be installed manually. See https://rustwasm.github.io/wasm-pack/book/prerequisites/index.html#target-wasm32-unknown-unknown on how to do this.", target)
};
writeln!(
f,
"{} target not found in sysroot: {:?}",
target, self.sysroot
)
.and_then(|_| {
writeln!(
f,
"\nUsed rustc from the following path: {:?}",
self.rustc_path
)
})
.and_then(|_| writeln!(f, "{}", rustup_string))
} else {
write!(
f,
"sysroot: {:?}, rustc path: {:?}, was found: {}, isRustup: {}",
self.sysroot, self.rustc_path, self.found, self.is_rustup
)
}
}
}
fn check_wasm32_target() -> Result<Wasm32Check, Error> { fn check_wasm32_target() -> Result<Wasm32Check, Error> {
let sysroot = get_rustc_sysroot()?; let sysroot = get_rustc_sysroot()?;
let rustc_path = which::which("rustc")?; let rustc_path = which::which("rustc")?;
@ -164,65 +139,3 @@ fn rustup_add_wasm_target() -> Result<(), Error> {
Ok(()) Ok(())
} }
/// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for
/// current toolchain
pub fn check_for_wasm32_target() -> Result<(), Error> {
let msg = format!("{}Checking for the Wasm target...", emoji::TARGET);
PBAR.info(&msg);
// Check if wasm32 target is present, otherwise bail.
match check_wasm32_target() {
Ok(ref wasm32_check) if wasm32_check.found => Ok(()),
Ok(wasm32_check) => bail!("{}", wasm32_check),
Err(err) => Err(err),
}
}
/// Run `cargo build` targetting `wasm32-unknown-unknown`.
pub fn cargo_build_wasm(
path: &Path,
profile: BuildProfile,
extra_options: &Vec<String>,
) -> Result<(), Error> {
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");
match profile {
BuildProfile::Profiling => {
// Once there are DWARF debug info consumers, force enable debug
// info, because builds that use the release cargo profile disables
// debug info.
//
// cmd.env("RUSTFLAGS", "-g");
cmd.arg("--release");
}
BuildProfile::Release => {
cmd.arg("--release");
}
BuildProfile::Dev => {
// Plain cargo builds use the dev cargo profile, which includes
// debug info by default.
}
}
cmd.arg("--target").arg("wasm32-unknown-unknown");
cmd.args(extra_options);
child::run(cmd, "cargo build").context("Compiling your crate to WebAssembly failed")?;
Ok(())
}
/// Run `cargo build --tests` targetting `wasm32-unknown-unknown`.
///
/// This generates the `Cargo.lock` file that we use in order to know which version of
/// wasm-bindgen-cli to use when running tests.
pub fn cargo_build_wasm_tests(path: &Path, debug: bool) -> Result<(), Error> {
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");
child::run(cmd, "cargo build").context("Compilation of your program failed")?;
Ok(())
}

@ -299,7 +299,7 @@ impl Build {
fn step_check_for_wasm_target(&mut self) -> Result<(), Error> { fn step_check_for_wasm_target(&mut self) -> Result<(), Error> {
info!("Checking for wasm-target..."); info!("Checking for wasm-target...");
build::check_for_wasm32_target()?; build::wasm_target::check_for_wasm32_target()?;
info!("Checking for wasm-target was successful."); info!("Checking for wasm-target was successful.");
Ok(()) Ok(())
} }

@ -236,7 +236,7 @@ impl Test {
fn step_check_for_wasm_target(&mut self) -> Result<(), Error> { fn step_check_for_wasm_target(&mut self) -> Result<(), Error> {
info!("Adding wasm-target..."); info!("Adding wasm-target...");
build::check_for_wasm32_target()?; build::wasm_target::check_for_wasm32_target()?;
info!("Adding wasm-target was successful."); info!("Adding wasm-target was successful.");
Ok(()) Ok(())
} }

Loading…
Cancel
Save