-
Notifications
You must be signed in to change notification settings - Fork 428
/
Copy pathmod.rs
193 lines (163 loc) · 6.01 KB
/
mod.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//! Building a Rust crate into a `.wasm` binary.
use crate::child;
use crate::command::build::BuildProfile;
use crate::emoji;
use crate::manifest::Crate;
use crate::PBAR;
use anyhow::{bail, Context, Result};
use std::path::Path;
use std::process::Command;
use std::str;
pub mod wasm_target;
/// Used when comparing the currently installed
/// wasm-pack version with the latest on crates.io.
pub struct WasmPackVersion {
/// The currently installed wasm-pack version.
pub local: String,
/// The latest version of wasm-pack that's released at
/// crates.io.
pub latest: String,
}
/// Ensure that `rustc` is present and that it is >= 1.30.0
pub fn check_rustc_version() -> Result<String> {
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()
}
/// Checks and returns local and latest versions of wasm-pack
pub fn check_wasm_pack_versions() -> Result<WasmPackVersion> {
match wasm_pack_local_version() {
Some(local) => Ok(WasmPackVersion {local, latest: Crate::return_wasm_pack_latest_version()?.unwrap_or_else(|| "".to_string())}),
None => bail!("We can't figure out what your wasm-pack version is, make sure the installation path is correct.")
}
}
fn wasm_pack_local_version() -> Option<String> {
let output = env!("CARGO_PKG_VERSION");
Some(output.to_string())
}
/// Run `cargo rustc` targetting `wasm32-unknown-unknown`.
pub fn cargo_build_wasm(
path: &Path,
profile: BuildProfile,
extra_options: &[String],
) -> Result<()> {
let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE);
PBAR.info(&msg);
let mut cmd = Command::new("cargo");
// Use rustc to allow crate-type flag to be added
cmd.current_dir(path).arg("rustc").arg("--lib");
if PBAR.quiet() {
cmd.arg("--quiet");
}
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 => {
// cargo rustc, like cargo build, uses the dev cargo profile which includes
// debug info by default.
}
}
add_crate_type(&mut cmd, extra_options);
cmd.arg("--target").arg("wasm32-unknown-unknown");
cmd.args(extra_options);
child::run(cmd, "cargo rustc").context("Compiling your crate to WebAssembly failed")?;
Ok(())
}
/// Runs `cargo build --tests` targeting `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.
///
/// Note that the command to build tests and the command to run tests must use the same parameters, i.e. features to be
/// disabled / enabled must be consistent for both `cargo rustc` and `cargo test`.
///
/// # Parameters
///
/// * `path`: Path to the crate directory to build tests.
/// * `debug`: Whether to build tests in `debug` mode.
/// * `extra_options`: Additional parameters to pass to `cargo` when building tests.
pub fn cargo_build_wasm_tests(path: &Path, debug: bool, extra_options: &[String]) -> Result<()> {
let mut cmd = Command::new("cargo");
cmd.current_dir(path).arg("build").arg("--tests");
if PBAR.quiet() {
cmd.arg("--quiet");
}
if !debug {
cmd.arg("--release");
}
cmd.arg("--target").arg("wasm32-unknown-unknown");
cmd.args(extra_options);
child::run(cmd, "cargo rustc").context("Compilation of your program failed")?;
Ok(())
}
/// Adds --crate-type option to cargo rustc command, allowing users to build without specifying cdylib
/// in Cargo.toml
fn add_crate_type(cmd: &mut Command, extra_options: &[String]) {
// Avoid setting crate type flag twice if provided in extra options
if extra_options.iter().any(|opt| opt.contains("--crate-type")) {
return;
}
cmd.arg("--crate-type").arg("cdylib");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adds_crate_type_flag_if_not_in_extra_opts() {
let mut cmd = Command::new("cargo");
let extra_options = vec![String::from("--crate-type dylib")];
add_crate_type(&mut cmd, &extra_options);
assert!(!cmd
.get_args()
.any(|arg| arg.to_str().unwrap() == "--crate-type"));
assert!(!cmd.get_args().any(|arg| arg.to_str().unwrap() == "cdylib"));
}
#[test]
fn does_not_add_crate_type_flag_if_in_extra_opts() {
let mut cmd = Command::new("cargo");
let extra_options = vec![];
add_crate_type(&mut cmd, &extra_options);
assert!(cmd
.get_args()
.any(|arg| arg.to_str().unwrap() == "--crate-type"));
assert!(cmd.get_args().any(|arg| arg.to_str().unwrap() == "cdylib"));
}
}