Repository navigation
Expand file tree
/
Copy pathbuild.rs
More file actions
101 lines (96 loc) · 3.55 KB
/
Copy pathbuild.rs
File metadata and controls
101 lines (96 loc) · 3.55 KB
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
//! Build script: prepares the build inputs from the `rustup/` submodule.
//!
//! The submodule is a build input only; this crate does not link against the
//! rustup library. It compiles the `rustup-init` binary that the mock server
//! serves and the tests run, and it compiles the mock toolchain binary that
//! goes into the mock toolchain tarballs, exactly like rustup's own test
//! infrastructure does (see `mock_bin` in rustup's `src/test/clitools.rs`).
//!
//! The resulting paths are exported to the crate and its tests as
//! `RUSTUP_INIT_BIN`, `RUSTUP_INIT_SH`, and `MOCK_BIN`.
use std::path::PathBuf;
use std::process::Command;
fn main() {
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let rustup_dir = manifest_dir.join("rustup");
let rustup_manifest = rustup_dir.join("Cargo.toml");
if !rustup_manifest.is_file() {
panic!(
"the rustup/ git submodule is missing or uninitialized; run \
`git submodule update --init` in the rustup-mocks repository root"
);
}
// Re-run when the submodule inputs that affect the build outputs change.
for path in [
"rustup/Cargo.toml",
"rustup/Cargo.lock",
"rustup/rustup-init.sh",
"rustup/src/test/mock_bin_src.rs",
] {
println!("cargo:rerun-if-changed={path}");
}
// Build the rustup-init binary from the submodule (debug profile), for
// the target this crate is being built for, so that the binary matches
// the test harness that runs it (also built for that target).
let target = std::env::var("TARGET").expect("TARGET is always set by cargo");
let status = Command::new("cargo")
.arg("build")
.arg("--manifest-path")
.arg(&rustup_manifest)
.arg("--bin")
.arg("rustup-init")
.arg("--target")
.arg(&target)
.status()
.expect("failed to run `cargo build` for the rustup submodule");
if !status.success() {
panic!("`cargo build` of the rustup submodule failed");
}
let exe_suffix = if target.contains("windows") {
".exe"
} else {
""
};
let rustup_init_bin = rustup_dir
.join("target")
.join(&target)
.join("debug")
.join(format!("rustup-init{exe_suffix}"));
if !rustup_init_bin.is_file() {
panic!(
"the rustup-init binary was not produced at {}",
rustup_init_bin.display()
);
}
println!(
"cargo:rustc-env=RUSTUP_INIT_BIN={}",
rustup_init_bin.display()
);
println!(
"cargo:rustc-env=RUSTUP_INIT_SH={}",
rustup_dir.join("rustup-init.sh").display()
);
// Compile the mock toolchain binary (the rustc/cargo/... executables that
// go into the mock toolchain tarballs).
let mock_bin_src = rustup_dir.join("src/test/mock_bin_src.rs");
let mock_bin = PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("mock-bin");
let status = Command::new("rustc")
.arg(&mock_bin_src)
.arg("-Cpanic=abort")
.arg("-O")
.arg("--target")
.arg(&target)
.arg("-o")
.arg(&mock_bin)
.status()
.expect("failed to run `rustc` for the mock toolchain binary");
if !status.success() {
panic!("`rustc` of the mock toolchain binary failed");
}
// Remove debug info from the binary (best effort), like rustup's
// `mock_bin` does.
if cfg!(unix) {
drop(Command::new("strip").arg(&mock_bin).status());
}
println!("cargo:rustc-env=MOCK_BIN={}", mock_bin.display());
}