Skip to content

Commit 611c518

Browse files
authored
Merge pull request #1341 from bjorn3/build_sysroot_cleanup
Refactor sysroot building
2 parents b31b74e + 0f4df8f commit 611c518

File tree

5 files changed

+172
-142
lines changed

5 files changed

+172
-142
lines changed

.github/workflows/main.yml

-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ jobs:
7777
run: |
7878
sudo apt-get update
7979
sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable
80-
rustup target add x86_64-pc-windows-gnu
8180
8281
- name: Install AArch64 toolchain and qemu
8382
if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'aarch64-unknown-linux-gnu'

build_system/bench.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::path::Path;
44

55
use super::path::{Dirs, RelPath};
66
use super::prepare::GitRepo;
7-
use super::rustc_info::{get_file_name, get_wrapper_file_name};
7+
use super::rustc_info::get_file_name;
88
use super::utils::{hyperfine_command, is_ci, spawn_and_wait, CargoProject, Compiler};
99

1010
pub(crate) static SIMPLE_RAYTRACER_REPO: GitRepo = GitRepo::github(
@@ -51,7 +51,8 @@ fn benchmark_simple_raytracer(dirs: &Dirs, bootstrap_host_compiler: &Compiler) {
5151
.unwrap();
5252

5353
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
54-
let cargo_clif = RelPath::DIST.to_path(dirs).join(get_wrapper_file_name("cargo-clif", "bin"));
54+
let cargo_clif =
55+
RelPath::DIST.to_path(dirs).join(get_file_name("cargo_clif", "bin").replace('_', "-"));
5556
let manifest_path = SIMPLE_RAYTRACER.manifest_path(dirs);
5657
let target_dir = SIMPLE_RAYTRACER.target_dir(dirs);
5758

build_system/build_sysroot.rs

+168-112
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
use std::fs;
2-
use std::path::Path;
2+
use std::path::{Path, PathBuf};
33
use std::process::{self, Command};
44

55
use super::path::{Dirs, RelPath};
6-
use super::rustc_info::{
7-
get_file_name, get_rustc_version, get_toolchain_name, get_wrapper_file_name,
8-
};
6+
use super::rustc_info::{get_file_name, get_rustc_version, get_toolchain_name};
97
use super::utils::{spawn_and_wait, try_hard_link, CargoProject, Compiler};
108
use super::SysrootKind;
119

1210
static DIST_DIR: RelPath = RelPath::DIST;
1311
static BIN_DIR: RelPath = RelPath::DIST.join("bin");
1412
static LIB_DIR: RelPath = RelPath::DIST.join("lib");
15-
static RUSTLIB_DIR: RelPath = LIB_DIR.join("rustlib");
1613

1714
pub(crate) fn build_sysroot(
1815
dirs: &Dirs,
@@ -39,145 +36,169 @@ pub(crate) fn build_sysroot(
3936
LIB_DIR
4037
}
4138
.to_path(dirs)
42-
.join(get_file_name("rustc_codegen_cranelift", "dylib"));
39+
.join(cg_clif_dylib_src.file_name().unwrap());
4340
try_hard_link(cg_clif_dylib_src, &cg_clif_dylib_path);
4441

4542
// Build and copy rustc and cargo wrappers
43+
let wrapper_base_name = get_file_name("____", "bin");
44+
let toolchain_name = get_toolchain_name();
4645
for wrapper in ["rustc-clif", "rustdoc-clif", "cargo-clif"] {
47-
let wrapper_name = get_wrapper_file_name(wrapper, "bin");
46+
let wrapper_name = wrapper_base_name.replace("____", wrapper);
4847

4948
let mut build_cargo_wrapper_cmd = Command::new(&bootstrap_host_compiler.rustc);
5049
build_cargo_wrapper_cmd
51-
.env("TOOLCHAIN_NAME", get_toolchain_name())
50+
.env("TOOLCHAIN_NAME", toolchain_name.clone())
5251
.arg(RelPath::SCRIPTS.to_path(dirs).join(&format!("{wrapper}.rs")))
5352
.arg("-o")
5453
.arg(DIST_DIR.to_path(dirs).join(wrapper_name))
55-
.arg("-g");
54+
.arg("-Cstrip=debuginfo");
5655
spawn_and_wait(build_cargo_wrapper_cmd);
5756
}
5857

59-
let default_sysroot = super::rustc_info::get_default_sysroot(&bootstrap_host_compiler.rustc);
58+
let host = build_sysroot_for_triple(
59+
dirs,
60+
channel,
61+
bootstrap_host_compiler.clone(),
62+
&cg_clif_dylib_path,
63+
sysroot_kind,
64+
);
65+
host.install_into_sysroot(&DIST_DIR.to_path(dirs));
6066

61-
let host_rustlib_lib =
62-
RUSTLIB_DIR.to_path(dirs).join(&bootstrap_host_compiler.triple).join("lib");
63-
let target_rustlib_lib = RUSTLIB_DIR.to_path(dirs).join(&target_triple).join("lib");
64-
fs::create_dir_all(&host_rustlib_lib).unwrap();
65-
fs::create_dir_all(&target_rustlib_lib).unwrap();
66-
67-
if target_triple == "x86_64-pc-windows-gnu" {
68-
if !default_sysroot.join("lib").join("rustlib").join(&target_triple).join("lib").exists() {
69-
eprintln!(
70-
"The x86_64-pc-windows-gnu target needs to be installed first before it is possible \
71-
to compile a sysroot for it.",
72-
);
73-
process::exit(1);
74-
}
75-
for file in fs::read_dir(
76-
default_sysroot.join("lib").join("rustlib").join(&target_triple).join("lib"),
67+
if !is_native {
68+
build_sysroot_for_triple(
69+
dirs,
70+
channel,
71+
{
72+
let mut bootstrap_target_compiler = bootstrap_host_compiler.clone();
73+
bootstrap_target_compiler.triple = target_triple.clone();
74+
bootstrap_target_compiler.set_cross_linker_and_runner();
75+
bootstrap_target_compiler
76+
},
77+
&cg_clif_dylib_path,
78+
sysroot_kind,
7779
)
78-
.unwrap()
79-
{
80-
let file = file.unwrap().path();
81-
if file.extension().map_or(true, |ext| ext.to_str().unwrap() != "o") {
82-
continue; // only copy object files
83-
}
84-
try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
85-
}
80+
.install_into_sysroot(&DIST_DIR.to_path(dirs));
8681
}
8782

88-
match sysroot_kind {
89-
SysrootKind::None => {} // Nothing to do
90-
SysrootKind::Llvm => {
91-
for file in fs::read_dir(
92-
default_sysroot
93-
.join("lib")
94-
.join("rustlib")
95-
.join(&bootstrap_host_compiler.triple)
96-
.join("lib"),
97-
)
98-
.unwrap()
99-
{
100-
let file = file.unwrap().path();
101-
let file_name_str = file.file_name().unwrap().to_str().unwrap();
102-
if (file_name_str.contains("rustc_")
103-
&& !file_name_str.contains("rustc_std_workspace_")
104-
&& !file_name_str.contains("rustc_demangle"))
105-
|| file_name_str.contains("chalk")
106-
|| file_name_str.contains("tracing")
107-
|| file_name_str.contains("regex")
108-
{
109-
// These are large crates that are part of the rustc-dev component and are not
110-
// necessary to run regular programs.
111-
continue;
112-
}
113-
try_hard_link(&file, host_rustlib_lib.join(file.file_name().unwrap()));
114-
}
115-
116-
if !is_native {
117-
for file in fs::read_dir(
118-
default_sysroot.join("lib").join("rustlib").join(&target_triple).join("lib"),
119-
)
120-
.unwrap()
121-
{
122-
let file = file.unwrap().path();
123-
try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
124-
}
125-
}
126-
}
127-
SysrootKind::Clif => {
128-
build_clif_sysroot_for_triple(
129-
dirs,
130-
channel,
131-
bootstrap_host_compiler.clone(),
132-
&cg_clif_dylib_path,
133-
);
134-
135-
if !is_native {
136-
build_clif_sysroot_for_triple(
137-
dirs,
138-
channel,
139-
{
140-
let mut bootstrap_target_compiler = bootstrap_host_compiler.clone();
141-
bootstrap_target_compiler.triple = target_triple.clone();
142-
bootstrap_target_compiler.set_cross_linker_and_runner();
143-
bootstrap_target_compiler
144-
},
145-
&cg_clif_dylib_path,
146-
);
147-
}
148-
149-
// Copy std for the host to the lib dir. This is necessary for the jit mode to find
150-
// libstd.
151-
for file in fs::read_dir(host_rustlib_lib).unwrap() {
152-
let file = file.unwrap().path();
153-
let filename = file.file_name().unwrap().to_str().unwrap();
154-
if filename.contains("std-") && !filename.contains(".rlib") {
155-
try_hard_link(&file, LIB_DIR.to_path(dirs).join(file.file_name().unwrap()));
156-
}
157-
}
83+
// Copy std for the host to the lib dir. This is necessary for the jit mode to find
84+
// libstd.
85+
for lib in host.libs {
86+
let filename = lib.file_name().unwrap().to_str().unwrap();
87+
if filename.contains("std-") && !filename.contains(".rlib") {
88+
try_hard_link(&lib, LIB_DIR.to_path(dirs).join(lib.file_name().unwrap()));
15889
}
15990
}
16091

161-
let mut target_compiler = Compiler::clif_with_triple(&dirs, target_triple);
92+
let mut target_compiler = {
93+
let dirs: &Dirs = &dirs;
94+
let rustc_clif =
95+
RelPath::DIST.to_path(&dirs).join(wrapper_base_name.replace("____", "rustc-clif"));
96+
let rustdoc_clif =
97+
RelPath::DIST.to_path(&dirs).join(wrapper_base_name.replace("____", "rustdoc-clif"));
98+
99+
Compiler {
100+
cargo: bootstrap_host_compiler.cargo.clone(),
101+
rustc: rustc_clif.clone(),
102+
rustdoc: rustdoc_clif.clone(),
103+
rustflags: String::new(),
104+
rustdocflags: String::new(),
105+
triple: target_triple,
106+
runner: vec![],
107+
}
108+
};
162109
if !is_native {
163110
target_compiler.set_cross_linker_and_runner();
164111
}
165112
target_compiler
166113
}
167114

115+
struct SysrootTarget {
116+
triple: String,
117+
libs: Vec<PathBuf>,
118+
}
119+
120+
impl SysrootTarget {
121+
fn install_into_sysroot(&self, sysroot: &Path) {
122+
if self.libs.is_empty() {
123+
return;
124+
}
125+
126+
let target_rustlib_lib = sysroot.join("lib").join("rustlib").join(&self.triple).join("lib");
127+
fs::create_dir_all(&target_rustlib_lib).unwrap();
128+
129+
for lib in &self.libs {
130+
try_hard_link(lib, target_rustlib_lib.join(lib.file_name().unwrap()));
131+
}
132+
}
133+
}
134+
168135
pub(crate) static ORIG_BUILD_SYSROOT: RelPath = RelPath::SOURCE.join("build_sysroot");
169136
pub(crate) static BUILD_SYSROOT: RelPath = RelPath::DOWNLOAD.join("sysroot");
170137
pub(crate) static SYSROOT_RUSTC_VERSION: RelPath = BUILD_SYSROOT.join("rustc_version");
171138
pub(crate) static SYSROOT_SRC: RelPath = BUILD_SYSROOT.join("sysroot_src");
172139
pub(crate) static STANDARD_LIBRARY: CargoProject =
173140
CargoProject::new(&BUILD_SYSROOT, "build_sysroot");
141+
pub(crate) static RTSTARTUP_SYSROOT: RelPath = RelPath::BUILD.join("rtstartup");
174142

143+
#[must_use]
144+
fn build_sysroot_for_triple(
145+
dirs: &Dirs,
146+
channel: &str,
147+
compiler: Compiler,
148+
cg_clif_dylib_path: &Path,
149+
sysroot_kind: SysrootKind,
150+
) -> SysrootTarget {
151+
match sysroot_kind {
152+
SysrootKind::None => build_rtstartup(dirs, &compiler)
153+
.unwrap_or(SysrootTarget { triple: compiler.triple, libs: vec![] }),
154+
SysrootKind::Llvm => build_llvm_sysroot_for_triple(compiler),
155+
SysrootKind::Clif => {
156+
build_clif_sysroot_for_triple(dirs, channel, compiler, &cg_clif_dylib_path)
157+
}
158+
}
159+
}
160+
161+
#[must_use]
162+
fn build_llvm_sysroot_for_triple(compiler: Compiler) -> SysrootTarget {
163+
let default_sysroot = super::rustc_info::get_default_sysroot(&compiler.rustc);
164+
165+
let mut target_libs = SysrootTarget { triple: compiler.triple, libs: vec![] };
166+
167+
for entry in fs::read_dir(
168+
default_sysroot.join("lib").join("rustlib").join(&target_libs.triple).join("lib"),
169+
)
170+
.unwrap()
171+
{
172+
let entry = entry.unwrap();
173+
if entry.file_type().unwrap().is_dir() {
174+
continue;
175+
}
176+
let file = entry.path();
177+
let file_name_str = file.file_name().unwrap().to_str().unwrap();
178+
if (file_name_str.contains("rustc_")
179+
&& !file_name_str.contains("rustc_std_workspace_")
180+
&& !file_name_str.contains("rustc_demangle"))
181+
|| file_name_str.contains("chalk")
182+
|| file_name_str.contains("tracing")
183+
|| file_name_str.contains("regex")
184+
{
185+
// These are large crates that are part of the rustc-dev component and are not
186+
// necessary to run regular programs.
187+
continue;
188+
}
189+
target_libs.libs.push(file);
190+
}
191+
192+
target_libs
193+
}
194+
195+
#[must_use]
175196
fn build_clif_sysroot_for_triple(
176197
dirs: &Dirs,
177198
channel: &str,
178199
mut compiler: Compiler,
179200
cg_clif_dylib_path: &Path,
180-
) {
201+
) -> SysrootTarget {
181202
match fs::read_to_string(SYSROOT_RUSTC_VERSION.to_path(dirs)) {
182203
Err(e) => {
183204
eprintln!("Failed to get rustc version for patched sysroot source: {}", e);
@@ -196,6 +217,14 @@ fn build_clif_sysroot_for_triple(
196217
}
197218
}
198219

220+
let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] };
221+
222+
if let Some(rtstartup_target_libs) = build_rtstartup(dirs, &compiler) {
223+
rtstartup_target_libs.install_into_sysroot(&RTSTARTUP_SYSROOT.to_path(dirs));
224+
225+
target_libs.libs.extend(rtstartup_target_libs.libs);
226+
}
227+
199228
let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(&compiler.triple).join(channel);
200229

201230
if !super::config::get_bool("keep_sysroot") {
@@ -209,7 +238,9 @@ fn build_clif_sysroot_for_triple(
209238
// Build sysroot
210239
let mut rustflags = " -Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
211240
rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap()));
212-
rustflags.push_str(&format!(" --sysroot={}", DIST_DIR.to_path(dirs).to_str().unwrap()));
241+
// Necessary for MinGW to find rsbegin.o and rsend.o
242+
rustflags
243+
.push_str(&format!(" --sysroot={}", RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap()));
213244
if channel == "release" {
214245
rustflags.push_str(" -Zmir-opt-level=3");
215246
}
@@ -221,7 +252,6 @@ fn build_clif_sysroot_for_triple(
221252
build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
222253
spawn_and_wait(build_cmd);
223254

224-
// Copy all relevant files to the sysroot
225255
for entry in fs::read_dir(build_dir.join("deps")).unwrap() {
226256
let entry = entry.unwrap();
227257
if let Some(ext) = entry.path().extension() {
@@ -231,9 +261,35 @@ fn build_clif_sysroot_for_triple(
231261
} else {
232262
continue;
233263
};
234-
try_hard_link(
235-
entry.path(),
236-
RUSTLIB_DIR.to_path(dirs).join(&compiler.triple).join("lib").join(entry.file_name()),
237-
);
264+
target_libs.libs.push(entry.path());
265+
}
266+
267+
target_libs
268+
}
269+
270+
fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option<SysrootTarget> {
271+
if !compiler.triple.ends_with("windows-gnu") {
272+
return None;
273+
}
274+
275+
RTSTARTUP_SYSROOT.ensure_fresh(dirs);
276+
277+
let rtstartup_src = SYSROOT_SRC.to_path(dirs).join("library").join("rtstartup");
278+
let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] };
279+
280+
for file in ["rsbegin", "rsend"] {
281+
let obj = RTSTARTUP_SYSROOT.to_path(dirs).join(format!("{file}.o"));
282+
let mut build_rtstartup_cmd = Command::new(&compiler.rustc);
283+
build_rtstartup_cmd
284+
.arg("--target")
285+
.arg(&compiler.triple)
286+
.arg("--emit=obj")
287+
.arg("-o")
288+
.arg(&obj)
289+
.arg(rtstartup_src.join(format!("{file}.rs")));
290+
spawn_and_wait(build_rtstartup_cmd);
291+
target_libs.libs.push(obj.clone());
238292
}
293+
294+
Some(target_libs)
239295
}

0 commit comments

Comments
 (0)