]>
Commit | Line | Data |
---|---|---|
a7813a04 XL |
1 | //! Implementation of the various distribution aspects of the compiler. |
2 | //! | |
3 | //! This module is responsible for creating tarballs of the standard library, | |
4 | //! compiler, and documentation. This ends up being what we distribute to | |
5 | //! everyone as well. | |
6 | //! | |
7 | //! No tarball is actually created literally in this file, but rather we shell | |
8 | //! out to `rust-installer` still. This may one day be replaced with bits and | |
9 | //! pieces of `rustup.rs`! | |
10 | ||
94222f64 | 11 | use std::collections::HashSet; |
32a655c1 | 12 | use std::env; |
487cf647 | 13 | use std::ffi::OsStr; |
0731742a | 14 | use std::fs; |
dfeec247 | 15 | use std::path::{Path, PathBuf}; |
29967ef6 | 16 | use std::process::Command; |
32a655c1 | 17 | |
487cf647 FG |
18 | use object::read::archive::ArchiveFile; |
19 | use object::BinaryFormat; | |
20 | ||
5099ac24 | 21 | use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; |
dfeec247 | 22 | use crate::cache::{Interned, INTERNER}; |
2b03887a | 23 | use crate::channel; |
0731742a | 24 | use crate::compile; |
3dfed10e | 25 | use crate::config::TargetSelection; |
487cf647 | 26 | use crate::doc::DocumentationFormat; |
fc512014 | 27 | use crate::tarball::{GeneratedTarball, OverlayKind, Tarball}; |
0731742a | 28 | use crate::tool::{self, Tool}; |
5e7ed085 | 29 | use crate::util::{exe, is_dylib, output, t, timeit}; |
f035d41b | 30 | use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS}; |
54a0048b | 31 | |
9fa01778 | 32 | pub fn pkgname(builder: &Builder<'_>, component: &str) -> String { |
1b1a35ee | 33 | format!("{}-{}", component, builder.rust_package_vers()) |
32a655c1 SL |
34 | } |
35 | ||
1b1a35ee | 36 | pub(crate) fn distdir(builder: &Builder<'_>) -> PathBuf { |
83c7162d | 37 | builder.out.join("dist") |
54a0048b SL |
38 | } |
39 | ||
9fa01778 | 40 | pub fn tmpdir(builder: &Builder<'_>) -> PathBuf { |
83c7162d | 41 | builder.out.join("tmp/dist") |
54a0048b SL |
42 | } |
43 | ||
94222f64 XL |
44 | fn should_build_extended_tool(builder: &Builder<'_>, tool: &str) -> bool { |
45 | if !builder.config.extended { | |
46 | return false; | |
47 | } | |
48 | builder.config.tools.as_ref().map_or(true, |tools| tools.contains(tool)) | |
49 | } | |
50 | ||
83c7162d | 51 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 | 52 | pub struct Docs { |
3dfed10e | 53 | pub host: TargetSelection, |
3b2f2976 XL |
54 | } |
55 | ||
56 | impl Step for Docs { | |
fc512014 | 57 | type Output = Option<GeneratedTarball>; |
3b2f2976 | 58 | const DEFAULT: bool = true; |
3b2f2976 | 59 | |
9fa01778 | 60 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
94222f64 | 61 | let default = run.builder.config.docs; |
04454e1e | 62 | run.alias("rust-docs").default_condition(default) |
476ff2be SL |
63 | } |
64 | ||
9fa01778 | 65 | fn make_run(run: RunConfig<'_>) { |
dfeec247 | 66 | run.builder.ensure(Docs { host: run.target }); |
3b2f2976 XL |
67 | } |
68 | ||
69 | /// Builds the `rust-docs` installer component. | |
fc512014 | 70 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
3b2f2976 | 71 | let host = self.host; |
6a06907d | 72 | builder.default_doc(&[]); |
3b2f2976 | 73 | |
fc512014 | 74 | let dest = "share/doc/rust/html"; |
e1599b0c | 75 | |
fc512014 XL |
76 | let mut tarball = Tarball::new(builder, "rust-docs", &host.triple); |
77 | tarball.set_product_name("Rust Documentation"); | |
cdc7bbd5 | 78 | tarball.add_bulk_dir(&builder.doc_out(host), dest); |
fc512014 XL |
79 | tarball.add_file(&builder.src.join("src/doc/robots.txt"), dest, 0o644); |
80 | Some(tarball.generate()) | |
0531ce1d XL |
81 | } |
82 | } | |
83 | ||
2b03887a FG |
84 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
85 | pub struct JsonDocs { | |
86 | pub host: TargetSelection, | |
87 | } | |
88 | ||
89 | impl Step for JsonDocs { | |
90 | type Output = Option<GeneratedTarball>; | |
91 | const DEFAULT: bool = true; | |
92 | ||
93 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
94 | let default = run.builder.config.docs; | |
95 | run.alias("rust-docs-json").default_condition(default) | |
96 | } | |
97 | ||
98 | fn make_run(run: RunConfig<'_>) { | |
99 | run.builder.ensure(JsonDocs { host: run.target }); | |
100 | } | |
101 | ||
102 | /// Builds the `rust-docs-json` installer component. | |
103 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { | |
104 | let host = self.host; | |
487cf647 FG |
105 | builder.ensure(crate::doc::Std { |
106 | stage: builder.top_stage, | |
107 | target: host, | |
108 | format: DocumentationFormat::JSON, | |
109 | }); | |
2b03887a FG |
110 | |
111 | let dest = "share/doc/rust/json"; | |
112 | ||
113 | let mut tarball = Tarball::new(builder, "rust-docs-json", &host.triple); | |
114 | tarball.set_product_name("Rust Documentation In JSON Format"); | |
115 | tarball.is_preview(true); | |
116 | tarball.add_bulk_dir(&builder.json_doc_out(host), dest); | |
117 | Some(tarball.generate()) | |
118 | } | |
119 | } | |
120 | ||
0531ce1d XL |
121 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] |
122 | pub struct RustcDocs { | |
3dfed10e | 123 | pub host: TargetSelection, |
0531ce1d XL |
124 | } |
125 | ||
126 | impl Step for RustcDocs { | |
fc512014 | 127 | type Output = Option<GeneratedTarball>; |
0531ce1d XL |
128 | const DEFAULT: bool = true; |
129 | ||
9fa01778 | 130 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
3c0e092e | 131 | let builder = run.builder; |
04454e1e | 132 | run.alias("rustc-docs").default_condition(builder.config.compiler_docs) |
0531ce1d XL |
133 | } |
134 | ||
9fa01778 | 135 | fn make_run(run: RunConfig<'_>) { |
dfeec247 | 136 | run.builder.ensure(RustcDocs { host: run.target }); |
0531ce1d XL |
137 | } |
138 | ||
139 | /// Builds the `rustc-docs` installer component. | |
fc512014 | 140 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
0531ce1d | 141 | let host = self.host; |
6a06907d | 142 | builder.default_doc(&[]); |
0531ce1d | 143 | |
fc512014 XL |
144 | let mut tarball = Tarball::new(builder, "rustc-docs", &host.triple); |
145 | tarball.set_product_name("Rustc Documentation"); | |
cdc7bbd5 | 146 | tarball.add_bulk_dir(&builder.compiler_doc_out(host), "share/doc/rust/html/rustc"); |
fc512014 | 147 | Some(tarball.generate()) |
54a0048b SL |
148 | } |
149 | } | |
150 | ||
7cac9316 | 151 | fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> { |
041b39d2 | 152 | let mut found = Vec::with_capacity(files.len()); |
7cac9316 XL |
153 | |
154 | for file in files { | |
dfeec247 | 155 | let file_path = path.iter().map(|dir| dir.join(file)).find(|p| p.exists()); |
7cac9316 XL |
156 | |
157 | if let Some(file_path) = file_path { | |
158 | found.push(file_path); | |
159 | } else { | |
160 | panic!("Could not find '{}' in {:?}", file, path); | |
161 | } | |
162 | } | |
163 | ||
164 | found | |
165 | } | |
166 | ||
3b2f2976 | 167 | fn make_win_dist( |
dfeec247 XL |
168 | rust_root: &Path, |
169 | plat_root: &Path, | |
3dfed10e | 170 | target: TargetSelection, |
dfeec247 | 171 | builder: &Builder<'_>, |
3b2f2976 | 172 | ) { |
7cac9316 | 173 | //Ask gcc where it keeps its stuff |
3dfed10e | 174 | let mut cmd = Command::new(builder.cc(target)); |
7cac9316 | 175 | cmd.arg("-print-search-dirs"); |
041b39d2 XL |
176 | let gcc_out = output(&mut cmd); |
177 | ||
178 | let mut bin_path: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect(); | |
7cac9316 XL |
179 | let mut lib_path = Vec::new(); |
180 | ||
181 | for line in gcc_out.lines() { | |
182 | let idx = line.find(':').unwrap(); | |
183 | let key = &line[..idx]; | |
184 | let trim_chars: &[_] = &[' ', '=']; | |
3dfed10e | 185 | let value = env::split_paths(line[(idx + 1)..].trim_start_matches(trim_chars)); |
7cac9316 XL |
186 | |
187 | if key == "programs" { | |
188 | bin_path.extend(value); | |
189 | } else if key == "libraries" { | |
190 | lib_path.extend(value); | |
191 | } | |
192 | } | |
193 | ||
3dfed10e | 194 | let compiler = if target == "i686-pc-windows-gnu" { |
74b04a01 | 195 | "i686-w64-mingw32-gcc.exe" |
3dfed10e | 196 | } else if target == "x86_64-pc-windows-gnu" { |
74b04a01 XL |
197 | "x86_64-w64-mingw32-gcc.exe" |
198 | } else { | |
199 | "gcc.exe" | |
200 | }; | |
201 | let target_tools = [compiler, "ld.exe", "dlltool.exe", "libwinpthread-1.dll"]; | |
e74abb32 | 202 | let mut rustc_dlls = vec!["libwinpthread-1.dll"]; |
3dfed10e | 203 | if target.starts_with("i686-") { |
7cac9316 XL |
204 | rustc_dlls.push("libgcc_s_dw2-1.dll"); |
205 | } else { | |
206 | rustc_dlls.push("libgcc_s_seh-1.dll"); | |
207 | } | |
208 | ||
dfeec247 XL |
209 | let target_libs = [ |
210 | //MinGW libs | |
7cac9316 XL |
211 | "libgcc.a", |
212 | "libgcc_eh.a", | |
213 | "libgcc_s.a", | |
214 | "libm.a", | |
215 | "libmingw32.a", | |
216 | "libmingwex.a", | |
217 | "libstdc++.a", | |
218 | "libiconv.a", | |
219 | "libmoldname.a", | |
220 | "libpthread.a", | |
221 | //Windows import libs | |
222 | "libadvapi32.a", | |
223 | "libbcrypt.a", | |
224 | "libcomctl32.a", | |
225 | "libcomdlg32.a", | |
0531ce1d | 226 | "libcredui.a", |
7cac9316 | 227 | "libcrypt32.a", |
0531ce1d | 228 | "libdbghelp.a", |
7cac9316 XL |
229 | "libgdi32.a", |
230 | "libimagehlp.a", | |
231 | "libiphlpapi.a", | |
232 | "libkernel32.a", | |
0531ce1d | 233 | "libmsimg32.a", |
7cac9316 XL |
234 | "libmsvcrt.a", |
235 | "libodbc32.a", | |
236 | "libole32.a", | |
237 | "liboleaut32.a", | |
238 | "libopengl32.a", | |
239 | "libpsapi.a", | |
240 | "librpcrt4.a", | |
0531ce1d | 241 | "libsecur32.a", |
7cac9316 XL |
242 | "libsetupapi.a", |
243 | "libshell32.a", | |
0531ce1d | 244 | "libsynchronization.a", |
7cac9316 XL |
245 | "libuser32.a", |
246 | "libuserenv.a", | |
247 | "libuuid.a", | |
248 | "libwinhttp.a", | |
249 | "libwinmm.a", | |
250 | "libwinspool.a", | |
251 | "libws2_32.a", | |
252 | "libwsock32.a", | |
253 | ]; | |
254 | ||
255 | //Find mingw artifacts we want to bundle | |
256 | let target_tools = find_files(&target_tools, &bin_path); | |
257 | let rustc_dlls = find_files(&rustc_dlls, &bin_path); | |
258 | let target_libs = find_files(&target_libs, &lib_path); | |
259 | ||
83c7162d | 260 | // Copy runtime dlls next to rustc.exe |
7cac9316 XL |
261 | let dist_bin_dir = rust_root.join("bin/"); |
262 | fs::create_dir_all(&dist_bin_dir).expect("creating dist_bin_dir failed"); | |
263 | for src in rustc_dlls { | |
83c7162d | 264 | builder.copy_to_folder(&src, &dist_bin_dir); |
7cac9316 XL |
265 | } |
266 | ||
267 | //Copy platform tools to platform-specific bin directory | |
f035d41b XL |
268 | let target_bin_dir = plat_root |
269 | .join("lib") | |
270 | .join("rustlib") | |
3dfed10e | 271 | .join(target.triple) |
f035d41b XL |
272 | .join("bin") |
273 | .join("self-contained"); | |
7cac9316 XL |
274 | fs::create_dir_all(&target_bin_dir).expect("creating target_bin_dir failed"); |
275 | for src in target_tools { | |
83c7162d | 276 | builder.copy_to_folder(&src, &target_bin_dir); |
7cac9316 XL |
277 | } |
278 | ||
8faf50e0 XL |
279 | // Warn windows-gnu users that the bundled GCC cannot compile C files |
280 | builder.create( | |
281 | &target_bin_dir.join("GCC-WARNING.txt"), | |
1b1a35ee XL |
282 | "gcc.exe contained in this folder cannot be used for compiling C files - it is only \ |
283 | used as a linker. In order to be able to compile projects containing C code use \ | |
dfeec247 | 284 | the GCC provided by MinGW or Cygwin.", |
8faf50e0 XL |
285 | ); |
286 | ||
7cac9316 | 287 | //Copy platform libs to platform-specific lib directory |
f035d41b XL |
288 | let target_lib_dir = plat_root |
289 | .join("lib") | |
290 | .join("rustlib") | |
3dfed10e | 291 | .join(target.triple) |
f035d41b XL |
292 | .join("lib") |
293 | .join("self-contained"); | |
7cac9316 XL |
294 | fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed"); |
295 | for src in target_libs { | |
83c7162d | 296 | builder.copy_to_folder(&src, &target_lib_dir); |
7cac9316 XL |
297 | } |
298 | } | |
299 | ||
83c7162d | 300 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 | 301 | pub struct Mingw { |
3dfed10e | 302 | pub host: TargetSelection, |
54a0048b SL |
303 | } |
304 | ||
3b2f2976 | 305 | impl Step for Mingw { |
fc512014 | 306 | type Output = Option<GeneratedTarball>; |
3b2f2976 | 307 | const DEFAULT: bool = true; |
3b2f2976 | 308 | |
9fa01778 | 309 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
04454e1e | 310 | run.alias("rust-mingw") |
54a0048b SL |
311 | } |
312 | ||
9fa01778 | 313 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 XL |
314 | run.builder.ensure(Mingw { host: run.target }); |
315 | } | |
316 | ||
9fa01778 | 317 | /// Builds the `rust-mingw` installer component. |
3b2f2976 XL |
318 | /// |
319 | /// This contains all the bits and pieces to run the MinGW Windows targets | |
0731742a | 320 | /// without any extra installed software (e.g., we bundle gcc, libraries, etc). |
fc512014 | 321 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
3b2f2976 | 322 | let host = self.host; |
04454e1e | 323 | if !host.ends_with("pc-windows-gnu") { |
3b2f2976 | 324 | return None; |
54a0048b SL |
325 | } |
326 | ||
fc512014 XL |
327 | let mut tarball = Tarball::new(builder, "rust-mingw", &host.triple); |
328 | tarball.set_product_name("Rust MinGW"); | |
3b2f2976 XL |
329 | |
330 | // The first argument is a "temporary directory" which is just | |
331 | // thrown away (this contains the runtime DLLs included in the rustc package | |
332 | // above) and the second argument is where to place all the MinGW components | |
333 | // (which is what we want). | |
fc512014 XL |
334 | make_win_dist(&tmpdir(builder), tarball.image_dir(), host, &builder); |
335 | ||
336 | Some(tarball.generate()) | |
3b2f2976 XL |
337 | } |
338 | } | |
54a0048b | 339 | |
83c7162d | 340 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 XL |
341 | pub struct Rustc { |
342 | pub compiler: Compiler, | |
343 | } | |
344 | ||
345 | impl Step for Rustc { | |
fc512014 | 346 | type Output = GeneratedTarball; |
3b2f2976 XL |
347 | const DEFAULT: bool = true; |
348 | const ONLY_HOSTS: bool = true; | |
3b2f2976 | 349 | |
9fa01778 | 350 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
04454e1e | 351 | run.alias("rustc") |
3b2f2976 XL |
352 | } |
353 | ||
9fa01778 | 354 | fn make_run(run: RunConfig<'_>) { |
dfeec247 XL |
355 | run.builder |
356 | .ensure(Rustc { compiler: run.builder.compiler(run.builder.top_stage, run.target) }); | |
3b2f2976 XL |
357 | } |
358 | ||
359 | /// Creates the `rustc` installer component. | |
fc512014 | 360 | fn run(self, builder: &Builder<'_>) -> GeneratedTarball { |
3b2f2976 XL |
361 | let compiler = self.compiler; |
362 | let host = self.compiler.host; | |
54a0048b | 363 | |
fc512014 | 364 | let tarball = Tarball::new(builder, "rustc", &host.triple); |
3b2f2976 XL |
365 | |
366 | // Prepare the rustc "image", what will actually end up getting installed | |
fc512014 | 367 | prepare_image(builder, compiler, tarball.image_dir()); |
3b2f2976 XL |
368 | |
369 | // On MinGW we've got a few runtime DLL dependencies that we need to | |
370 | // include. The first argument to this script is where to put these DLLs | |
371 | // (the image we're creating), and the second argument is a junk directory | |
372 | // to ignore all other MinGW stuff the script creates. | |
373 | // | |
374 | // On 32-bit MinGW we're always including a DLL which needs some extra | |
375 | // licenses to distribute. On 64-bit MinGW we don't actually distribute | |
376 | // anything requiring us to distribute a license, but it's likely the | |
377 | // install will *also* include the rust-mingw package, which also needs | |
378 | // licenses, so to be safe we just include it here in all MinGW packages. | |
04454e1e | 379 | if host.ends_with("pc-windows-gnu") { |
fc512014 XL |
380 | make_win_dist(tarball.image_dir(), &tmpdir(builder), host, builder); |
381 | tarball.add_dir(builder.src.join("src/etc/third-party"), "share/doc"); | |
3b2f2976 XL |
382 | } |
383 | ||
fc512014 | 384 | return tarball.generate(); |
3b2f2976 | 385 | |
9fa01778 | 386 | fn prepare_image(builder: &Builder<'_>, compiler: Compiler, image: &Path) { |
3b2f2976 | 387 | let host = compiler.host; |
3b2f2976 | 388 | let src = builder.sysroot(compiler); |
3b2f2976 XL |
389 | |
390 | // Copy rustc/rustdoc binaries | |
391 | t!(fs::create_dir_all(image.join("bin"))); | |
83c7162d | 392 | builder.cp_r(&src.join("bin"), &image.join("bin")); |
3b2f2976 | 393 | |
532ac7d7 XL |
394 | builder.install(&builder.rustdoc(compiler), &image.join("bin"), 0o755); |
395 | ||
064997fb FG |
396 | let ra_proc_macro_srv = builder |
397 | .ensure(tool::RustAnalyzerProcMacroSrv { | |
398 | compiler: builder.compiler_for( | |
399 | compiler.stage, | |
400 | builder.config.build, | |
401 | compiler.host, | |
402 | ), | |
403 | target: compiler.host, | |
404 | }) | |
405 | .expect("rust-analyzer-proc-macro-server always builds"); | |
406 | builder.install(&ra_proc_macro_srv, &image.join("libexec"), 0o755); | |
407 | ||
532ac7d7 | 408 | let libdir_relative = builder.libdir_relative(compiler); |
3b2f2976 XL |
409 | |
410 | // Copy runtime DLLs needed by the compiler | |
532ac7d7 | 411 | if libdir_relative.to_str() != Some("bin") { |
e1599b0c | 412 | let libdir = builder.rustc_libdir(compiler); |
532ac7d7 | 413 | for entry in builder.read_dir(&libdir) { |
3b2f2976 XL |
414 | let name = entry.file_name(); |
415 | if let Some(s) = name.to_str() { | |
416 | if is_dylib(s) { | |
e1599b0c XL |
417 | // Don't use custom libdir here because ^lib/ will be resolved again |
418 | // with installer | |
419 | builder.install(&entry.path(), &image.join("lib"), 0o644); | |
3b2f2976 XL |
420 | } |
421 | } | |
422 | } | |
423 | } | |
424 | ||
29967ef6 XL |
425 | // Copy over the codegen backends |
426 | let backends_src = builder.sysroot_codegen_backends(compiler); | |
427 | let backends_rel = backends_src | |
428 | .strip_prefix(&src) | |
429 | .unwrap() | |
430 | .strip_prefix(builder.sysroot_libdir_relative(compiler)) | |
431 | .unwrap(); | |
432 | // Don't use custom libdir here because ^lib/ will be resolved again with installer | |
433 | let backends_dst = image.join("lib").join(&backends_rel); | |
434 | ||
435 | t!(fs::create_dir_all(&backends_dst)); | |
436 | builder.cp_r(&backends_src, &backends_dst); | |
437 | ||
b7449926 XL |
438 | // Copy libLLVM.so to the lib dir as well, if needed. While not |
439 | // technically needed by rustc itself it's needed by lots of other | |
440 | // components like the llvm tools and LLD. LLD is included below and | |
441 | // tools/LLDB come later, so let's just throw it in the rustc | |
442 | // component for now. | |
f9f354fc | 443 | maybe_install_llvm_runtime(builder, host, image); |
b7449926 | 444 | |
fc512014 XL |
445 | let dst_dir = image.join("lib/rustlib").join(&*host.triple).join("bin"); |
446 | t!(fs::create_dir_all(&dst_dir)); | |
447 | ||
0531ce1d XL |
448 | // Copy over lld if it's there |
449 | if builder.config.lld_enabled { | |
a2a8927a | 450 | let src_dir = builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin"); |
136023e0 XL |
451 | let rust_lld = exe("rust-lld", compiler.host); |
452 | builder.copy(&src_dir.join(&rust_lld), &dst_dir.join(&rust_lld)); | |
17df50a5 | 453 | // for `-Z gcc-ld=lld` |
dc3f5686 XL |
454 | let gcc_lld_src_dir = src_dir.join("gcc-ld"); |
455 | let gcc_lld_dst_dir = dst_dir.join("gcc-ld"); | |
456 | t!(fs::create_dir(&gcc_lld_dst_dir)); | |
f2b60f7d FG |
457 | for name in crate::LLD_FILE_NAMES { |
458 | let exe_name = exe(name, compiler.host); | |
459 | builder | |
460 | .copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name)); | |
461 | } | |
0531ce1d XL |
462 | } |
463 | ||
3b2f2976 XL |
464 | // Man pages |
465 | t!(fs::create_dir_all(image.join("share/man/man1"))); | |
83c7162d | 466 | let man_src = builder.src.join("src/doc/man"); |
ff7c6d11 | 467 | let man_dst = image.join("share/man/man1"); |
9fa01778 | 468 | |
ff7c6d11 XL |
469 | // don't use our `bootstrap::util::{copy, cp_r}`, because those try |
470 | // to hardlink, and we don't want to edit the source templates | |
83c7162d | 471 | for file_entry in builder.read_dir(&man_src) { |
ff7c6d11 XL |
472 | let page_src = file_entry.path(); |
473 | let page_dst = man_dst.join(file_entry.file_name()); | |
5099ac24 FG |
474 | let src_text = t!(std::fs::read_to_string(&page_src)); |
475 | let new_text = src_text.replace("<INSERT VERSION HERE>", &builder.version); | |
476 | t!(std::fs::write(&page_dst, &new_text)); | |
ff7c6d11 | 477 | t!(fs::copy(&page_src, &page_dst)); |
ff7c6d11 | 478 | } |
3b2f2976 XL |
479 | |
480 | // Debugger scripts | |
dfeec247 XL |
481 | builder |
482 | .ensure(DebuggerScripts { sysroot: INTERNER.intern_path(image.to_owned()), host }); | |
3b2f2976 XL |
483 | |
484 | // Misc license info | |
485 | let cp = |file: &str| { | |
83c7162d | 486 | builder.install(&builder.src.join(file), &image.join("share/doc/rust"), 0o644); |
3b2f2976 XL |
487 | }; |
488 | cp("COPYRIGHT"); | |
489 | cp("LICENSE-APACHE"); | |
490 | cp("LICENSE-MIT"); | |
491 | cp("README.md"); | |
492 | } | |
54a0048b SL |
493 | } |
494 | } | |
495 | ||
3b2f2976 XL |
496 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] |
497 | pub struct DebuggerScripts { | |
498 | pub sysroot: Interned<PathBuf>, | |
3dfed10e | 499 | pub host: TargetSelection, |
3b2f2976 | 500 | } |
a7813a04 | 501 | |
3b2f2976 XL |
502 | impl Step for DebuggerScripts { |
503 | type Output = (); | |
504 | ||
9fa01778 | 505 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
04454e1e | 506 | run.never() |
3b2f2976 | 507 | } |
a7813a04 | 508 | |
3b2f2976 | 509 | /// Copies debugger scripts for `target` into the `sysroot` specified. |
9fa01778 | 510 | fn run(self, builder: &Builder<'_>) { |
3b2f2976 XL |
511 | let host = self.host; |
512 | let sysroot = self.sysroot; | |
513 | let dst = sysroot.join("lib/rustlib/etc"); | |
514 | t!(fs::create_dir_all(&dst)); | |
515 | let cp_debugger_script = |file: &str| { | |
83c7162d | 516 | builder.install(&builder.src.join("src/etc/").join(file), &dst, 0o644); |
3b2f2976 XL |
517 | }; |
518 | if host.contains("windows-msvc") { | |
519 | // windbg debugger scripts | |
dfeec247 XL |
520 | builder.install( |
521 | &builder.src.join("src/etc/rust-windbg.cmd"), | |
522 | &sysroot.join("bin"), | |
523 | 0o755, | |
524 | ); | |
a7813a04 | 525 | |
ff7c6d11 | 526 | cp_debugger_script("natvis/intrinsic.natvis"); |
3b2f2976 XL |
527 | cp_debugger_script("natvis/liballoc.natvis"); |
528 | cp_debugger_script("natvis/libcore.natvis"); | |
60c5eb7d | 529 | cp_debugger_script("natvis/libstd.natvis"); |
3b2f2976 | 530 | } else { |
f035d41b | 531 | cp_debugger_script("rust_types.py"); |
3b2f2976 XL |
532 | |
533 | // gdb debugger scripts | |
dfeec247 XL |
534 | builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755); |
535 | builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), 0o755); | |
3b2f2976 XL |
536 | |
537 | cp_debugger_script("gdb_load_rust_pretty_printers.py"); | |
f035d41b XL |
538 | cp_debugger_script("gdb_lookup.py"); |
539 | cp_debugger_script("gdb_providers.py"); | |
3b2f2976 XL |
540 | |
541 | // lldb debugger scripts | |
dfeec247 | 542 | builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"), 0o755); |
3b2f2976 | 543 | |
f035d41b XL |
544 | cp_debugger_script("lldb_lookup.py"); |
545 | cp_debugger_script("lldb_providers.py"); | |
6c58768f | 546 | cp_debugger_script("lldb_commands") |
3b2f2976 | 547 | } |
a7813a04 XL |
548 | } |
549 | } | |
550 | ||
e74abb32 XL |
551 | fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool { |
552 | // The only true set of target libraries came from the build triple, so | |
553 | // let's reduce redundant work by only producing archives from that host. | |
554 | if compiler.host != builder.config.build { | |
555 | builder.info("\tskipping, not a build host"); | |
556 | true | |
557 | } else { | |
558 | false | |
559 | } | |
560 | } | |
561 | ||
487cf647 FG |
562 | /// Check that all objects in rlibs for UEFI targets are COFF. This |
563 | /// ensures that the C compiler isn't producing ELF objects, which would | |
564 | /// not link correctly with the COFF objects. | |
565 | fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp: &Path) { | |
566 | if !target.ends_with("-uefi") { | |
567 | return; | |
568 | } | |
569 | ||
570 | for (path, _) in builder.read_stamp_file(stamp) { | |
571 | if path.extension() != Some(OsStr::new("rlib")) { | |
572 | continue; | |
573 | } | |
574 | ||
575 | let data = t!(fs::read(&path)); | |
576 | let data = data.as_slice(); | |
577 | let archive = t!(ArchiveFile::parse(data)); | |
578 | for member in archive.members() { | |
579 | let member = t!(member); | |
580 | let member_data = t!(member.data(data)); | |
581 | ||
582 | let is_coff = match object::File::parse(member_data) { | |
583 | Ok(member_file) => member_file.format() == BinaryFormat::Coff, | |
584 | Err(_) => false, | |
585 | }; | |
586 | ||
587 | if !is_coff { | |
588 | let member_name = String::from_utf8_lossy(member.name()); | |
589 | panic!("member {} in {} is not COFF", member_name, path.display()); | |
590 | } | |
591 | } | |
592 | } | |
593 | } | |
594 | ||
e74abb32 | 595 | /// Copy stamped files into an image's `target/lib` directory. |
3dfed10e XL |
596 | fn copy_target_libs(builder: &Builder<'_>, target: TargetSelection, image: &Path, stamp: &Path) { |
597 | let dst = image.join("lib/rustlib").join(target.triple).join("lib"); | |
f035d41b | 598 | let self_contained_dst = dst.join("self-contained"); |
e74abb32 | 599 | t!(fs::create_dir_all(&dst)); |
f035d41b XL |
600 | t!(fs::create_dir_all(&self_contained_dst)); |
601 | for (path, dependency_type) in builder.read_stamp_file(stamp) { | |
602 | if dependency_type == DependencyType::TargetSelfContained { | |
603 | builder.copy(&path, &self_contained_dst.join(path.file_name().unwrap())); | |
604 | } else if dependency_type == DependencyType::Target || builder.config.build == target { | |
e74abb32 XL |
605 | builder.copy(&path, &dst.join(path.file_name().unwrap())); |
606 | } | |
607 | } | |
608 | } | |
609 | ||
83c7162d | 610 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 XL |
611 | pub struct Std { |
612 | pub compiler: Compiler, | |
3dfed10e | 613 | pub target: TargetSelection, |
3b2f2976 XL |
614 | } |
615 | ||
616 | impl Step for Std { | |
fc512014 | 617 | type Output = Option<GeneratedTarball>; |
3b2f2976 | 618 | const DEFAULT: bool = true; |
3b2f2976 | 619 | |
9fa01778 | 620 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
04454e1e | 621 | run.alias("rust-std") |
476ff2be SL |
622 | } |
623 | ||
9fa01778 | 624 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 | 625 | run.builder.ensure(Std { |
dc9dc135 XL |
626 | compiler: run.builder.compiler_for( |
627 | run.builder.top_stage, | |
628 | run.builder.config.build, | |
629 | run.target, | |
630 | ), | |
3b2f2976 XL |
631 | target: run.target, |
632 | }); | |
633 | } | |
634 | ||
fc512014 | 635 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
3b2f2976 XL |
636 | let compiler = self.compiler; |
637 | let target = self.target; | |
638 | ||
e74abb32 | 639 | if skip_host_target_lib(builder, compiler) { |
fc512014 | 640 | return None; |
3b2f2976 XL |
641 | } |
642 | ||
064997fb | 643 | builder.ensure(compile::Std::new(compiler, target)); |
3b2f2976 | 644 | |
fc512014 XL |
645 | let mut tarball = Tarball::new(builder, "rust-std", &target.triple); |
646 | tarball.include_target_in_component_name(true); | |
3b2f2976 | 647 | |
e74abb32 XL |
648 | let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); |
649 | let stamp = compile::libstd_stamp(builder, compiler_to_use, target); | |
487cf647 | 650 | verify_uefi_rlib_format(builder, target, &stamp); |
fc512014 XL |
651 | copy_target_libs(builder, target, &tarball.image_dir(), &stamp); |
652 | ||
653 | Some(tarball.generate()) | |
e74abb32 XL |
654 | } |
655 | } | |
656 | ||
657 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] | |
658 | pub struct RustcDev { | |
659 | pub compiler: Compiler, | |
3dfed10e | 660 | pub target: TargetSelection, |
e74abb32 XL |
661 | } |
662 | ||
663 | impl Step for RustcDev { | |
fc512014 | 664 | type Output = Option<GeneratedTarball>; |
e74abb32 XL |
665 | const DEFAULT: bool = true; |
666 | const ONLY_HOSTS: bool = true; | |
667 | ||
668 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
04454e1e | 669 | run.alias("rustc-dev") |
e74abb32 XL |
670 | } |
671 | ||
672 | fn make_run(run: RunConfig<'_>) { | |
673 | run.builder.ensure(RustcDev { | |
674 | compiler: run.builder.compiler_for( | |
675 | run.builder.top_stage, | |
676 | run.builder.config.build, | |
677 | run.target, | |
678 | ), | |
679 | target: run.target, | |
680 | }); | |
681 | } | |
682 | ||
fc512014 | 683 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
e74abb32 XL |
684 | let compiler = self.compiler; |
685 | let target = self.target; | |
e74abb32 | 686 | if skip_host_target_lib(builder, compiler) { |
fc512014 | 687 | return None; |
e74abb32 XL |
688 | } |
689 | ||
064997fb | 690 | builder.ensure(compile::Rustc::new(compiler, target)); |
e74abb32 | 691 | |
fc512014 | 692 | let tarball = Tarball::new(builder, "rustc-dev", &target.triple); |
e74abb32 XL |
693 | |
694 | let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); | |
695 | let stamp = compile::librustc_stamp(builder, compiler_to_use, target); | |
fc512014 | 696 | copy_target_libs(builder, target, tarball.image_dir(), &stamp); |
e74abb32 | 697 | |
fc512014 | 698 | let src_files = &["Cargo.lock"]; |
1b1a35ee XL |
699 | // This is the reduced set of paths which will become the rustc-dev component |
700 | // (essentially the compiler crates and all of their path dependencies). | |
fc512014 XL |
701 | copy_src_dirs( |
702 | builder, | |
703 | &builder.src, | |
704 | &["compiler"], | |
705 | &[], | |
706 | &tarball.image_dir().join("lib/rustlib/rustc-src/rust"), | |
707 | ); | |
708 | for file in src_files { | |
709 | tarball.add_file(builder.src.join(file), "lib/rustlib/rustc-src/rust", 0o644); | |
1b1a35ee XL |
710 | } |
711 | ||
fc512014 | 712 | Some(tarball.generate()) |
3b2f2976 | 713 | } |
476ff2be SL |
714 | } |
715 | ||
3b2f2976 XL |
716 | #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] |
717 | pub struct Analysis { | |
718 | pub compiler: Compiler, | |
3dfed10e | 719 | pub target: TargetSelection, |
7cac9316 XL |
720 | } |
721 | ||
3b2f2976 | 722 | impl Step for Analysis { |
fc512014 | 723 | type Output = Option<GeneratedTarball>; |
3b2f2976 | 724 | const DEFAULT: bool = true; |
476ff2be | 725 | |
9fa01778 | 726 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
94222f64 | 727 | let default = should_build_extended_tool(&run.builder, "analysis"); |
04454e1e | 728 | run.alias("rust-analysis").default_condition(default) |
476ff2be SL |
729 | } |
730 | ||
9fa01778 | 731 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 | 732 | run.builder.ensure(Analysis { |
dc9dc135 XL |
733 | // Find the actual compiler (handling the full bootstrap option) which |
734 | // produced the save-analysis data because that data isn't copied | |
735 | // through the sysroot uplifting. | |
736 | compiler: run.builder.compiler_for( | |
737 | run.builder.top_stage, | |
738 | run.builder.config.build, | |
739 | run.target, | |
740 | ), | |
3b2f2976 XL |
741 | target: run.target, |
742 | }); | |
743 | } | |
744 | ||
745 | /// Creates a tarball of save-analysis metadata, if available. | |
fc512014 | 746 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
3b2f2976 XL |
747 | let compiler = self.compiler; |
748 | let target = self.target; | |
74b04a01 | 749 | if compiler.host != builder.config.build { |
fc512014 | 750 | return None; |
3b2f2976 XL |
751 | } |
752 | ||
064997fb | 753 | builder.ensure(compile::Std::new(compiler, target)); |
dfeec247 XL |
754 | let src = builder |
755 | .stage_out(compiler, Mode::Std) | |
3dfed10e | 756 | .join(target.triple) |
dfeec247 | 757 | .join(builder.cargo_dir()) |
fc512014 XL |
758 | .join("deps") |
759 | .join("save-analysis"); | |
3b2f2976 | 760 | |
fc512014 XL |
761 | let mut tarball = Tarball::new(builder, "rust-analysis", &target.triple); |
762 | tarball.include_target_in_component_name(true); | |
763 | tarball.add_dir(src, format!("lib/rustlib/{}/analysis", target.triple)); | |
764 | Some(tarball.generate()) | |
3b2f2976 | 765 | } |
476ff2be SL |
766 | } |
767 | ||
3dfed10e XL |
768 | /// Use the `builder` to make a filtered copy of `base`/X for X in (`src_dirs` - `exclude_dirs`) to |
769 | /// `dst_dir`. | |
770 | fn copy_src_dirs( | |
771 | builder: &Builder<'_>, | |
772 | base: &Path, | |
773 | src_dirs: &[&str], | |
774 | exclude_dirs: &[&str], | |
775 | dst_dir: &Path, | |
776 | ) { | |
7cac9316 XL |
777 | fn filter_fn(exclude_dirs: &[&str], dir: &str, path: &Path) -> bool { |
778 | let spath = match path.to_str() { | |
779 | Some(path) => path, | |
780 | None => return false, | |
781 | }; | |
74b04a01 | 782 | if spath.ends_with('~') || spath.ends_with(".pyc") { |
dfeec247 | 783 | return false; |
7cac9316 | 784 | } |
9fa01778 XL |
785 | |
786 | const LLVM_PROJECTS: &[&str] = &[ | |
dfeec247 XL |
787 | "llvm-project/clang", |
788 | "llvm-project\\clang", | |
789 | "llvm-project/libunwind", | |
790 | "llvm-project\\libunwind", | |
791 | "llvm-project/lld", | |
792 | "llvm-project\\lld", | |
793 | "llvm-project/lldb", | |
794 | "llvm-project\\lldb", | |
795 | "llvm-project/llvm", | |
796 | "llvm-project\\llvm", | |
797 | "llvm-project/compiler-rt", | |
798 | "llvm-project\\compiler-rt", | |
5099ac24 FG |
799 | "llvm-project/cmake", |
800 | "llvm-project\\cmake", | |
9fa01778 | 801 | ]; |
dfeec247 XL |
802 | if spath.contains("llvm-project") |
803 | && !spath.ends_with("llvm-project") | |
9fa01778 XL |
804 | && !LLVM_PROJECTS.iter().any(|path| spath.contains(path)) |
805 | { | |
806 | return false; | |
807 | } | |
808 | ||
dfeec247 XL |
809 | const LLVM_TEST: &[&str] = &["llvm-project/llvm/test", "llvm-project\\llvm\\test"]; |
810 | if LLVM_TEST.iter().any(|path| spath.contains(path)) | |
811 | && (spath.ends_with(".ll") || spath.ends_with(".td") || spath.ends_with(".s")) | |
812 | { | |
813 | return false; | |
7cac9316 | 814 | } |
8bb4bdeb | 815 | |
7cac9316 XL |
816 | let full_path = Path::new(dir).join(path); |
817 | if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) { | |
818 | return false; | |
819 | } | |
820 | ||
821 | let excludes = [ | |
dfeec247 XL |
822 | "CVS", |
823 | "RCS", | |
824 | "SCCS", | |
825 | ".git", | |
826 | ".gitignore", | |
827 | ".gitmodules", | |
828 | ".gitattributes", | |
829 | ".cvsignore", | |
830 | ".svn", | |
831 | ".arch-ids", | |
832 | "{arch}", | |
833 | "=RELEASE-ID", | |
834 | "=meta-update", | |
835 | "=update", | |
836 | ".bzr", | |
837 | ".bzrignore", | |
838 | ".bzrtags", | |
839 | ".hg", | |
840 | ".hgignore", | |
841 | ".hgrags", | |
842 | "_darcs", | |
7cac9316 | 843 | ]; |
dfeec247 | 844 | !path.iter().map(|s| s.to_str().unwrap()).any(|s| excludes.contains(&s)) |
8bb4bdeb XL |
845 | } |
846 | ||
7cac9316 XL |
847 | // Copy the directories using our filter |
848 | for item in src_dirs { | |
849 | let dst = &dst_dir.join(item); | |
850 | t!(fs::create_dir_all(dst)); | |
3dfed10e | 851 | builder.cp_filtered(&base.join(item), dst, &|path| filter_fn(exclude_dirs, item, path)); |
7cac9316 XL |
852 | } |
853 | } | |
854 | ||
83c7162d | 855 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 XL |
856 | pub struct Src; |
857 | ||
858 | impl Step for Src { | |
859 | /// The output path of the src installer tarball | |
fc512014 | 860 | type Output = GeneratedTarball; |
3b2f2976 XL |
861 | const DEFAULT: bool = true; |
862 | const ONLY_HOSTS: bool = true; | |
3b2f2976 | 863 | |
9fa01778 | 864 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
04454e1e | 865 | run.alias("rust-src") |
3b2f2976 XL |
866 | } |
867 | ||
9fa01778 | 868 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 XL |
869 | run.builder.ensure(Src); |
870 | } | |
7cac9316 | 871 | |
3b2f2976 | 872 | /// Creates the `rust-src` installer component |
fc512014 XL |
873 | fn run(self, builder: &Builder<'_>) -> GeneratedTarball { |
874 | let tarball = Tarball::new_targetless(builder, "rust-src"); | |
3b2f2976 | 875 | |
3dfed10e XL |
876 | // A lot of tools expect the rust-src component to be entirely in this directory, so if you |
877 | // change that (e.g. by adding another directory `lib/rustlib/src/foo` or | |
878 | // `lib/rustlib/src/rust/foo`), you will need to go around hunting for implicit assumptions | |
879 | // and fix them... | |
880 | // | |
881 | // NOTE: if you update the paths here, you also should update the "virtual" path | |
882 | // translation code in `imported_source_files` in `src/librustc_metadata/rmeta/decoder.rs` | |
fc512014 | 883 | let dst_src = tarball.image_dir().join("lib/rustlib/src/rust"); |
3b2f2976 | 884 | |
dfeec247 | 885 | let src_files = ["Cargo.lock"]; |
3b2f2976 | 886 | // This is the reduced set of paths which will become the rust-src component |
3dfed10e XL |
887 | // (essentially libstd and all of its path dependencies). |
888 | copy_src_dirs( | |
889 | builder, | |
890 | &builder.src, | |
1b1a35ee | 891 | &["library", "src/llvm-project/libunwind"], |
3dfed10e XL |
892 | &[ |
893 | // not needed and contains symlinks which rustup currently | |
894 | // chokes on when unpacking. | |
895 | "library/backtrace/crates", | |
5e7ed085 FG |
896 | // these are 30MB combined and aren't necessary for building |
897 | // the standard library. | |
923072b8 | 898 | "library/stdarch/Cargo.toml", |
5e7ed085 FG |
899 | "library/stdarch/crates/stdarch-verify", |
900 | "library/stdarch/crates/intrinsic-test", | |
3dfed10e XL |
901 | ], |
902 | &dst_src, | |
903 | ); | |
ea8adc8c | 904 | for file in src_files.iter() { |
83c7162d | 905 | builder.copy(&builder.src.join(file), &dst_src.join(file)); |
ea8adc8c | 906 | } |
3b2f2976 | 907 | |
fc512014 | 908 | tarball.generate() |
3b2f2976 | 909 | } |
7cac9316 XL |
910 | } |
911 | ||
83c7162d | 912 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 | 913 | pub struct PlainSourceTarball; |
5bcae85e | 914 | |
3b2f2976 XL |
915 | impl Step for PlainSourceTarball { |
916 | /// Produces the location of the tarball generated | |
fc512014 | 917 | type Output = GeneratedTarball; |
3b2f2976 XL |
918 | const DEFAULT: bool = true; |
919 | const ONLY_HOSTS: bool = true; | |
3b2f2976 | 920 | |
9fa01778 | 921 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
3b2f2976 | 922 | let builder = run.builder; |
04454e1e | 923 | run.alias("rustc-src").default_condition(builder.config.rust_dist_src) |
3b2f2976 | 924 | } |
5bcae85e | 925 | |
9fa01778 | 926 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 | 927 | run.builder.ensure(PlainSourceTarball); |
5bcae85e SL |
928 | } |
929 | ||
3b2f2976 | 930 | /// Creates the plain source tarball |
fc512014 | 931 | fn run(self, builder: &Builder<'_>) -> GeneratedTarball { |
923072b8 FG |
932 | // NOTE: This is a strange component in a lot of ways. It uses `src` as the target, which |
933 | // means neither rustup nor rustup-toolchain-install-master know how to download it. | |
934 | // It also contains symbolic links, unlike other any other dist tarball. | |
935 | // It's used for distros building rustc from source in a pre-vendored environment. | |
936 | let mut tarball = Tarball::new(builder, "rustc", "src"); | |
937 | tarball.permit_symlinks(true); | |
fc512014 | 938 | let plain_dst_src = tarball.image_dir(); |
3b2f2976 XL |
939 | |
940 | // This is the set of root paths which will become part of the source package | |
941 | let src_files = [ | |
942 | "COPYRIGHT", | |
943 | "LICENSE-APACHE", | |
944 | "LICENSE-MIT", | |
945 | "CONTRIBUTING.md", | |
946 | "README.md", | |
947 | "RELEASES.md", | |
948 | "configure", | |
949 | "x.py", | |
ea8adc8c | 950 | "config.toml.example", |
a1dfa0c6 XL |
951 | "Cargo.toml", |
952 | "Cargo.lock", | |
3b2f2976 | 953 | ]; |
1b1a35ee | 954 | let src_dirs = ["src", "compiler", "library"]; |
3b2f2976 | 955 | |
3dfed10e | 956 | copy_src_dirs(builder, &builder.src, &src_dirs, &[], &plain_dst_src); |
7cac9316 | 957 | |
3b2f2976 XL |
958 | // Copy the files normally |
959 | for item in &src_files { | |
83c7162d | 960 | builder.copy(&builder.src.join(item), &plain_dst_src.join(item)); |
8bb4bdeb | 961 | } |
3b2f2976 XL |
962 | |
963 | // Create the version file | |
83c7162d | 964 | builder.create(&plain_dst_src.join("version"), &builder.rust_version()); |
487cf647 | 965 | if let Some(info) = builder.rust_info().info() { |
2b03887a FG |
966 | channel::write_commit_hash_file(&plain_dst_src, &info.sha); |
967 | channel::write_commit_info_file(&plain_dst_src, info); | |
ea8adc8c | 968 | } |
3b2f2976 XL |
969 | |
970 | // If we're building from git sources, we need to vendor a complete distribution. | |
487cf647 | 971 | if builder.rust_info().is_managed_git_subrepository() { |
923072b8 FG |
972 | // Ensure we have the submodules checked out. |
973 | builder.update_submodule(Path::new("src/tools/rust-analyzer")); | |
974 | ||
3b2f2976 | 975 | // Vendor all Cargo dependencies |
83c7162d | 976 | let mut cmd = Command::new(&builder.initial_cargo); |
f035d41b XL |
977 | cmd.arg("vendor") |
978 | .arg("--sync") | |
979 | .arg(builder.src.join("./src/tools/rust-analyzer/Cargo.toml")) | |
04454e1e | 980 | .arg("--sync") |
29967ef6 | 981 | .arg(builder.src.join("./compiler/rustc_codegen_cranelift/Cargo.toml")) |
064997fb FG |
982 | .arg("--sync") |
983 | .arg(builder.src.join("./src/bootstrap/Cargo.toml")) | |
f035d41b | 984 | .current_dir(&plain_dst_src); |
064997fb | 985 | |
487cf647 | 986 | let config = if !builder.config.dry_run() { |
064997fb FG |
987 | t!(String::from_utf8(t!(cmd.output()).stdout)) |
988 | } else { | |
989 | String::new() | |
990 | }; | |
991 | ||
992 | let cargo_config_dir = plain_dst_src.join(".cargo"); | |
993 | builder.create_dir(&cargo_config_dir); | |
994 | builder.create(&cargo_config_dir.join("config.toml"), &config); | |
8bb4bdeb XL |
995 | } |
996 | ||
fc512014 | 997 | tarball.bare() |
8bb4bdeb | 998 | } |
5bcae85e SL |
999 | } |
1000 | ||
83c7162d | 1001 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 | 1002 | pub struct Cargo { |
dc9dc135 | 1003 | pub compiler: Compiler, |
3dfed10e | 1004 | pub target: TargetSelection, |
3b2f2976 XL |
1005 | } |
1006 | ||
1007 | impl Step for Cargo { | |
94222f64 XL |
1008 | type Output = Option<GeneratedTarball>; |
1009 | const DEFAULT: bool = true; | |
3b2f2976 XL |
1010 | const ONLY_HOSTS: bool = true; |
1011 | ||
9fa01778 | 1012 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
94222f64 | 1013 | let default = should_build_extended_tool(&run.builder, "cargo"); |
04454e1e | 1014 | run.alias("cargo").default_condition(default) |
3b2f2976 XL |
1015 | } |
1016 | ||
9fa01778 | 1017 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 | 1018 | run.builder.ensure(Cargo { |
dc9dc135 XL |
1019 | compiler: run.builder.compiler_for( |
1020 | run.builder.top_stage, | |
1021 | run.builder.config.build, | |
1022 | run.target, | |
1023 | ), | |
3b2f2976 XL |
1024 | target: run.target, |
1025 | }); | |
1026 | } | |
1027 | ||
94222f64 | 1028 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
dc9dc135 | 1029 | let compiler = self.compiler; |
3b2f2976 XL |
1030 | let target = self.target; |
1031 | ||
fc512014 | 1032 | let cargo = builder.ensure(tool::Cargo { compiler, target }); |
83c7162d | 1033 | let src = builder.src.join("src/tools/cargo"); |
3b2f2976 | 1034 | let etc = src.join("src/etc"); |
3b2f2976 XL |
1035 | |
1036 | // Prepare the image directory | |
fc512014 XL |
1037 | let mut tarball = Tarball::new(builder, "cargo", &target.triple); |
1038 | tarball.set_overlay(OverlayKind::Cargo); | |
1039 | ||
1040 | tarball.add_file(&cargo, "bin", 0o755); | |
1041 | tarball.add_file(etc.join("_cargo"), "share/zsh/site-functions", 0o644); | |
1042 | tarball.add_renamed_file(etc.join("cargo.bashcomp.sh"), "etc/bash_completion.d", "cargo"); | |
1043 | tarball.add_dir(etc.join("man"), "share/man/man1"); | |
1044 | tarball.add_legal_and_readme_to("share/doc/cargo"); | |
1045 | ||
1046 | for dirent in fs::read_dir(cargo.parent().unwrap()).expect("read_dir") { | |
1047 | let dirent = dirent.expect("read dir entry"); | |
1048 | if dirent.file_name().to_str().expect("utf8").starts_with("cargo-credential-") { | |
1049 | tarball.add_file(&dirent.path(), "libexec", 0o755); | |
1050 | } | |
3b2f2976 | 1051 | } |
fc512014 | 1052 | |
94222f64 | 1053 | Some(tarball.generate()) |
8bb4bdeb | 1054 | } |
32a655c1 SL |
1055 | } |
1056 | ||
83c7162d | 1057 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 | 1058 | pub struct Rls { |
dc9dc135 | 1059 | pub compiler: Compiler, |
3dfed10e | 1060 | pub target: TargetSelection, |
cc61c64b XL |
1061 | } |
1062 | ||
3b2f2976 | 1063 | impl Step for Rls { |
fc512014 | 1064 | type Output = Option<GeneratedTarball>; |
3b2f2976 | 1065 | const ONLY_HOSTS: bool = true; |
94222f64 | 1066 | const DEFAULT: bool = true; |
3b2f2976 | 1067 | |
9fa01778 | 1068 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
94222f64 | 1069 | let default = should_build_extended_tool(&run.builder, "rls"); |
04454e1e | 1070 | run.alias("rls").default_condition(default) |
32a655c1 SL |
1071 | } |
1072 | ||
9fa01778 | 1073 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 | 1074 | run.builder.ensure(Rls { |
dc9dc135 XL |
1075 | compiler: run.builder.compiler_for( |
1076 | run.builder.top_stage, | |
1077 | run.builder.config.build, | |
1078 | run.target, | |
1079 | ), | |
3b2f2976 XL |
1080 | target: run.target, |
1081 | }); | |
32a655c1 | 1082 | } |
3b2f2976 | 1083 | |
fc512014 | 1084 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
dc9dc135 | 1085 | let compiler = self.compiler; |
3b2f2976 | 1086 | let target = self.target; |
3b2f2976 | 1087 | |
dfeec247 XL |
1088 | let rls = builder |
1089 | .ensure(tool::Rls { compiler, target, extra_features: Vec::new() }) | |
f2b60f7d | 1090 | .expect("rls expected to build"); |
ff7c6d11 | 1091 | |
fc512014 XL |
1092 | let mut tarball = Tarball::new(builder, "rls", &target.triple); |
1093 | tarball.set_overlay(OverlayKind::RLS); | |
1094 | tarball.is_preview(true); | |
1095 | tarball.add_file(rls, "bin", 0o755); | |
1096 | tarball.add_legal_and_readme_to("share/doc/rls"); | |
1097 | Some(tarball.generate()) | |
abe05a73 XL |
1098 | } |
1099 | } | |
1100 | ||
f035d41b XL |
1101 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
1102 | pub struct RustAnalyzer { | |
1103 | pub compiler: Compiler, | |
3dfed10e | 1104 | pub target: TargetSelection, |
f035d41b XL |
1105 | } |
1106 | ||
1107 | impl Step for RustAnalyzer { | |
fc512014 | 1108 | type Output = Option<GeneratedTarball>; |
94222f64 | 1109 | const DEFAULT: bool = true; |
f035d41b XL |
1110 | const ONLY_HOSTS: bool = true; |
1111 | ||
1112 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
94222f64 | 1113 | let default = should_build_extended_tool(&run.builder, "rust-analyzer"); |
04454e1e | 1114 | run.alias("rust-analyzer").default_condition(default) |
f035d41b XL |
1115 | } |
1116 | ||
1117 | fn make_run(run: RunConfig<'_>) { | |
1118 | run.builder.ensure(RustAnalyzer { | |
1119 | compiler: run.builder.compiler_for( | |
1120 | run.builder.top_stage, | |
1121 | run.builder.config.build, | |
1122 | run.target, | |
1123 | ), | |
1124 | target: run.target, | |
1125 | }); | |
1126 | } | |
1127 | ||
fc512014 | 1128 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
f035d41b XL |
1129 | let compiler = self.compiler; |
1130 | let target = self.target; | |
f035d41b | 1131 | |
3dfed10e XL |
1132 | if target.contains("riscv64") { |
1133 | // riscv64 currently has an LLVM bug that makes rust-analyzer unable | |
1134 | // to build. See #74813 for details. | |
1135 | return None; | |
1136 | } | |
1137 | ||
f035d41b | 1138 | let rust_analyzer = builder |
064997fb | 1139 | .ensure(tool::RustAnalyzer { compiler, target }) |
f035d41b XL |
1140 | .expect("rust-analyzer always builds"); |
1141 | ||
fc512014 XL |
1142 | let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple); |
1143 | tarball.set_overlay(OverlayKind::RustAnalyzer); | |
1144 | tarball.is_preview(true); | |
1145 | tarball.add_file(rust_analyzer, "bin", 0o755); | |
1146 | tarball.add_legal_and_readme_to("share/doc/rust-analyzer"); | |
1147 | Some(tarball.generate()) | |
f035d41b XL |
1148 | } |
1149 | } | |
1150 | ||
8faf50e0 XL |
1151 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
1152 | pub struct Clippy { | |
dc9dc135 | 1153 | pub compiler: Compiler, |
3dfed10e | 1154 | pub target: TargetSelection, |
8faf50e0 XL |
1155 | } |
1156 | ||
1157 | impl Step for Clippy { | |
94222f64 XL |
1158 | type Output = Option<GeneratedTarball>; |
1159 | const DEFAULT: bool = true; | |
8faf50e0 XL |
1160 | const ONLY_HOSTS: bool = true; |
1161 | ||
9fa01778 | 1162 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
94222f64 | 1163 | let default = should_build_extended_tool(&run.builder, "clippy"); |
04454e1e | 1164 | run.alias("clippy").default_condition(default) |
8faf50e0 XL |
1165 | } |
1166 | ||
9fa01778 | 1167 | fn make_run(run: RunConfig<'_>) { |
8faf50e0 | 1168 | run.builder.ensure(Clippy { |
dc9dc135 XL |
1169 | compiler: run.builder.compiler_for( |
1170 | run.builder.top_stage, | |
1171 | run.builder.config.build, | |
1172 | run.target, | |
1173 | ), | |
8faf50e0 XL |
1174 | target: run.target, |
1175 | }); | |
1176 | } | |
1177 | ||
94222f64 | 1178 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
dc9dc135 | 1179 | let compiler = self.compiler; |
8faf50e0 | 1180 | let target = self.target; |
8faf50e0 | 1181 | |
8faf50e0 XL |
1182 | // Prepare the image directory |
1183 | // We expect clippy to build, because we've exited this step above if tool | |
1184 | // state for clippy isn't testing. | |
dfeec247 XL |
1185 | let clippy = builder |
1186 | .ensure(tool::Clippy { compiler, target, extra_features: Vec::new() }) | |
f9f354fc | 1187 | .expect("clippy expected to build - essential tool"); |
dfeec247 XL |
1188 | let cargoclippy = builder |
1189 | .ensure(tool::CargoClippy { compiler, target, extra_features: Vec::new() }) | |
f9f354fc | 1190 | .expect("clippy expected to build - essential tool"); |
8faf50e0 | 1191 | |
fc512014 XL |
1192 | let mut tarball = Tarball::new(builder, "clippy", &target.triple); |
1193 | tarball.set_overlay(OverlayKind::Clippy); | |
1194 | tarball.is_preview(true); | |
1195 | tarball.add_file(clippy, "bin", 0o755); | |
1196 | tarball.add_file(cargoclippy, "bin", 0o755); | |
1197 | tarball.add_legal_and_readme_to("share/doc/clippy"); | |
94222f64 | 1198 | Some(tarball.generate()) |
8faf50e0 XL |
1199 | } |
1200 | } | |
abe05a73 | 1201 | |
0731742a XL |
1202 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
1203 | pub struct Miri { | |
dc9dc135 | 1204 | pub compiler: Compiler, |
3dfed10e | 1205 | pub target: TargetSelection, |
0731742a XL |
1206 | } |
1207 | ||
1208 | impl Step for Miri { | |
fc512014 | 1209 | type Output = Option<GeneratedTarball>; |
94222f64 | 1210 | const DEFAULT: bool = true; |
0731742a XL |
1211 | const ONLY_HOSTS: bool = true; |
1212 | ||
9fa01778 | 1213 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
94222f64 | 1214 | let default = should_build_extended_tool(&run.builder, "miri"); |
04454e1e | 1215 | run.alias("miri").default_condition(default) |
0731742a XL |
1216 | } |
1217 | ||
9fa01778 | 1218 | fn make_run(run: RunConfig<'_>) { |
0731742a | 1219 | run.builder.ensure(Miri { |
dc9dc135 XL |
1220 | compiler: run.builder.compiler_for( |
1221 | run.builder.top_stage, | |
1222 | run.builder.config.build, | |
1223 | run.target, | |
1224 | ), | |
0731742a XL |
1225 | target: run.target, |
1226 | }); | |
1227 | } | |
1228 | ||
fc512014 | 1229 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
17df50a5 XL |
1230 | // This prevents miri from being built for "dist" or "install" |
1231 | // on the stable/beta channels. It is a nightly-only tool and should | |
1232 | // not be included. | |
1233 | if !builder.build.unstable_features() { | |
1234 | return None; | |
1235 | } | |
dc9dc135 | 1236 | let compiler = self.compiler; |
0731742a | 1237 | let target = self.target; |
0731742a | 1238 | |
2b03887a FG |
1239 | let miri = builder.ensure(tool::Miri { compiler, target, extra_features: Vec::new() })?; |
1240 | let cargomiri = | |
1241 | builder.ensure(tool::CargoMiri { compiler, target, extra_features: Vec::new() })?; | |
0731742a | 1242 | |
fc512014 XL |
1243 | let mut tarball = Tarball::new(builder, "miri", &target.triple); |
1244 | tarball.set_overlay(OverlayKind::Miri); | |
1245 | tarball.is_preview(true); | |
1246 | tarball.add_file(miri, "bin", 0o755); | |
1247 | tarball.add_file(cargomiri, "bin", 0o755); | |
1248 | tarball.add_legal_and_readme_to("share/doc/miri"); | |
1249 | Some(tarball.generate()) | |
0731742a XL |
1250 | } |
1251 | } | |
1252 | ||
83c7162d | 1253 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
abe05a73 | 1254 | pub struct Rustfmt { |
dc9dc135 | 1255 | pub compiler: Compiler, |
3dfed10e | 1256 | pub target: TargetSelection, |
abe05a73 XL |
1257 | } |
1258 | ||
1259 | impl Step for Rustfmt { | |
fc512014 | 1260 | type Output = Option<GeneratedTarball>; |
94222f64 | 1261 | const DEFAULT: bool = true; |
abe05a73 XL |
1262 | const ONLY_HOSTS: bool = true; |
1263 | ||
9fa01778 | 1264 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
94222f64 | 1265 | let default = should_build_extended_tool(&run.builder, "rustfmt"); |
04454e1e | 1266 | run.alias("rustfmt").default_condition(default) |
abe05a73 XL |
1267 | } |
1268 | ||
9fa01778 | 1269 | fn make_run(run: RunConfig<'_>) { |
abe05a73 | 1270 | run.builder.ensure(Rustfmt { |
dc9dc135 XL |
1271 | compiler: run.builder.compiler_for( |
1272 | run.builder.top_stage, | |
1273 | run.builder.config.build, | |
1274 | run.target, | |
1275 | ), | |
abe05a73 XL |
1276 | target: run.target, |
1277 | }); | |
1278 | } | |
1279 | ||
fc512014 | 1280 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
dc9dc135 | 1281 | let compiler = self.compiler; |
abe05a73 | 1282 | let target = self.target; |
abe05a73 | 1283 | |
dfeec247 XL |
1284 | let rustfmt = builder |
1285 | .ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() }) | |
f2b60f7d | 1286 | .expect("rustfmt expected to build - essential tool"); |
dfeec247 XL |
1287 | let cargofmt = builder |
1288 | .ensure(tool::Cargofmt { compiler, target, extra_features: Vec::new() }) | |
f2b60f7d | 1289 | .expect("cargo fmt expected to build - essential tool"); |
fc512014 XL |
1290 | let mut tarball = Tarball::new(builder, "rustfmt", &target.triple); |
1291 | tarball.set_overlay(OverlayKind::Rustfmt); | |
1292 | tarball.is_preview(true); | |
1293 | tarball.add_file(rustfmt, "bin", 0o755); | |
1294 | tarball.add_file(cargofmt, "bin", 0o755); | |
1295 | tarball.add_legal_and_readme_to("share/doc/rustfmt"); | |
1296 | Some(tarball.generate()) | |
32a655c1 | 1297 | } |
3b2f2976 | 1298 | } |
32a655c1 | 1299 | |
cdc7bbd5 XL |
1300 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
1301 | pub struct RustDemangler { | |
1302 | pub compiler: Compiler, | |
1303 | pub target: TargetSelection, | |
1304 | } | |
1305 | ||
1306 | impl Step for RustDemangler { | |
1307 | type Output = Option<GeneratedTarball>; | |
94222f64 | 1308 | const DEFAULT: bool = true; |
cdc7bbd5 XL |
1309 | const ONLY_HOSTS: bool = true; |
1310 | ||
1311 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
94222f64 XL |
1312 | // While other tools use `should_build_extended_tool` to decide whether to be run by |
1313 | // default or not, `rust-demangler` must be build when *either* it's enabled as a tool like | |
1314 | // the other ones or if `profiler = true`. Because we don't know the target at this stage | |
1315 | // we run the step by default when only `extended = true`, and decide whether to actually | |
1316 | // run it or not later. | |
1317 | let default = run.builder.config.extended; | |
04454e1e | 1318 | run.alias("rust-demangler").default_condition(default) |
cdc7bbd5 XL |
1319 | } |
1320 | ||
1321 | fn make_run(run: RunConfig<'_>) { | |
1322 | run.builder.ensure(RustDemangler { | |
1323 | compiler: run.builder.compiler_for( | |
1324 | run.builder.top_stage, | |
1325 | run.builder.config.build, | |
1326 | run.target, | |
1327 | ), | |
1328 | target: run.target, | |
1329 | }); | |
1330 | } | |
1331 | ||
1332 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { | |
1333 | let compiler = self.compiler; | |
1334 | let target = self.target; | |
cdc7bbd5 XL |
1335 | |
1336 | // Only build this extended tool if explicitly included in `tools`, or if `profiler = true` | |
94222f64 XL |
1337 | let condition = should_build_extended_tool(builder, "rust-demangler") |
1338 | || builder.config.profiler_enabled(target); | |
1339 | if builder.config.extended && !condition { | |
cdc7bbd5 XL |
1340 | return None; |
1341 | } | |
1342 | ||
1343 | let rust_demangler = builder | |
1344 | .ensure(tool::RustDemangler { compiler, target, extra_features: Vec::new() }) | |
1345 | .expect("rust-demangler expected to build - in-tree tool"); | |
1346 | ||
1347 | // Prepare the image directory | |
1348 | let mut tarball = Tarball::new(builder, "rust-demangler", &target.triple); | |
1349 | tarball.set_overlay(OverlayKind::RustDemangler); | |
1350 | tarball.is_preview(true); | |
1351 | tarball.add_file(&rust_demangler, "bin", 0o755); | |
1352 | tarball.add_legal_and_readme_to("share/doc/rust-demangler"); | |
1353 | Some(tarball.generate()) | |
1354 | } | |
1355 | } | |
1356 | ||
83c7162d | 1357 | #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] |
3b2f2976 XL |
1358 | pub struct Extended { |
1359 | stage: u32, | |
3dfed10e XL |
1360 | host: TargetSelection, |
1361 | target: TargetSelection, | |
3b2f2976 XL |
1362 | } |
1363 | ||
1364 | impl Step for Extended { | |
1365 | type Output = (); | |
1366 | const DEFAULT: bool = true; | |
3b2f2976 XL |
1367 | const ONLY_HOSTS: bool = true; |
1368 | ||
9fa01778 | 1369 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
3b2f2976 | 1370 | let builder = run.builder; |
04454e1e | 1371 | run.alias("extended").default_condition(builder.config.extended) |
3b2f2976 | 1372 | } |
32a655c1 | 1373 | |
9fa01778 | 1374 | fn make_run(run: RunConfig<'_>) { |
3b2f2976 XL |
1375 | run.builder.ensure(Extended { |
1376 | stage: run.builder.top_stage, | |
83c7162d | 1377 | host: run.builder.config.build, |
3b2f2976 XL |
1378 | target: run.target, |
1379 | }); | |
1380 | } | |
1381 | ||
1382 | /// Creates a combined installer for the specified target in the provided stage. | |
9fa01778 | 1383 | fn run(self, builder: &Builder<'_>) { |
3b2f2976 | 1384 | let target = self.target; |
dc9dc135 XL |
1385 | let stage = self.stage; |
1386 | let compiler = builder.compiler_for(self.stage, self.host, self.target); | |
3b2f2976 | 1387 | |
dc9dc135 | 1388 | builder.info(&format!("Dist extended stage{} ({})", compiler.stage, target)); |
3b2f2976 | 1389 | |
94222f64 XL |
1390 | let mut tarballs = Vec::new(); |
1391 | let mut built_tools = HashSet::new(); | |
1392 | macro_rules! add_component { | |
1393 | ($name:expr => $step:expr) => { | |
5099ac24 | 1394 | if let Some(tarball) = builder.ensure_if_default($step, Kind::Dist) { |
94222f64 XL |
1395 | tarballs.push(tarball); |
1396 | built_tools.insert($name); | |
1397 | } | |
1398 | }; | |
ea8adc8c | 1399 | } |
3b2f2976 XL |
1400 | |
1401 | // When rust-std package split from rustc, we needed to ensure that during | |
1402 | // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering | |
1403 | // the std files during uninstall. To do this ensure that rustc comes | |
1404 | // before rust-std in the list below. | |
94222f64 XL |
1405 | tarballs.push(builder.ensure(Rustc { compiler: builder.compiler(stage, target) })); |
1406 | tarballs.push(builder.ensure(Std { compiler, target }).expect("missing std")); | |
1407 | ||
04454e1e | 1408 | if target.ends_with("windows-gnu") { |
94222f64 | 1409 | tarballs.push(builder.ensure(Mingw { host: target }).expect("missing mingw")); |
ea8adc8c | 1410 | } |
94222f64 XL |
1411 | |
1412 | add_component!("rust-docs" => Docs { host: target }); | |
2b03887a | 1413 | add_component!("rust-json-docs" => JsonDocs { host: target }); |
94222f64 XL |
1414 | add_component!("rust-demangler"=> RustDemangler { compiler, target }); |
1415 | add_component!("cargo" => Cargo { compiler, target }); | |
1416 | add_component!("rustfmt" => Rustfmt { compiler, target }); | |
1417 | add_component!("rls" => Rls { compiler, target }); | |
1418 | add_component!("rust-analyzer" => RustAnalyzer { compiler, target }); | |
1419 | add_component!("llvm-components" => LlvmTools { target }); | |
1420 | add_component!("clippy" => Clippy { compiler, target }); | |
1421 | add_component!("miri" => Miri { compiler, target }); | |
1422 | add_component!("analysis" => Analysis { compiler, target }); | |
1423 | ||
1424 | let etc = builder.src.join("src/etc/installer"); | |
1425 | ||
1426 | // Avoid producing tarballs during a dry run. | |
487cf647 | 1427 | if builder.config.dry_run() { |
94222f64 | 1428 | return; |
3b2f2976 | 1429 | } |
3b2f2976 | 1430 | |
fc512014 XL |
1431 | let tarball = Tarball::new(builder, "rust", &target.triple); |
1432 | let generated = tarball.combine(&tarballs); | |
1433 | ||
1434 | let tmp = tmpdir(builder).join("combined-tarball"); | |
1435 | let work = generated.work_dir(); | |
32a655c1 | 1436 | |
3b2f2976 | 1437 | let mut license = String::new(); |
83c7162d XL |
1438 | license += &builder.read(&builder.src.join("COPYRIGHT")); |
1439 | license += &builder.read(&builder.src.join("LICENSE-APACHE")); | |
1440 | license += &builder.read(&builder.src.join("LICENSE-MIT")); | |
5869c6ff XL |
1441 | license.push('\n'); |
1442 | license.push('\n'); | |
3b2f2976 XL |
1443 | |
1444 | let rtf = r"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Arial;}}\nowwrap\fs18"; | |
1445 | let mut rtf = rtf.to_string(); | |
5869c6ff | 1446 | rtf.push('\n'); |
3b2f2976 XL |
1447 | for line in license.lines() { |
1448 | rtf.push_str(line); | |
1449 | rtf.push_str("\\line "); | |
1450 | } | |
5869c6ff | 1451 | rtf.push('}'); |
3b2f2976 | 1452 | |
abe05a73 XL |
1453 | fn filter(contents: &str, marker: &str) -> String { |
1454 | let start = format!("tool-{}-start", marker); | |
1455 | let end = format!("tool-{}-end", marker); | |
1456 | let mut lines = Vec::new(); | |
1457 | let mut omitted = false; | |
1458 | for line in contents.lines() { | |
1459 | if line.contains(&start) { | |
1460 | omitted = true; | |
1461 | } else if line.contains(&end) { | |
1462 | omitted = false; | |
1463 | } else if !omitted { | |
1464 | lines.push(line); | |
1465 | } | |
1466 | } | |
1467 | ||
1468 | lines.join("\n") | |
1469 | } | |
1470 | ||
1471 | let xform = |p: &Path| { | |
0731742a | 1472 | let mut contents = t!(fs::read_to_string(p)); |
2b03887a | 1473 | for tool in &["rust-demangler", "miri"] { |
94222f64 XL |
1474 | if !built_tools.contains(tool) { |
1475 | contents = filter(&contents, tool); | |
1476 | } | |
abe05a73 XL |
1477 | } |
1478 | let ret = tmp.join(p.file_name().unwrap()); | |
0731742a XL |
1479 | t!(fs::write(&ret, &contents)); |
1480 | ret | |
abe05a73 XL |
1481 | }; |
1482 | ||
3b2f2976 | 1483 | if target.contains("apple-darwin") { |
e1599b0c | 1484 | builder.info("building pkg installer"); |
3b2f2976 XL |
1485 | let pkg = tmp.join("pkg"); |
1486 | let _ = fs::remove_dir_all(&pkg); | |
3b2f2976 XL |
1487 | |
1488 | let pkgbuild = |component: &str| { | |
1489 | let mut cmd = Command::new("pkgbuild"); | |
dfeec247 XL |
1490 | cmd.arg("--identifier") |
1491 | .arg(format!("org.rust-lang.{}", component)) | |
1492 | .arg("--scripts") | |
1493 | .arg(pkg.join(component)) | |
3b2f2976 XL |
1494 | .arg("--nopayload") |
1495 | .arg(pkg.join(component).with_extension("pkg")); | |
83c7162d | 1496 | builder.run(&mut cmd); |
3b2f2976 | 1497 | }; |
abe05a73 XL |
1498 | |
1499 | let prepare = |name: &str| { | |
83c7162d | 1500 | builder.create_dir(&pkg.join(name)); |
dfeec247 | 1501 | builder.cp_r( |
3dfed10e | 1502 | &work.join(&format!("{}-{}", pkgname(builder, name), target.triple)), |
dfeec247 XL |
1503 | &pkg.join(name), |
1504 | ); | |
83c7162d | 1505 | builder.install(&etc.join("pkg/postinstall"), &pkg.join(name), 0o755); |
abe05a73 XL |
1506 | pkgbuild(name); |
1507 | }; | |
1508 | prepare("rustc"); | |
1509 | prepare("cargo"); | |
abe05a73 XL |
1510 | prepare("rust-std"); |
1511 | prepare("rust-analysis"); | |
f9f354fc | 1512 | prepare("clippy"); |
2b03887a FG |
1513 | prepare("rust-analyzer"); |
1514 | for tool in &["rust-docs", "rust-demangler", "miri"] { | |
94222f64 XL |
1515 | if built_tools.contains(tool) { |
1516 | prepare(tool); | |
1517 | } | |
0731742a | 1518 | } |
3b2f2976 | 1519 | // create an 'uninstall' package |
83c7162d | 1520 | builder.install(&etc.join("pkg/postinstall"), &pkg.join("uninstall"), 0o755); |
3b2f2976 XL |
1521 | pkgbuild("uninstall"); |
1522 | ||
83c7162d XL |
1523 | builder.create_dir(&pkg.join("res")); |
1524 | builder.create(&pkg.join("res/LICENSE.txt"), &license); | |
1525 | builder.install(&etc.join("gfx/rust-logo.png"), &pkg.join("res"), 0o644); | |
3b2f2976 | 1526 | let mut cmd = Command::new("productbuild"); |
dfeec247 XL |
1527 | cmd.arg("--distribution") |
1528 | .arg(xform(&etc.join("pkg/Distribution.xml"))) | |
1529 | .arg("--resources") | |
1530 | .arg(pkg.join("res")) | |
3dfed10e XL |
1531 | .arg(distdir(builder).join(format!( |
1532 | "{}-{}.pkg", | |
1533 | pkgname(builder, "rust"), | |
1534 | target.triple | |
1535 | ))) | |
dfeec247 XL |
1536 | .arg("--package-path") |
1537 | .arg(&pkg); | |
e1599b0c | 1538 | let _time = timeit(builder); |
83c7162d | 1539 | builder.run(&mut cmd); |
3b2f2976 XL |
1540 | } |
1541 | ||
1542 | if target.contains("windows") { | |
1543 | let exe = tmp.join("exe"); | |
1544 | let _ = fs::remove_dir_all(&exe); | |
3b2f2976 | 1545 | |
abe05a73 | 1546 | let prepare = |name: &str| { |
83c7162d | 1547 | builder.create_dir(&exe.join(name)); |
abe05a73 | 1548 | let dir = if name == "rust-std" || name == "rust-analysis" { |
3dfed10e | 1549 | format!("{}-{}", name, target.triple) |
f035d41b XL |
1550 | } else if name == "rust-analyzer" { |
1551 | "rust-analyzer-preview".to_string() | |
8faf50e0 XL |
1552 | } else if name == "clippy" { |
1553 | "clippy-preview".to_string() | |
cdc7bbd5 XL |
1554 | } else if name == "rust-demangler" { |
1555 | "rust-demangler-preview".to_string() | |
0731742a XL |
1556 | } else if name == "miri" { |
1557 | "miri-preview".to_string() | |
abe05a73 XL |
1558 | } else { |
1559 | name.to_string() | |
1560 | }; | |
dfeec247 | 1561 | builder.cp_r( |
3dfed10e | 1562 | &work.join(&format!("{}-{}", pkgname(builder, name), target.triple)).join(dir), |
dfeec247 XL |
1563 | &exe.join(name), |
1564 | ); | |
83c7162d | 1565 | builder.remove(&exe.join(name).join("manifest.in")); |
abe05a73 XL |
1566 | }; |
1567 | prepare("rustc"); | |
1568 | prepare("cargo"); | |
1569 | prepare("rust-analysis"); | |
1570 | prepare("rust-docs"); | |
1571 | prepare("rust-std"); | |
f9f354fc | 1572 | prepare("clippy"); |
2b03887a FG |
1573 | prepare("rust-analyzer"); |
1574 | for tool in &["rust-demangler", "miri"] { | |
94222f64 XL |
1575 | if built_tools.contains(tool) { |
1576 | prepare(tool); | |
1577 | } | |
0731742a | 1578 | } |
04454e1e | 1579 | if target.ends_with("windows-gnu") { |
abe05a73 | 1580 | prepare("rust-mingw"); |
3b2f2976 XL |
1581 | } |
1582 | ||
83c7162d | 1583 | builder.install(&etc.join("gfx/rust-logo.ico"), &exe, 0o644); |
3b2f2976 XL |
1584 | |
1585 | // Generate msi installer | |
a2a8927a XL |
1586 | let wix_path = env::var_os("WIX") |
1587 | .expect("`WIX` environment variable must be set for generating MSI installer(s)."); | |
1588 | let wix = PathBuf::from(wix_path); | |
3b2f2976 XL |
1589 | let heat = wix.join("bin/heat.exe"); |
1590 | let candle = wix.join("bin/candle.exe"); | |
1591 | let light = wix.join("bin/light.exe"); | |
1592 | ||
1593 | let heat_flags = ["-nologo", "-gg", "-sfrag", "-srd", "-sreg"]; | |
dfeec247 XL |
1594 | builder.run( |
1595 | Command::new(&heat) | |
1596 | .current_dir(&exe) | |
1597 | .arg("dir") | |
1598 | .arg("rustc") | |
1599 | .args(&heat_flags) | |
1600 | .arg("-cg") | |
1601 | .arg("RustcGroup") | |
1602 | .arg("-dr") | |
1603 | .arg("Rustc") | |
1604 | .arg("-var") | |
1605 | .arg("var.RustcDir") | |
1606 | .arg("-out") | |
1607 | .arg(exe.join("RustcGroup.wxs")), | |
1608 | ); | |
1609 | builder.run( | |
1610 | Command::new(&heat) | |
1611 | .current_dir(&exe) | |
1612 | .arg("dir") | |
1613 | .arg("rust-docs") | |
1614 | .args(&heat_flags) | |
1615 | .arg("-cg") | |
1616 | .arg("DocsGroup") | |
1617 | .arg("-dr") | |
1618 | .arg("Docs") | |
1619 | .arg("-var") | |
1620 | .arg("var.DocsDir") | |
1621 | .arg("-out") | |
1622 | .arg(exe.join("DocsGroup.wxs")) | |
1623 | .arg("-t") | |
1624 | .arg(etc.join("msi/squash-components.xsl")), | |
1625 | ); | |
1626 | builder.run( | |
1627 | Command::new(&heat) | |
1628 | .current_dir(&exe) | |
1629 | .arg("dir") | |
1630 | .arg("cargo") | |
1631 | .args(&heat_flags) | |
1632 | .arg("-cg") | |
1633 | .arg("CargoGroup") | |
1634 | .arg("-dr") | |
1635 | .arg("Cargo") | |
1636 | .arg("-var") | |
1637 | .arg("var.CargoDir") | |
1638 | .arg("-out") | |
1639 | .arg(exe.join("CargoGroup.wxs")) | |
1640 | .arg("-t") | |
1641 | .arg(etc.join("msi/remove-duplicates.xsl")), | |
1642 | ); | |
1643 | builder.run( | |
1644 | Command::new(&heat) | |
1645 | .current_dir(&exe) | |
1646 | .arg("dir") | |
1647 | .arg("rust-std") | |
1648 | .args(&heat_flags) | |
1649 | .arg("-cg") | |
1650 | .arg("StdGroup") | |
1651 | .arg("-dr") | |
1652 | .arg("Std") | |
1653 | .arg("-var") | |
1654 | .arg("var.StdDir") | |
1655 | .arg("-out") | |
1656 | .arg(exe.join("StdGroup.wxs")), | |
1657 | ); | |
2b03887a FG |
1658 | builder.run( |
1659 | Command::new(&heat) | |
1660 | .current_dir(&exe) | |
1661 | .arg("dir") | |
1662 | .arg("rust-analyzer") | |
1663 | .args(&heat_flags) | |
1664 | .arg("-cg") | |
1665 | .arg("RustAnalyzerGroup") | |
1666 | .arg("-dr") | |
1667 | .arg("RustAnalyzer") | |
1668 | .arg("-var") | |
1669 | .arg("var.RustAnalyzerDir") | |
1670 | .arg("-out") | |
1671 | .arg(exe.join("RustAnalyzerGroup.wxs")) | |
1672 | .arg("-t") | |
1673 | .arg(etc.join("msi/remove-duplicates.xsl")), | |
1674 | ); | |
f9f354fc XL |
1675 | builder.run( |
1676 | Command::new(&heat) | |
1677 | .current_dir(&exe) | |
1678 | .arg("dir") | |
1679 | .arg("clippy") | |
1680 | .args(&heat_flags) | |
1681 | .arg("-cg") | |
1682 | .arg("ClippyGroup") | |
1683 | .arg("-dr") | |
1684 | .arg("Clippy") | |
1685 | .arg("-var") | |
1686 | .arg("var.ClippyDir") | |
1687 | .arg("-out") | |
1688 | .arg(exe.join("ClippyGroup.wxs")) | |
1689 | .arg("-t") | |
1690 | .arg(etc.join("msi/remove-duplicates.xsl")), | |
1691 | ); | |
94222f64 | 1692 | if built_tools.contains("rust-demangler") { |
cdc7bbd5 XL |
1693 | builder.run( |
1694 | Command::new(&heat) | |
1695 | .current_dir(&exe) | |
1696 | .arg("dir") | |
1697 | .arg("rust-demangler") | |
1698 | .args(&heat_flags) | |
1699 | .arg("-cg") | |
1700 | .arg("RustDemanglerGroup") | |
1701 | .arg("-dr") | |
1702 | .arg("RustDemangler") | |
1703 | .arg("-var") | |
1704 | .arg("var.RustDemanglerDir") | |
1705 | .arg("-out") | |
1706 | .arg(exe.join("RustDemanglerGroup.wxs")) | |
1707 | .arg("-t") | |
1708 | .arg(etc.join("msi/remove-duplicates.xsl")), | |
1709 | ); | |
1710 | } | |
94222f64 | 1711 | if built_tools.contains("miri") { |
dfeec247 XL |
1712 | builder.run( |
1713 | Command::new(&heat) | |
1714 | .current_dir(&exe) | |
1715 | .arg("dir") | |
1716 | .arg("miri") | |
1717 | .args(&heat_flags) | |
1718 | .arg("-cg") | |
1719 | .arg("MiriGroup") | |
1720 | .arg("-dr") | |
1721 | .arg("Miri") | |
1722 | .arg("-var") | |
1723 | .arg("var.MiriDir") | |
1724 | .arg("-out") | |
1725 | .arg(exe.join("MiriGroup.wxs")) | |
1726 | .arg("-t") | |
1727 | .arg(etc.join("msi/remove-duplicates.xsl")), | |
1728 | ); | |
0731742a | 1729 | } |
dfeec247 XL |
1730 | builder.run( |
1731 | Command::new(&heat) | |
1732 | .current_dir(&exe) | |
1733 | .arg("dir") | |
1734 | .arg("rust-analysis") | |
1735 | .args(&heat_flags) | |
1736 | .arg("-cg") | |
1737 | .arg("AnalysisGroup") | |
1738 | .arg("-dr") | |
1739 | .arg("Analysis") | |
1740 | .arg("-var") | |
1741 | .arg("var.AnalysisDir") | |
1742 | .arg("-out") | |
1743 | .arg(exe.join("AnalysisGroup.wxs")) | |
1744 | .arg("-t") | |
1745 | .arg(etc.join("msi/remove-duplicates.xsl")), | |
1746 | ); | |
04454e1e | 1747 | if target.ends_with("windows-gnu") { |
dfeec247 XL |
1748 | builder.run( |
1749 | Command::new(&heat) | |
1750 | .current_dir(&exe) | |
1751 | .arg("dir") | |
1752 | .arg("rust-mingw") | |
1753 | .args(&heat_flags) | |
1754 | .arg("-cg") | |
1755 | .arg("GccGroup") | |
1756 | .arg("-dr") | |
1757 | .arg("Gcc") | |
1758 | .arg("-var") | |
1759 | .arg("var.GccDir") | |
1760 | .arg("-out") | |
1761 | .arg(exe.join("GccGroup.wxs")), | |
1762 | ); | |
3b2f2976 | 1763 | } |
32a655c1 | 1764 | |
3b2f2976 | 1765 | let candle = |input: &Path| { |
dfeec247 XL |
1766 | let output = exe.join(input.file_stem().unwrap()).with_extension("wixobj"); |
1767 | let arch = if target.contains("x86_64") { "x64" } else { "x86" }; | |
3b2f2976 XL |
1768 | let mut cmd = Command::new(&candle); |
1769 | cmd.current_dir(&exe) | |
1770 | .arg("-nologo") | |
1771 | .arg("-dRustcDir=rustc") | |
1772 | .arg("-dDocsDir=rust-docs") | |
1773 | .arg("-dCargoDir=cargo") | |
1774 | .arg("-dStdDir=rust-std") | |
3b2f2976 | 1775 | .arg("-dAnalysisDir=rust-analysis") |
f9f354fc | 1776 | .arg("-dClippyDir=clippy") |
dfeec247 XL |
1777 | .arg("-arch") |
1778 | .arg(&arch) | |
1779 | .arg("-out") | |
1780 | .arg(&output) | |
3b2f2976 | 1781 | .arg(&input); |
83c7162d | 1782 | add_env(builder, &mut cmd, target); |
3b2f2976 | 1783 | |
94222f64 | 1784 | if built_tools.contains("rust-demangler") { |
cdc7bbd5 XL |
1785 | cmd.arg("-dRustDemanglerDir=rust-demangler"); |
1786 | } | |
94222f64 | 1787 | if built_tools.contains("rust-analyzer") { |
3dfed10e XL |
1788 | cmd.arg("-dRustAnalyzerDir=rust-analyzer"); |
1789 | } | |
94222f64 | 1790 | if built_tools.contains("miri") { |
0731742a XL |
1791 | cmd.arg("-dMiriDir=miri"); |
1792 | } | |
04454e1e | 1793 | if target.ends_with("windows-gnu") { |
3b2f2976 XL |
1794 | cmd.arg("-dGccDir=rust-mingw"); |
1795 | } | |
83c7162d | 1796 | builder.run(&mut cmd); |
3b2f2976 | 1797 | }; |
abe05a73 | 1798 | candle(&xform(&etc.join("msi/rust.wxs"))); |
3b2f2976 XL |
1799 | candle(&etc.join("msi/ui.wxs")); |
1800 | candle(&etc.join("msi/rustwelcomedlg.wxs")); | |
1801 | candle("RustcGroup.wxs".as_ref()); | |
1802 | candle("DocsGroup.wxs".as_ref()); | |
1803 | candle("CargoGroup.wxs".as_ref()); | |
1804 | candle("StdGroup.wxs".as_ref()); | |
f9f354fc | 1805 | candle("ClippyGroup.wxs".as_ref()); |
2b03887a FG |
1806 | if built_tools.contains("miri") { |
1807 | candle("MiriGroup.wxs".as_ref()); | |
1808 | } | |
94222f64 | 1809 | if built_tools.contains("rust-demangler") { |
cdc7bbd5 XL |
1810 | candle("RustDemanglerGroup.wxs".as_ref()); |
1811 | } | |
94222f64 | 1812 | if built_tools.contains("rust-analyzer") { |
3dfed10e XL |
1813 | candle("RustAnalyzerGroup.wxs".as_ref()); |
1814 | } | |
3b2f2976 | 1815 | candle("AnalysisGroup.wxs".as_ref()); |
32a655c1 | 1816 | |
04454e1e | 1817 | if target.ends_with("windows-gnu") { |
3b2f2976 | 1818 | candle("GccGroup.wxs".as_ref()); |
32a655c1 | 1819 | } |
32a655c1 | 1820 | |
83c7162d XL |
1821 | builder.create(&exe.join("LICENSE.rtf"), &rtf); |
1822 | builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644); | |
1823 | builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644); | |
3b2f2976 | 1824 | |
e1599b0c | 1825 | builder.info(&format!("building `msi` installer with {:?}", light)); |
3dfed10e | 1826 | let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target.triple); |
3b2f2976 XL |
1827 | let mut cmd = Command::new(&light); |
1828 | cmd.arg("-nologo") | |
dfeec247 XL |
1829 | .arg("-ext") |
1830 | .arg("WixUIExtension") | |
1831 | .arg("-ext") | |
1832 | .arg("WixUtilExtension") | |
1833 | .arg("-out") | |
1834 | .arg(exe.join(&filename)) | |
3b2f2976 XL |
1835 | .arg("rust.wixobj") |
1836 | .arg("ui.wixobj") | |
1837 | .arg("rustwelcomedlg.wixobj") | |
1838 | .arg("RustcGroup.wixobj") | |
1839 | .arg("DocsGroup.wixobj") | |
1840 | .arg("CargoGroup.wixobj") | |
1841 | .arg("StdGroup.wixobj") | |
3b2f2976 | 1842 | .arg("AnalysisGroup.wixobj") |
f9f354fc | 1843 | .arg("ClippyGroup.wixobj") |
3b2f2976 | 1844 | .current_dir(&exe); |
32a655c1 | 1845 | |
2b03887a FG |
1846 | if built_tools.contains("miri") { |
1847 | cmd.arg("MiriGroup.wixobj"); | |
1848 | } | |
94222f64 | 1849 | if built_tools.contains("rust-analyzer") { |
3dfed10e XL |
1850 | cmd.arg("RustAnalyzerGroup.wixobj"); |
1851 | } | |
94222f64 | 1852 | if built_tools.contains("rust-demangler") { |
cdc7bbd5 XL |
1853 | cmd.arg("RustDemanglerGroup.wixobj"); |
1854 | } | |
abe05a73 | 1855 | |
04454e1e | 1856 | if target.ends_with("windows-gnu") { |
3b2f2976 XL |
1857 | cmd.arg("GccGroup.wixobj"); |
1858 | } | |
1859 | // ICE57 wrongly complains about the shortcuts | |
1860 | cmd.arg("-sice:ICE57"); | |
1861 | ||
e1599b0c | 1862 | let _time = timeit(builder); |
83c7162d | 1863 | builder.run(&mut cmd); |
32a655c1 | 1864 | |
487cf647 | 1865 | if !builder.config.dry_run() { |
83c7162d XL |
1866 | t!(fs::rename(exe.join(&filename), distdir(builder).join(&filename))); |
1867 | } | |
3b2f2976 | 1868 | } |
32a655c1 SL |
1869 | } |
1870 | } | |
1871 | ||
3dfed10e | 1872 | fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) { |
1b1a35ee | 1873 | let mut parts = builder.version.split('.'); |
83c7162d | 1874 | cmd.env("CFG_RELEASE_INFO", builder.rust_version()) |
1b1a35ee | 1875 | .env("CFG_RELEASE_NUM", &builder.version) |
dfeec247 XL |
1876 | .env("CFG_RELEASE", builder.rust_release()) |
1877 | .env("CFG_VER_MAJOR", parts.next().unwrap()) | |
1878 | .env("CFG_VER_MINOR", parts.next().unwrap()) | |
1879 | .env("CFG_VER_PATCH", parts.next().unwrap()) | |
1880 | .env("CFG_VER_BUILD", "0") // just needed to build | |
1881 | .env("CFG_PACKAGE_VERS", builder.rust_package_vers()) | |
1882 | .env("CFG_PACKAGE_NAME", pkgname(builder, "rust")) | |
3dfed10e | 1883 | .env("CFG_BUILD", target.triple) |
dfeec247 | 1884 | .env("CFG_CHANNEL", &builder.config.channel); |
32a655c1 | 1885 | |
04454e1e FG |
1886 | if target.contains("windows-gnullvm") { |
1887 | cmd.env("CFG_MINGW", "1").env("CFG_ABI", "LLVM"); | |
1888 | } else if target.contains("windows-gnu") { | |
dfeec247 | 1889 | cmd.env("CFG_MINGW", "1").env("CFG_ABI", "GNU"); |
32a655c1 | 1890 | } else { |
dfeec247 | 1891 | cmd.env("CFG_MINGW", "0").env("CFG_ABI", "MSVC"); |
32a655c1 | 1892 | } |
32a655c1 SL |
1893 | } |
1894 | ||
5869c6ff | 1895 | /// Maybe add LLVM object files to the given destination lib-dir. Allows either static or dynamic linking. |
f9f354fc | 1896 | /// |
5869c6ff XL |
1897 | /// Returns whether the files were actually copied. |
1898 | fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool { | |
487cf647 FG |
1899 | if let Some(config) = builder.config.target_config.get(&target) { |
1900 | if config.llvm_config.is_some() && !builder.config.llvm_from_ci { | |
1901 | // If the LLVM was externally provided, then we don't currently copy | |
1902 | // artifacts into the sysroot. This is not necessarily the right | |
1903 | // choice (in particular, it will require the LLVM dylib to be in | |
1904 | // the linker's load path at runtime), but the common use case for | |
1905 | // external LLVMs is distribution provided LLVMs, and in that case | |
1906 | // they're usually in the standard search path (e.g., /usr/lib) and | |
1907 | // copying them here is going to cause problems as we may end up | |
1908 | // with the wrong files and isn't what distributions want. | |
1909 | // | |
1910 | // This behavior may be revisited in the future though. | |
1911 | // | |
1912 | // If the LLVM is coming from ourselves (just from CI) though, we | |
1913 | // still want to install it, as it otherwise won't be available. | |
1914 | return false; | |
1915 | } | |
2a314972 XL |
1916 | } |
1917 | ||
1b1a35ee XL |
1918 | // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib |
1919 | // instead of libLLVM-11-rust-....dylib, as on linux. It's not entirely | |
1920 | // clear why this is the case, though. llvm-config will emit the versioned | |
1921 | // paths and we don't want those in the sysroot (as we're expecting | |
1922 | // unversioned paths). | |
04454e1e | 1923 | if target.contains("apple-darwin") && builder.llvm_link_shared() { |
1b1a35ee | 1924 | let src_libdir = builder.llvm_out(target).join("lib"); |
b7449926 XL |
1925 | let llvm_dylib_path = src_libdir.join("libLLVM.dylib"); |
1926 | if llvm_dylib_path.exists() { | |
f9f354fc | 1927 | builder.install(&llvm_dylib_path, dst_libdir, 0o644); |
b7449926 | 1928 | } |
487cf647 | 1929 | !builder.config.dry_run() |
1b1a35ee | 1930 | } else if let Ok(llvm_config) = crate::native::prebuilt_llvm_config(builder, target) { |
5869c6ff XL |
1931 | let mut cmd = Command::new(llvm_config); |
1932 | cmd.arg("--libfiles"); | |
1933 | builder.verbose(&format!("running {:?}", cmd)); | |
487cf647 | 1934 | let files = if builder.config.dry_run() { "".into() } else { output(&mut cmd) }; |
136023e0 XL |
1935 | let build_llvm_out = &builder.llvm_out(builder.config.build); |
1936 | let target_llvm_out = &builder.llvm_out(target); | |
5869c6ff | 1937 | for file in files.trim_end().split(' ') { |
136023e0 XL |
1938 | // If we're not using a custom LLVM, make sure we package for the target. |
1939 | let file = if let Ok(relative_path) = Path::new(file).strip_prefix(build_llvm_out) { | |
1940 | target_llvm_out.join(relative_path) | |
1941 | } else { | |
1942 | PathBuf::from(file) | |
1943 | }; | |
1944 | builder.install(&file, dst_libdir, 0o644); | |
1b1a35ee | 1945 | } |
487cf647 | 1946 | !builder.config.dry_run() |
5869c6ff XL |
1947 | } else { |
1948 | false | |
b7449926 XL |
1949 | } |
1950 | } | |
1951 | ||
f9f354fc | 1952 | /// Maybe add libLLVM.so to the target lib-dir for linking. |
3dfed10e XL |
1953 | pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) { |
1954 | let dst_libdir = sysroot.join("lib/rustlib").join(&*target.triple).join("lib"); | |
5869c6ff XL |
1955 | // We do not need to copy LLVM files into the sysroot if it is not |
1956 | // dynamically linked; it is already included into librustc_llvm | |
1957 | // statically. | |
04454e1e | 1958 | if builder.llvm_link_shared() { |
5869c6ff XL |
1959 | maybe_install_llvm(builder, target, &dst_libdir); |
1960 | } | |
f9f354fc XL |
1961 | } |
1962 | ||
1963 | /// Maybe add libLLVM.so to the runtime lib-dir for rustc itself. | |
3dfed10e | 1964 | pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) { |
f9f354fc XL |
1965 | let dst_libdir = |
1966 | sysroot.join(builder.sysroot_libdir_relative(Compiler { stage: 1, host: target })); | |
5869c6ff XL |
1967 | // We do not need to copy LLVM files into the sysroot if it is not |
1968 | // dynamically linked; it is already included into librustc_llvm | |
1969 | // statically. | |
04454e1e | 1970 | if builder.llvm_link_shared() { |
5869c6ff XL |
1971 | maybe_install_llvm(builder, target, &dst_libdir); |
1972 | } | |
f9f354fc XL |
1973 | } |
1974 | ||
8faf50e0 XL |
1975 | #[derive(Clone, Debug, Eq, Hash, PartialEq)] |
1976 | pub struct LlvmTools { | |
3dfed10e | 1977 | pub target: TargetSelection, |
8faf50e0 XL |
1978 | } |
1979 | ||
1980 | impl Step for LlvmTools { | |
fc512014 | 1981 | type Output = Option<GeneratedTarball>; |
8faf50e0 | 1982 | const ONLY_HOSTS: bool = true; |
94222f64 | 1983 | const DEFAULT: bool = true; |
8faf50e0 | 1984 | |
9fa01778 | 1985 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
94222f64 | 1986 | let default = should_build_extended_tool(&run.builder, "llvm-tools"); |
04454e1e FG |
1987 | // FIXME: allow using the names of the tools themselves? |
1988 | run.alias("llvm-tools").default_condition(default) | |
8faf50e0 XL |
1989 | } |
1990 | ||
9fa01778 | 1991 | fn make_run(run: RunConfig<'_>) { |
dfeec247 | 1992 | run.builder.ensure(LlvmTools { target: run.target }); |
8faf50e0 XL |
1993 | } |
1994 | ||
fc512014 | 1995 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
8faf50e0 | 1996 | let target = self.target; |
8faf50e0 XL |
1997 | |
1998 | /* run only if llvm-config isn't used */ | |
1999 | if let Some(config) = builder.config.target_config.get(&target) { | |
2000 | if let Some(ref _s) = config.llvm_config { | |
dfeec247 | 2001 | builder.info(&format!("Skipping LlvmTools ({}): external LLVM", target)); |
8faf50e0 XL |
2002 | return None; |
2003 | } | |
2004 | } | |
2005 | ||
923072b8 FG |
2006 | builder.ensure(crate::native::Llvm { target }); |
2007 | ||
fc512014 XL |
2008 | let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple); |
2009 | tarball.set_overlay(OverlayKind::LLVM); | |
2010 | tarball.is_preview(true); | |
8faf50e0 XL |
2011 | |
2012 | // Prepare the image directory | |
dfeec247 | 2013 | let src_bindir = builder.llvm_out(target).join("bin"); |
fc512014 | 2014 | let dst_bindir = format!("lib/rustlib/{}/bin", target.triple); |
8faf50e0 | 2015 | for tool in LLVM_TOOLS { |
3dfed10e | 2016 | let exe = src_bindir.join(exe(tool, target)); |
fc512014 | 2017 | tarball.add_file(&exe, &dst_bindir, 0o755); |
8faf50e0 XL |
2018 | } |
2019 | ||
f9f354fc XL |
2020 | // Copy libLLVM.so to the target lib dir as well, so the RPATH like |
2021 | // `$ORIGIN/../lib` can find it. It may also be used as a dependency | |
2022 | // of `rustc-dev` to support the inherited `-lLLVM` when using the | |
2023 | // compiler libraries. | |
fc512014 XL |
2024 | maybe_install_llvm_target(builder, target, tarball.image_dir()); |
2025 | ||
2026 | Some(tarball.generate()) | |
8faf50e0 XL |
2027 | } |
2028 | } | |
1b1a35ee XL |
2029 | |
2030 | // Tarball intended for internal consumption to ease rustc/std development. | |
2031 | // | |
2032 | // Should not be considered stable by end users. | |
2033 | #[derive(Clone, Debug, Eq, Hash, PartialEq)] | |
2034 | pub struct RustDev { | |
2035 | pub target: TargetSelection, | |
2036 | } | |
2037 | ||
2038 | impl Step for RustDev { | |
fc512014 | 2039 | type Output = Option<GeneratedTarball>; |
1b1a35ee XL |
2040 | const DEFAULT: bool = true; |
2041 | const ONLY_HOSTS: bool = true; | |
2042 | ||
2043 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
04454e1e | 2044 | run.alias("rust-dev") |
1b1a35ee XL |
2045 | } |
2046 | ||
2047 | fn make_run(run: RunConfig<'_>) { | |
2048 | run.builder.ensure(RustDev { target: run.target }); | |
2049 | } | |
2050 | ||
fc512014 | 2051 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { |
1b1a35ee XL |
2052 | let target = self.target; |
2053 | ||
2054 | /* run only if llvm-config isn't used */ | |
2055 | if let Some(config) = builder.config.target_config.get(&target) { | |
2056 | if let Some(ref _s) = config.llvm_config { | |
2057 | builder.info(&format!("Skipping RustDev ({}): external LLVM", target)); | |
2058 | return None; | |
2059 | } | |
2060 | } | |
2061 | ||
fc512014 XL |
2062 | let mut tarball = Tarball::new(builder, "rust-dev", &target.triple); |
2063 | tarball.set_overlay(OverlayKind::LLVM); | |
1b1a35ee | 2064 | |
064997fb FG |
2065 | builder.ensure(crate::native::Llvm { target }); |
2066 | ||
29967ef6 | 2067 | let src_bindir = builder.llvm_out(target).join("bin"); |
923072b8 FG |
2068 | // If updating this list, you likely want to change |
2069 | // src/bootstrap/download-ci-llvm-stamp as well, otherwise local users | |
2070 | // will not pick up the extra file until LLVM gets bumped. | |
fc512014 XL |
2071 | for bin in &[ |
2072 | "llvm-config", | |
2073 | "llvm-ar", | |
2074 | "llvm-objdump", | |
2075 | "llvm-profdata", | |
2076 | "llvm-bcanalyzer", | |
2077 | "llvm-cov", | |
2078 | "llvm-dwp", | |
5e7ed085 | 2079 | "llvm-nm", |
923072b8 | 2080 | "llvm-dwarfdump", |
2b03887a FG |
2081 | "llvm-dis", |
2082 | "llvm-tblgen", | |
fc512014 XL |
2083 | ] { |
2084 | tarball.add_file(src_bindir.join(exe(bin, target)), "bin", 0o755); | |
2085 | } | |
a2a8927a XL |
2086 | |
2087 | // We don't build LLD on some platforms, so only add it if it exists | |
2088 | let lld_path = builder.lld_out(target).join("bin").join(exe("lld", target)); | |
2089 | if lld_path.exists() { | |
2090 | tarball.add_file(lld_path, "bin", 0o755); | |
2091 | } | |
2092 | ||
fc512014 | 2093 | tarball.add_file(&builder.llvm_filecheck(target), "bin", 0o755); |
1b1a35ee XL |
2094 | |
2095 | // Copy the include directory as well; needed mostly to build | |
2096 | // librustc_llvm properly (e.g., llvm-config.h is in here). But also | |
2097 | // just broadly useful to be able to link against the bundled LLVM. | |
fc512014 | 2098 | tarball.add_dir(&builder.llvm_out(target).join("include"), "include"); |
1b1a35ee XL |
2099 | |
2100 | // Copy libLLVM.so to the target lib dir as well, so the RPATH like | |
2101 | // `$ORIGIN/../lib` can find it. It may also be used as a dependency | |
2102 | // of `rustc-dev` to support the inherited `-lLLVM` when using the | |
2103 | // compiler libraries. | |
5869c6ff XL |
2104 | let dst_libdir = tarball.image_dir().join("lib"); |
2105 | maybe_install_llvm(builder, target, &dst_libdir); | |
04454e1e | 2106 | let link_type = if builder.llvm_link_shared() { "dynamic" } else { "static" }; |
5869c6ff | 2107 | t!(std::fs::write(tarball.image_dir().join("link-type.txt"), link_type), dst_libdir); |
fc512014 XL |
2108 | |
2109 | Some(tarball.generate()) | |
1b1a35ee XL |
2110 | } |
2111 | } | |
2112 | ||
2b03887a FG |
2113 | // Tarball intended for internal consumption to ease rustc/std development. |
2114 | // | |
2115 | // Should not be considered stable by end users. | |
2116 | #[derive(Clone, Debug, Eq, Hash, PartialEq)] | |
2117 | pub struct Bootstrap { | |
2118 | pub target: TargetSelection, | |
2119 | } | |
2120 | ||
2121 | impl Step for Bootstrap { | |
2122 | type Output = Option<GeneratedTarball>; | |
2123 | const DEFAULT: bool = false; | |
2124 | const ONLY_HOSTS: bool = true; | |
2125 | ||
2126 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
2127 | run.alias("bootstrap") | |
2128 | } | |
2129 | ||
2130 | fn make_run(run: RunConfig<'_>) { | |
2131 | run.builder.ensure(Bootstrap { target: run.target }); | |
2132 | } | |
2133 | ||
2134 | fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { | |
2135 | let target = self.target; | |
2136 | ||
2137 | let tarball = Tarball::new(builder, "bootstrap", &target.triple); | |
2138 | ||
2139 | let bootstrap_outdir = &builder.bootstrap_out; | |
2140 | for file in &["bootstrap", "llvm-config-wrapper", "rustc", "rustdoc", "sccache-plus-cl"] { | |
2141 | tarball.add_file(bootstrap_outdir.join(exe(file, target)), "bootstrap/bin", 0o755); | |
2142 | } | |
2143 | ||
2144 | Some(tarball.generate()) | |
2145 | } | |
2146 | } | |
2147 | ||
5e7ed085 | 2148 | /// Tarball containing a prebuilt version of the build-manifest tool, intended to be used by the |
1b1a35ee XL |
2149 | /// release process to avoid cloning the monorepo and building stuff. |
2150 | /// | |
2151 | /// Should not be considered stable by end users. | |
2152 | #[derive(Clone, Debug, Eq, Hash, PartialEq)] | |
2153 | pub struct BuildManifest { | |
2154 | pub target: TargetSelection, | |
2155 | } | |
2156 | ||
2157 | impl Step for BuildManifest { | |
fc512014 | 2158 | type Output = GeneratedTarball; |
1b1a35ee XL |
2159 | const DEFAULT: bool = false; |
2160 | const ONLY_HOSTS: bool = true; | |
2161 | ||
2162 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
04454e1e | 2163 | run.alias("build-manifest") |
1b1a35ee XL |
2164 | } |
2165 | ||
2166 | fn make_run(run: RunConfig<'_>) { | |
2167 | run.builder.ensure(BuildManifest { target: run.target }); | |
2168 | } | |
2169 | ||
fc512014 | 2170 | fn run(self, builder: &Builder<'_>) -> GeneratedTarball { |
1b1a35ee XL |
2171 | let build_manifest = builder.tool_exe(Tool::BuildManifest); |
2172 | ||
fc512014 XL |
2173 | let tarball = Tarball::new(builder, "build-manifest", &self.target.triple); |
2174 | tarball.add_file(&build_manifest, "bin", 0o755); | |
2175 | tarball.generate() | |
2176 | } | |
2177 | } | |
2178 | ||
2179 | /// Tarball containing artifacts necessary to reproduce the build of rustc. | |
2180 | /// | |
2181 | /// Currently this is the PGO profile data. | |
2182 | /// | |
2183 | /// Should not be considered stable by end users. | |
2184 | #[derive(Clone, Debug, Eq, Hash, PartialEq)] | |
2185 | pub struct ReproducibleArtifacts { | |
2186 | pub target: TargetSelection, | |
2187 | } | |
2188 | ||
2189 | impl Step for ReproducibleArtifacts { | |
2190 | type Output = Option<GeneratedTarball>; | |
2191 | const DEFAULT: bool = true; | |
2192 | const ONLY_HOSTS: bool = true; | |
2193 | ||
2194 | fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { | |
04454e1e | 2195 | run.alias("reproducible-artifacts") |
fc512014 XL |
2196 | } |
2197 | ||
2198 | fn make_run(run: RunConfig<'_>) { | |
2199 | run.builder.ensure(ReproducibleArtifacts { target: run.target }); | |
2200 | } | |
2201 | ||
2202 | fn run(self, builder: &Builder<'_>) -> Self::Output { | |
94222f64 | 2203 | let mut added_anything = false; |
fc512014 | 2204 | let tarball = Tarball::new(builder, "reproducible-artifacts", &self.target.triple); |
94222f64 XL |
2205 | if let Some(path) = builder.config.rust_profile_use.as_ref() { |
2206 | tarball.add_file(path, ".", 0o644); | |
2207 | added_anything = true; | |
2208 | } | |
2209 | if let Some(path) = builder.config.llvm_profile_use.as_ref() { | |
2210 | tarball.add_file(path, ".", 0o644); | |
2211 | added_anything = true; | |
2212 | } | |
2b03887a FG |
2213 | if let Some(path) = builder.config.llvm_bolt_profile_use.as_ref() { |
2214 | tarball.add_file(path, ".", 0o644); | |
2215 | added_anything = true; | |
2216 | } | |
94222f64 | 2217 | if added_anything { Some(tarball.generate()) } else { None } |
1b1a35ee XL |
2218 | } |
2219 | } |