]> git.proxmox.com Git - rustc.git/blame - src/bootstrap/dist.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / src / bootstrap / dist.rs
CommitLineData
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 11use std::collections::HashSet;
32a655c1 12use std::env;
487cf647 13use std::ffi::OsStr;
0731742a 14use std::fs;
dfeec247 15use std::path::{Path, PathBuf};
29967ef6 16use std::process::Command;
32a655c1 17
487cf647
FG
18use object::read::archive::ArchiveFile;
19use object::BinaryFormat;
20
5099ac24 21use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
dfeec247 22use crate::cache::{Interned, INTERNER};
2b03887a 23use crate::channel;
0731742a 24use crate::compile;
3dfed10e 25use crate::config::TargetSelection;
487cf647 26use crate::doc::DocumentationFormat;
fc512014 27use crate::tarball::{GeneratedTarball, OverlayKind, Tarball};
0731742a 28use crate::tool::{self, Tool};
5e7ed085 29use crate::util::{exe, is_dylib, output, t, timeit};
f035d41b 30use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS};
54a0048b 31
9fa01778 32pub fn pkgname(builder: &Builder<'_>, component: &str) -> String {
1b1a35ee 33 format!("{}-{}", component, builder.rust_package_vers())
32a655c1
SL
34}
35
1b1a35ee 36pub(crate) fn distdir(builder: &Builder<'_>) -> PathBuf {
83c7162d 37 builder.out.join("dist")
54a0048b
SL
38}
39
9fa01778 40pub fn tmpdir(builder: &Builder<'_>) -> PathBuf {
83c7162d 41 builder.out.join("tmp/dist")
54a0048b
SL
42}
43
94222f64
XL
44fn 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 52pub struct Docs {
3dfed10e 53 pub host: TargetSelection,
3b2f2976
XL
54}
55
56impl 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)]
85pub struct JsonDocs {
86 pub host: TargetSelection,
87}
88
89impl 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)]
122pub struct RustcDocs {
3dfed10e 123 pub host: TargetSelection,
0531ce1d
XL
124}
125
126impl 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 151fn 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 167fn 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 301pub struct Mingw {
3dfed10e 302 pub host: TargetSelection,
54a0048b
SL
303}
304
3b2f2976 305impl 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
341pub struct Rustc {
342 pub compiler: Compiler,
343}
344
345impl 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)]
497pub struct DebuggerScripts {
498 pub sysroot: Interned<PathBuf>,
3dfed10e 499 pub host: TargetSelection,
3b2f2976 500}
a7813a04 501
3b2f2976
XL
502impl 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
551fn 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.
565fn 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
596fn 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
611pub struct Std {
612 pub compiler: Compiler,
3dfed10e 613 pub target: TargetSelection,
3b2f2976
XL
614}
615
616impl 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)]
658pub struct RustcDev {
659 pub compiler: Compiler,
3dfed10e 660 pub target: TargetSelection,
e74abb32
XL
661}
662
663impl 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)]
717pub struct Analysis {
718 pub compiler: Compiler,
3dfed10e 719 pub target: TargetSelection,
7cac9316
XL
720}
721
3b2f2976 722impl 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`.
770fn 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
856pub struct Src;
857
858impl 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 913pub struct PlainSourceTarball;
5bcae85e 914
3b2f2976
XL
915impl 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 1002pub struct Cargo {
dc9dc135 1003 pub compiler: Compiler,
3dfed10e 1004 pub target: TargetSelection,
3b2f2976
XL
1005}
1006
1007impl 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 1058pub struct Rls {
dc9dc135 1059 pub compiler: Compiler,
3dfed10e 1060 pub target: TargetSelection,
cc61c64b
XL
1061}
1062
3b2f2976 1063impl 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)]
1102pub struct RustAnalyzer {
1103 pub compiler: Compiler,
3dfed10e 1104 pub target: TargetSelection,
f035d41b
XL
1105}
1106
1107impl 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)]
1152pub struct Clippy {
dc9dc135 1153 pub compiler: Compiler,
3dfed10e 1154 pub target: TargetSelection,
8faf50e0
XL
1155}
1156
1157impl 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)]
1203pub struct Miri {
dc9dc135 1204 pub compiler: Compiler,
3dfed10e 1205 pub target: TargetSelection,
0731742a
XL
1206}
1207
1208impl 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 1254pub struct Rustfmt {
dc9dc135 1255 pub compiler: Compiler,
3dfed10e 1256 pub target: TargetSelection,
abe05a73
XL
1257}
1258
1259impl 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)]
1301pub struct RustDemangler {
1302 pub compiler: Compiler,
1303 pub target: TargetSelection,
1304}
1305
1306impl 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
1358pub struct Extended {
1359 stage: u32,
3dfed10e
XL
1360 host: TargetSelection,
1361 target: TargetSelection,
3b2f2976
XL
1362}
1363
1364impl 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 1872fn 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.
1898fn 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
1953pub 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 1964pub 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)]
1976pub struct LlvmTools {
3dfed10e 1977 pub target: TargetSelection,
8faf50e0
XL
1978}
1979
1980impl 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)]
2034pub struct RustDev {
2035 pub target: TargetSelection,
2036}
2037
2038impl 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)]
2117pub struct Bootstrap {
2118 pub target: TargetSelection,
2119}
2120
2121impl 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)]
2153pub struct BuildManifest {
2154 pub target: TargetSelection,
2155}
2156
2157impl 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)]
2185pub struct ReproducibleArtifacts {
2186 pub target: TargetSelection,
2187}
2188
2189impl 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}