-
Notifications
You must be signed in to change notification settings - Fork 409
/
wasm_target.rs
171 lines (154 loc) · 5 KB
/
wasm_target.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
//! Checking for the wasm32 target
use crate::child;
use crate::emoji;
use crate::PBAR;
use anyhow::{anyhow, bail, Context, Result};
use log::error;
use log::info;
use std::fmt;
use std::path::PathBuf;
use std::process::Command;
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/non-rustup-setups.html 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<()> {
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> {
let command = Command::new("rustc")
.args(&["--print", "sysroot"])
.output()?;
if command.status.success() {
Ok(String::from_utf8(command.stdout)?.trim().into())
} else {
Err(anyhow!(
"Getting rustc's sysroot wasn't successful. Got {}",
command.status
))
}
}
/// Get wasm32-unknown-unknown target libdir
fn get_rustc_wasm32_unknown_unknown_target_libdir() -> Result<PathBuf> {
let command = Command::new("rustc")
.args(&[
"--target",
"wasm32-unknown-unknown",
"--print",
"target-libdir",
])
.output()?;
if command.status.success() {
Ok(String::from_utf8(command.stdout)?.trim().into())
} else {
Err(anyhow!(
"Getting rustc's wasm32-unknown-unknown target wasn't successful. Got {}",
command.status
))
}
}
fn does_wasm32_target_libdir_exist() -> bool {
let result = get_rustc_wasm32_unknown_unknown_target_libdir();
match result {
Ok(wasm32_target_libdir_path) => {
if wasm32_target_libdir_path.exists() {
info!(
"Found wasm32-unknown-unknown in {:?}",
wasm32_target_libdir_path
);
true
} else {
info!(
"Failed to find wasm32-unknown-unknown in {:?}",
wasm32_target_libdir_path
);
false
}
}
Err(_) => {
error!("Some error in getting the target libdir!");
false
}
}
}
fn check_wasm32_target() -> Result<Wasm32Check> {
let sysroot = get_rustc_sysroot()?;
let rustc_path = which::which("rustc")?;
if does_wasm32_target_libdir_exist() {
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<()> {
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(())
}