commit
3ccaee1abf
@ -0,0 +1,141 @@ |
||||
//! Checking for the wasm32 target
|
||||
|
||||
use child; |
||||
use emoji; |
||||
use failure::{Error, ResultExt}; |
||||
use log::info; |
||||
use std::fmt; |
||||
use std::path::PathBuf; |
||||
use std::process::Command; |
||||
use PBAR; |
||||
|
||||
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 |
||||
) |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// 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), |
||||
} |
||||
} |
||||
|
||||
/// Get rustc's sysroot as a PathBuf
|
||||
fn get_rustc_sysroot() -> Result<PathBuf, Error> { |
||||
let command = Command::new("rustc") |
||||
.args(&["--print", "sysroot"]) |
||||
.output()?; |
||||
|
||||
if command.status.success() { |
||||
Ok(String::from_utf8(command.stdout)?.trim().into()) |
||||
} else { |
||||
Err(format_err!( |
||||
"Getting rustc's sysroot wasn't successful. Got {}", |
||||
command.status |
||||
)) |
||||
} |
||||
} |
||||
|
||||
/// Checks if the wasm32-unknown-unknown is present in rustc's sysroot.
|
||||
fn is_wasm32_target_in_sysroot(sysroot: &PathBuf) -> bool { |
||||
let wasm32_target = "wasm32-unknown-unknown"; |
||||
|
||||
let rustlib_path = sysroot.join("lib/rustlib"); |
||||
|
||||
info!("Looking for {} in {:?}", wasm32_target, rustlib_path); |
||||
|
||||
if rustlib_path.join(wasm32_target).exists() { |
||||
info!("Found {} in {:?}", wasm32_target, rustlib_path); |
||||
true |
||||
} else { |
||||
info!("Failed to find {} in {:?}", wasm32_target, rustlib_path); |
||||
false |
||||
} |
||||
} |
||||
|
||||
fn check_wasm32_target() -> Result<Wasm32Check, Error> { |
||||
let sysroot = get_rustc_sysroot()?; |
||||
let rustc_path = which::which("rustc")?; |
||||
|
||||
// If wasm32-unknown-unknown already exists we're ok.
|
||||
if is_wasm32_target_in_sysroot(&sysroot) { |
||||
Ok(Wasm32Check { |
||||
rustc_path, |
||||
sysroot, |
||||
found: true, |
||||
is_rustup: false, |
||||
}) |
||||
// If it doesn't exist, then we need to check if we're using rustup.
|
||||
} else { |
||||
// If sysroot contains .rustup, then we can assume we're using rustup
|
||||
// and use rustup to add the wasm32-unknown-unknown target.
|
||||
if sysroot.to_string_lossy().contains(".rustup") { |
||||
rustup_add_wasm_target().map(|()| Wasm32Check { |
||||
rustc_path, |
||||
sysroot, |
||||
found: true, |
||||
is_rustup: true, |
||||
}) |
||||
} else { |
||||
Ok(Wasm32Check { |
||||
rustc_path, |
||||
sysroot, |
||||
found: false, |
||||
is_rustup: false, |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// Add wasm32-unknown-unknown using `rustup`.
|
||||
fn rustup_add_wasm_target() -> Result<(), Error> { |
||||
let mut cmd = Command::new("rustup"); |
||||
cmd.arg("target").arg("add").arg("wasm32-unknown-unknown"); |
||||
child::run(cmd, "rustup").context("Adding the wasm32-unknown-unknown target with rustup")?; |
||||
|
||||
Ok(()) |
||||
} |
Loading…
Reference in new issue