]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / compiler / rustc_codegen_cranelift / build_system / build_sysroot.rs
CommitLineData
136023e0
XL
1use std::fs;
2use std::path::{Path, PathBuf};
3use std::process::{self, Command};
4
f2b60f7d 5use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name};
5e7ed085
FG
6use super::utils::{spawn_and_wait, try_hard_link};
7use super::SysrootKind;
136023e0
XL
8
9pub(crate) fn build_sysroot(
10 channel: &str,
11 sysroot_kind: SysrootKind,
12 target_dir: &Path,
f2b60f7d 13 cg_clif_build_dir: &Path,
136023e0
XL
14 host_triple: &str,
15 target_triple: &str,
16) {
f2b60f7d
FG
17 eprintln!("[BUILD] sysroot {:?}", sysroot_kind);
18
136023e0
XL
19 if target_dir.exists() {
20 fs::remove_dir_all(target_dir).unwrap();
21 }
22 fs::create_dir_all(target_dir.join("bin")).unwrap();
23 fs::create_dir_all(target_dir.join("lib")).unwrap();
24
25 // Copy the backend
136023e0 26 let cg_clif_dylib = get_file_name("rustc_codegen_cranelift", "dylib");
923072b8
FG
27 let cg_clif_dylib_path = target_dir
28 .join(if cfg!(windows) {
29 // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
30 // binaries.
31 "bin"
32 } else {
33 "lib"
34 })
35 .join(&cg_clif_dylib);
36 try_hard_link(cg_clif_build_dir.join(cg_clif_dylib), &cg_clif_dylib_path);
37
38 // Build and copy rustc and cargo wrappers
39 for wrapper in ["rustc-clif", "cargo-clif"] {
f2b60f7d
FG
40 let wrapper_name = get_wrapper_file_name(wrapper, "bin");
41
923072b8
FG
42 let mut build_cargo_wrapper_cmd = Command::new("rustc");
43 build_cargo_wrapper_cmd
44 .arg(PathBuf::from("scripts").join(format!("{wrapper}.rs")))
45 .arg("-o")
f2b60f7d 46 .arg(target_dir.join(wrapper_name))
923072b8
FG
47 .arg("-g");
48 spawn_and_wait(build_cargo_wrapper_cmd);
49 }
136023e0 50
5e7ed085 51 let default_sysroot = super::rustc_info::get_default_sysroot();
136023e0
XL
52
53 let rustlib = target_dir.join("lib").join("rustlib");
54 let host_rustlib_lib = rustlib.join(host_triple).join("lib");
55 let target_rustlib_lib = rustlib.join(target_triple).join("lib");
56 fs::create_dir_all(&host_rustlib_lib).unwrap();
57 fs::create_dir_all(&target_rustlib_lib).unwrap();
58
59 if target_triple == "x86_64-pc-windows-gnu" {
60 if !default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib").exists() {
61 eprintln!(
62 "The x86_64-pc-windows-gnu target needs to be installed first before it is possible \
63 to compile a sysroot for it.",
64 );
65 process::exit(1);
66 }
67 for file in fs::read_dir(
68 default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
69 )
70 .unwrap()
71 {
72 let file = file.unwrap().path();
73 if file.extension().map_or(true, |ext| ext.to_str().unwrap() != "o") {
74 continue; // only copy object files
75 }
76 try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
77 }
78 }
79
80 match sysroot_kind {
81 SysrootKind::None => {} // Nothing to do
82 SysrootKind::Llvm => {
83 for file in fs::read_dir(
84 default_sysroot.join("lib").join("rustlib").join(host_triple).join("lib"),
85 )
86 .unwrap()
87 {
88 let file = file.unwrap().path();
89 let file_name_str = file.file_name().unwrap().to_str().unwrap();
94222f64
XL
90 if (file_name_str.contains("rustc_")
91 && !file_name_str.contains("rustc_std_workspace_")
92 && !file_name_str.contains("rustc_demangle"))
136023e0
XL
93 || file_name_str.contains("chalk")
94 || file_name_str.contains("tracing")
95 || file_name_str.contains("regex")
96 {
97 // These are large crates that are part of the rustc-dev component and are not
98 // necessary to run regular programs.
99 continue;
100 }
101 try_hard_link(&file, host_rustlib_lib.join(file.file_name().unwrap()));
102 }
103
104 if target_triple != host_triple {
105 for file in fs::read_dir(
106 default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
107 )
108 .unwrap()
109 {
110 let file = file.unwrap().path();
111 try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
112 }
113 }
114 }
115 SysrootKind::Clif => {
923072b8
FG
116 build_clif_sysroot_for_triple(
117 channel,
118 target_dir,
119 host_triple,
120 &cg_clif_dylib_path,
121 None,
122 );
136023e0
XL
123
124 if host_triple != target_triple {
125 // When cross-compiling it is often necessary to manually pick the right linker
126 let linker = if target_triple == "aarch64-unknown-linux-gnu" {
127 Some("aarch64-linux-gnu-gcc")
128 } else {
129 None
130 };
923072b8
FG
131 build_clif_sysroot_for_triple(
132 channel,
133 target_dir,
134 target_triple,
135 &cg_clif_dylib_path,
136 linker,
137 );
136023e0
XL
138 }
139
140 // Copy std for the host to the lib dir. This is necessary for the jit mode to find
141 // libstd.
142 for file in fs::read_dir(host_rustlib_lib).unwrap() {
143 let file = file.unwrap().path();
923072b8
FG
144 let filename = file.file_name().unwrap().to_str().unwrap();
145 if filename.contains("std-") && !filename.contains(".rlib") {
136023e0
XL
146 try_hard_link(&file, target_dir.join("lib").join(file.file_name().unwrap()));
147 }
148 }
149 }
150 }
151}
152
153fn build_clif_sysroot_for_triple(
154 channel: &str,
155 target_dir: &Path,
156 triple: &str,
923072b8 157 cg_clif_dylib_path: &Path,
136023e0
XL
158 linker: Option<&str>,
159) {
160 match fs::read_to_string(Path::new("build_sysroot").join("rustc_version")) {
161 Err(e) => {
162 eprintln!("Failed to get rustc version for patched sysroot source: {}", e);
163 eprintln!("Hint: Try `./y.rs prepare` to patch the sysroot source");
164 process::exit(1);
165 }
166 Ok(source_version) => {
167 let rustc_version = get_rustc_version();
168 if source_version != rustc_version {
169 eprintln!("The patched sysroot source is outdated");
170 eprintln!("Source version: {}", source_version.trim());
171 eprintln!("Rustc version: {}", rustc_version.trim());
172 eprintln!("Hint: Try `./y.rs prepare` to update the patched sysroot source");
173 process::exit(1);
174 }
175 }
176 }
177
178 let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
179
5e7ed085 180 if !super::config::get_bool("keep_sysroot") {
923072b8
FG
181 // Cleanup the deps dir, but keep build scripts and the incremental cache for faster
182 // recompilation as they are not affected by changes in cg_clif.
183 if build_dir.join("deps").exists() {
184 fs::remove_dir_all(build_dir.join("deps")).unwrap();
136023e0
XL
185 }
186 }
187
188 // Build sysroot
189 let mut build_cmd = Command::new("cargo");
190 build_cmd.arg("build").arg("--target").arg(triple).current_dir("build_sysroot");
923072b8
FG
191 let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
192 rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap()));
136023e0
XL
193 if channel == "release" {
194 build_cmd.arg("--release");
195 rustflags.push_str(" -Zmir-opt-level=3");
196 }
197 if let Some(linker) = linker {
198 use std::fmt::Write;
199 write!(rustflags, " -Clinker={}", linker).unwrap();
200 }
201 build_cmd.env("RUSTFLAGS", rustflags);
a2a8927a 202 build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
136023e0
XL
203 spawn_and_wait(build_cmd);
204
205 // Copy all relevant files to the sysroot
206 for entry in
207 fs::read_dir(Path::new("build_sysroot/target").join(triple).join(channel).join("deps"))
208 .unwrap()
209 {
210 let entry = entry.unwrap();
211 if let Some(ext) = entry.path().extension() {
064997fb 212 if ext == "rmeta" || ext == "d" || ext == "dSYM" || ext == "clif" {
136023e0
XL
213 continue;
214 }
215 } else {
216 continue;
217 };
218 try_hard_link(
219 entry.path(),
220 target_dir.join("lib").join("rustlib").join(triple).join("lib").join(entry.file_name()),
221 );
222 }
223}