]> git.proxmox.com Git - rustc.git/blame - src/bootstrap/dist.rs
New upstream version 1.48.0~beta.8+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
32a655c1 11use std::env;
0731742a
XL
12use std::fs;
13use std::io::Write;
dfeec247 14use std::path::{Path, PathBuf};
32a655c1
SL
15use std::process::{Command, Stdio};
16
48663c56 17use build_helper::{output, t};
54a0048b 18
0731742a 19use crate::builder::{Builder, RunConfig, ShouldRun, Step};
dfeec247 20use crate::cache::{Interned, INTERNER};
0731742a 21use crate::compile;
3dfed10e 22use crate::config::TargetSelection;
0731742a 23use crate::tool::{self, Tool};
dfeec247 24use crate::util::{exe, is_dylib, timeit};
f035d41b 25use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS};
9fa01778 26use time::{self, Timespec};
54a0048b 27
9fa01778 28pub fn pkgname(builder: &Builder<'_>, component: &str) -> String {
1b1a35ee 29 format!("{}-{}", component, builder.rust_package_vers())
32a655c1
SL
30}
31
1b1a35ee 32pub(crate) fn distdir(builder: &Builder<'_>) -> PathBuf {
83c7162d 33 builder.out.join("dist")
54a0048b
SL
34}
35
9fa01778 36pub fn tmpdir(builder: &Builder<'_>) -> PathBuf {
83c7162d 37 builder.out.join("tmp/dist")
54a0048b
SL
38}
39
9fa01778 40fn rust_installer(builder: &Builder<'_>) -> Command {
3b2f2976 41 builder.tool_cmd(Tool::RustInstaller)
7cac9316
XL
42}
43
0bf4aa26
XL
44fn missing_tool(tool_name: &str, skip: bool) {
45 if skip {
46 println!("Unable to build {}, skipping dist", tool_name)
47 } else {
48 panic!("Unable to build {}", tool_name)
49 }
50}
51
83c7162d 52#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976 53pub struct Docs {
3dfed10e 54 pub host: TargetSelection,
3b2f2976
XL
55}
56
57impl Step for Docs {
58 type Output = PathBuf;
59 const DEFAULT: bool = true;
3b2f2976 60
9fa01778 61 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976 62 run.path("src/doc")
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.
9fa01778 70 fn run(self, builder: &Builder<'_>) -> PathBuf {
3b2f2976
XL
71 let host = self.host;
72
83c7162d 73 let name = pkgname(builder, "rust-docs");
3b2f2976 74
83c7162d 75 if !builder.config.docs {
3dfed10e 76 return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple));
3b2f2976
XL
77 }
78
79 builder.default_doc(None);
80
e1599b0c
XL
81 builder.info(&format!("Dist docs ({})", host));
82 let _time = timeit(builder);
83
3dfed10e 84 let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple));
3b2f2976
XL
85 let _ = fs::remove_dir_all(&image);
86
87 let dst = image.join("share/doc/rust/html");
54a0048b 88 t!(fs::create_dir_all(&dst));
83c7162d
XL
89 let src = builder.doc_out(host);
90 builder.cp_r(&src, &dst);
74b04a01 91 builder.install(&builder.src.join("src/doc/robots.txt"), &dst, 0o644);
3b2f2976
XL
92
93 let mut cmd = rust_installer(builder);
94 cmd.arg("generate")
dfeec247
XL
95 .arg("--product-name=Rust-Documentation")
96 .arg("--rel-manifest-dir=rustlib")
97 .arg("--success-message=Rust-documentation-is-installed.")
98 .arg("--image-dir")
99 .arg(&image)
100 .arg("--work-dir")
101 .arg(&tmpdir(builder))
102 .arg("--output-dir")
103 .arg(&distdir(builder))
3dfed10e 104 .arg(format!("--package-name={}-{}", name, host.triple))
dfeec247
XL
105 .arg("--component-name=rust-docs")
106 .arg("--legacy-manifest-dirs=rustlib,cargo")
107 .arg("--bulk-dirs=share/doc/rust/html");
83c7162d
XL
108 builder.run(&mut cmd);
109 builder.remove_dir(&image);
3b2f2976 110
3dfed10e 111 distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple))
0531ce1d
XL
112 }
113}
114
115#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
116pub struct RustcDocs {
3dfed10e 117 pub host: TargetSelection,
0531ce1d
XL
118}
119
120impl Step for RustcDocs {
121 type Output = PathBuf;
122 const DEFAULT: bool = true;
123
9fa01778 124 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
0531ce1d
XL
125 run.path("src/librustc")
126 }
127
9fa01778 128 fn make_run(run: RunConfig<'_>) {
dfeec247 129 run.builder.ensure(RustcDocs { host: run.target });
0531ce1d
XL
130 }
131
132 /// Builds the `rustc-docs` installer component.
9fa01778 133 fn run(self, builder: &Builder<'_>) -> PathBuf {
0531ce1d
XL
134 let host = self.host;
135
83c7162d 136 let name = pkgname(builder, "rustc-docs");
0531ce1d 137
83c7162d 138 if !builder.config.compiler_docs {
3dfed10e 139 return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple));
3b2f2976
XL
140 }
141
0531ce1d
XL
142 builder.default_doc(None);
143
3dfed10e 144 let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple));
0531ce1d
XL
145 let _ = fs::remove_dir_all(&image);
146
3dfed10e 147 let dst = image.join("share/doc/rust/html/rustc");
0531ce1d 148 t!(fs::create_dir_all(&dst));
83c7162d
XL
149 let src = builder.compiler_doc_out(host);
150 builder.cp_r(&src, &dst);
0531ce1d
XL
151
152 let mut cmd = rust_installer(builder);
153 cmd.arg("generate")
dfeec247
XL
154 .arg("--product-name=Rustc-Documentation")
155 .arg("--rel-manifest-dir=rustlib")
156 .arg("--success-message=Rustc-documentation-is-installed.")
157 .arg("--image-dir")
158 .arg(&image)
159 .arg("--work-dir")
160 .arg(&tmpdir(builder))
161 .arg("--output-dir")
162 .arg(&distdir(builder))
3dfed10e 163 .arg(format!("--package-name={}-{}", name, host.triple))
dfeec247
XL
164 .arg("--component-name=rustc-docs")
165 .arg("--legacy-manifest-dirs=rustlib,cargo")
3dfed10e 166 .arg("--bulk-dirs=share/doc/rust/html/rustc");
e1599b0c
XL
167
168 builder.info(&format!("Dist compiler docs ({})", host));
169 let _time = timeit(builder);
83c7162d
XL
170 builder.run(&mut cmd);
171 builder.remove_dir(&image);
0531ce1d 172
3dfed10e 173 distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple))
54a0048b
SL
174 }
175}
176
7cac9316 177fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> {
041b39d2 178 let mut found = Vec::with_capacity(files.len());
7cac9316
XL
179
180 for file in files {
dfeec247 181 let file_path = path.iter().map(|dir| dir.join(file)).find(|p| p.exists());
7cac9316
XL
182
183 if let Some(file_path) = file_path {
184 found.push(file_path);
185 } else {
186 panic!("Could not find '{}' in {:?}", file, path);
187 }
188 }
189
190 found
191}
192
3b2f2976 193fn make_win_dist(
dfeec247
XL
194 rust_root: &Path,
195 plat_root: &Path,
3dfed10e 196 target: TargetSelection,
dfeec247 197 builder: &Builder<'_>,
3b2f2976 198) {
7cac9316 199 //Ask gcc where it keeps its stuff
3dfed10e 200 let mut cmd = Command::new(builder.cc(target));
7cac9316 201 cmd.arg("-print-search-dirs");
041b39d2
XL
202 let gcc_out = output(&mut cmd);
203
204 let mut bin_path: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect();
7cac9316
XL
205 let mut lib_path = Vec::new();
206
207 for line in gcc_out.lines() {
208 let idx = line.find(':').unwrap();
209 let key = &line[..idx];
210 let trim_chars: &[_] = &[' ', '='];
3dfed10e 211 let value = env::split_paths(line[(idx + 1)..].trim_start_matches(trim_chars));
7cac9316
XL
212
213 if key == "programs" {
214 bin_path.extend(value);
215 } else if key == "libraries" {
216 lib_path.extend(value);
217 }
218 }
219
3dfed10e 220 let compiler = if target == "i686-pc-windows-gnu" {
74b04a01 221 "i686-w64-mingw32-gcc.exe"
3dfed10e 222 } else if target == "x86_64-pc-windows-gnu" {
74b04a01
XL
223 "x86_64-w64-mingw32-gcc.exe"
224 } else {
225 "gcc.exe"
226 };
227 let target_tools = [compiler, "ld.exe", "dlltool.exe", "libwinpthread-1.dll"];
e74abb32 228 let mut rustc_dlls = vec!["libwinpthread-1.dll"];
3dfed10e 229 if target.starts_with("i686-") {
7cac9316
XL
230 rustc_dlls.push("libgcc_s_dw2-1.dll");
231 } else {
232 rustc_dlls.push("libgcc_s_seh-1.dll");
233 }
234
dfeec247
XL
235 let target_libs = [
236 //MinGW libs
7cac9316
XL
237 "libgcc.a",
238 "libgcc_eh.a",
239 "libgcc_s.a",
240 "libm.a",
241 "libmingw32.a",
242 "libmingwex.a",
243 "libstdc++.a",
244 "libiconv.a",
245 "libmoldname.a",
246 "libpthread.a",
247 //Windows import libs
248 "libadvapi32.a",
249 "libbcrypt.a",
250 "libcomctl32.a",
251 "libcomdlg32.a",
0531ce1d 252 "libcredui.a",
7cac9316 253 "libcrypt32.a",
0531ce1d 254 "libdbghelp.a",
7cac9316
XL
255 "libgdi32.a",
256 "libimagehlp.a",
257 "libiphlpapi.a",
258 "libkernel32.a",
0531ce1d 259 "libmsimg32.a",
7cac9316
XL
260 "libmsvcrt.a",
261 "libodbc32.a",
262 "libole32.a",
263 "liboleaut32.a",
264 "libopengl32.a",
265 "libpsapi.a",
266 "librpcrt4.a",
0531ce1d 267 "libsecur32.a",
7cac9316
XL
268 "libsetupapi.a",
269 "libshell32.a",
0531ce1d 270 "libsynchronization.a",
7cac9316
XL
271 "libuser32.a",
272 "libuserenv.a",
273 "libuuid.a",
274 "libwinhttp.a",
275 "libwinmm.a",
276 "libwinspool.a",
277 "libws2_32.a",
278 "libwsock32.a",
279 ];
280
281 //Find mingw artifacts we want to bundle
282 let target_tools = find_files(&target_tools, &bin_path);
283 let rustc_dlls = find_files(&rustc_dlls, &bin_path);
284 let target_libs = find_files(&target_libs, &lib_path);
285
83c7162d 286 // Copy runtime dlls next to rustc.exe
7cac9316
XL
287 let dist_bin_dir = rust_root.join("bin/");
288 fs::create_dir_all(&dist_bin_dir).expect("creating dist_bin_dir failed");
289 for src in rustc_dlls {
83c7162d 290 builder.copy_to_folder(&src, &dist_bin_dir);
7cac9316
XL
291 }
292
293 //Copy platform tools to platform-specific bin directory
f035d41b
XL
294 let target_bin_dir = plat_root
295 .join("lib")
296 .join("rustlib")
3dfed10e 297 .join(target.triple)
f035d41b
XL
298 .join("bin")
299 .join("self-contained");
7cac9316
XL
300 fs::create_dir_all(&target_bin_dir).expect("creating target_bin_dir failed");
301 for src in target_tools {
83c7162d 302 builder.copy_to_folder(&src, &target_bin_dir);
7cac9316
XL
303 }
304
8faf50e0
XL
305 // Warn windows-gnu users that the bundled GCC cannot compile C files
306 builder.create(
307 &target_bin_dir.join("GCC-WARNING.txt"),
1b1a35ee
XL
308 "gcc.exe contained in this folder cannot be used for compiling C files - it is only \
309 used as a linker. In order to be able to compile projects containing C code use \
dfeec247 310 the GCC provided by MinGW or Cygwin.",
8faf50e0
XL
311 );
312
7cac9316 313 //Copy platform libs to platform-specific lib directory
f035d41b
XL
314 let target_lib_dir = plat_root
315 .join("lib")
316 .join("rustlib")
3dfed10e 317 .join(target.triple)
f035d41b
XL
318 .join("lib")
319 .join("self-contained");
7cac9316
XL
320 fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed");
321 for src in target_libs {
83c7162d 322 builder.copy_to_folder(&src, &target_lib_dir);
7cac9316
XL
323 }
324}
325
83c7162d 326#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976 327pub struct Mingw {
3dfed10e 328 pub host: TargetSelection,
54a0048b
SL
329}
330
3b2f2976
XL
331impl Step for Mingw {
332 type Output = Option<PathBuf>;
333 const DEFAULT: bool = true;
3b2f2976 334
9fa01778 335 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976 336 run.never()
54a0048b
SL
337 }
338
9fa01778 339 fn make_run(run: RunConfig<'_>) {
3b2f2976
XL
340 run.builder.ensure(Mingw { host: run.target });
341 }
342
9fa01778 343 /// Builds the `rust-mingw` installer component.
3b2f2976
XL
344 ///
345 /// This contains all the bits and pieces to run the MinGW Windows targets
0731742a 346 /// without any extra installed software (e.g., we bundle gcc, libraries, etc).
9fa01778 347 fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
3b2f2976
XL
348 let host = self.host;
349
350 if !host.contains("pc-windows-gnu") {
351 return None;
54a0048b
SL
352 }
353
83c7162d 354 builder.info(&format!("Dist mingw ({})", host));
e1599b0c 355 let _time = timeit(builder);
83c7162d 356 let name = pkgname(builder, "rust-mingw");
3dfed10e 357 let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple));
3b2f2976
XL
358 let _ = fs::remove_dir_all(&image);
359 t!(fs::create_dir_all(&image));
360
361 // The first argument is a "temporary directory" which is just
362 // thrown away (this contains the runtime DLLs included in the rustc package
363 // above) and the second argument is where to place all the MinGW components
364 // (which is what we want).
83c7162d 365 make_win_dist(&tmpdir(builder), &image, host, &builder);
3b2f2976
XL
366
367 let mut cmd = rust_installer(builder);
368 cmd.arg("generate")
dfeec247
XL
369 .arg("--product-name=Rust-MinGW")
370 .arg("--rel-manifest-dir=rustlib")
371 .arg("--success-message=Rust-MinGW-is-installed.")
372 .arg("--image-dir")
373 .arg(&image)
374 .arg("--work-dir")
375 .arg(&tmpdir(builder))
376 .arg("--output-dir")
377 .arg(&distdir(builder))
3dfed10e 378 .arg(format!("--package-name={}-{}", name, host.triple))
dfeec247
XL
379 .arg("--component-name=rust-mingw")
380 .arg("--legacy-manifest-dirs=rustlib,cargo");
83c7162d 381 builder.run(&mut cmd);
3b2f2976 382 t!(fs::remove_dir_all(&image));
3dfed10e 383 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple)))
3b2f2976
XL
384 }
385}
54a0048b 386
83c7162d 387#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976
XL
388pub struct Rustc {
389 pub compiler: Compiler,
390}
391
392impl Step for Rustc {
393 type Output = PathBuf;
394 const DEFAULT: bool = true;
395 const ONLY_HOSTS: bool = true;
3b2f2976 396
9fa01778 397 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
398 run.path("src/librustc")
399 }
400
9fa01778 401 fn make_run(run: RunConfig<'_>) {
dfeec247
XL
402 run.builder
403 .ensure(Rustc { compiler: run.builder.compiler(run.builder.top_stage, run.target) });
3b2f2976
XL
404 }
405
406 /// Creates the `rustc` installer component.
9fa01778 407 fn run(self, builder: &Builder<'_>) -> PathBuf {
3b2f2976
XL
408 let compiler = self.compiler;
409 let host = self.compiler.host;
54a0048b 410
83c7162d 411 let name = pkgname(builder, "rustc");
3dfed10e 412 let image = tmpdir(builder).join(format!("{}-{}-image", name, host.triple));
3b2f2976 413 let _ = fs::remove_dir_all(&image);
3dfed10e 414 let overlay = tmpdir(builder).join(format!("{}-{}-overlay", name, host.triple));
3b2f2976
XL
415 let _ = fs::remove_dir_all(&overlay);
416
417 // Prepare the rustc "image", what will actually end up getting installed
418 prepare_image(builder, compiler, &image);
419
420 // Prepare the overlay which is part of the tarball but won't actually be
421 // installed
54a0048b 422 let cp = |file: &str| {
83c7162d 423 builder.install(&builder.src.join(file), &overlay, 0o644);
54a0048b 424 };
54a0048b
SL
425 cp("COPYRIGHT");
426 cp("LICENSE-APACHE");
427 cp("LICENSE-MIT");
428 cp("README.md");
3b2f2976 429 // tiny morsel of metadata is used by rust-packaging
83c7162d
XL
430 let version = builder.rust_version();
431 builder.create(&overlay.join("version"), &version);
432 if let Some(sha) = builder.rust_sha() {
433 builder.create(&overlay.join("git-commit-hash"), &sha);
ea8adc8c 434 }
3b2f2976
XL
435
436 // On MinGW we've got a few runtime DLL dependencies that we need to
437 // include. The first argument to this script is where to put these DLLs
438 // (the image we're creating), and the second argument is a junk directory
439 // to ignore all other MinGW stuff the script creates.
440 //
441 // On 32-bit MinGW we're always including a DLL which needs some extra
442 // licenses to distribute. On 64-bit MinGW we don't actually distribute
443 // anything requiring us to distribute a license, but it's likely the
444 // install will *also* include the rust-mingw package, which also needs
445 // licenses, so to be safe we just include it here in all MinGW packages.
446 if host.contains("pc-windows-gnu") {
83c7162d 447 make_win_dist(&image, &tmpdir(builder), host, builder);
3b2f2976
XL
448
449 let dst = image.join("share/doc");
450 t!(fs::create_dir_all(&dst));
83c7162d 451 builder.cp_r(&builder.src.join("src/etc/third-party"), &dst);
3b2f2976
XL
452 }
453
454 // Finally, wrap everything up in a nice tarball!
455 let mut cmd = rust_installer(builder);
456 cmd.arg("generate")
dfeec247
XL
457 .arg("--product-name=Rust")
458 .arg("--rel-manifest-dir=rustlib")
459 .arg("--success-message=Rust-is-ready-to-roll.")
460 .arg("--image-dir")
461 .arg(&image)
462 .arg("--work-dir")
463 .arg(&tmpdir(builder))
464 .arg("--output-dir")
465 .arg(&distdir(builder))
466 .arg("--non-installed-overlay")
467 .arg(&overlay)
3dfed10e 468 .arg(format!("--package-name={}-{}", name, host.triple))
dfeec247
XL
469 .arg("--component-name=rustc")
470 .arg("--legacy-manifest-dirs=rustlib,cargo");
e1599b0c 471
3dfed10e 472 builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host.triple));
e1599b0c 473 let _time = timeit(builder);
83c7162d
XL
474 builder.run(&mut cmd);
475 builder.remove_dir(&image);
476 builder.remove_dir(&overlay);
3b2f2976 477
3dfed10e 478 return distdir(builder).join(format!("{}-{}.tar.gz", name, host.triple));
3b2f2976 479
9fa01778 480 fn prepare_image(builder: &Builder<'_>, compiler: Compiler, image: &Path) {
3b2f2976 481 let host = compiler.host;
3b2f2976 482 let src = builder.sysroot(compiler);
3b2f2976
XL
483
484 // Copy rustc/rustdoc binaries
485 t!(fs::create_dir_all(image.join("bin")));
83c7162d 486 builder.cp_r(&src.join("bin"), &image.join("bin"));
3b2f2976 487
532ac7d7
XL
488 builder.install(&builder.rustdoc(compiler), &image.join("bin"), 0o755);
489
490 let libdir_relative = builder.libdir_relative(compiler);
3b2f2976
XL
491
492 // Copy runtime DLLs needed by the compiler
532ac7d7 493 if libdir_relative.to_str() != Some("bin") {
e1599b0c 494 let libdir = builder.rustc_libdir(compiler);
532ac7d7 495 for entry in builder.read_dir(&libdir) {
3b2f2976
XL
496 let name = entry.file_name();
497 if let Some(s) = name.to_str() {
498 if is_dylib(s) {
e1599b0c
XL
499 // Don't use custom libdir here because ^lib/ will be resolved again
500 // with installer
501 builder.install(&entry.path(), &image.join("lib"), 0o644);
3b2f2976
XL
502 }
503 }
504 }
505 }
506
b7449926
XL
507 // Copy libLLVM.so to the lib dir as well, if needed. While not
508 // technically needed by rustc itself it's needed by lots of other
509 // components like the llvm tools and LLD. LLD is included below and
510 // tools/LLDB come later, so let's just throw it in the rustc
511 // component for now.
f9f354fc 512 maybe_install_llvm_runtime(builder, host, image);
b7449926 513
0531ce1d
XL
514 // Copy over lld if it's there
515 if builder.config.lld_enabled {
3dfed10e 516 let exe = exe("rust-lld", compiler.host);
dfeec247
XL
517 let src =
518 builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin").join(&exe);
8faf50e0 519 // for the rationale about this rename check `compile::copy_lld_to_sysroot`
3dfed10e 520 let dst = image.join("lib/rustlib").join(&*host.triple).join("bin").join(&exe);
0531ce1d 521 t!(fs::create_dir_all(&dst.parent().unwrap()));
83c7162d 522 builder.copy(&src, &dst);
0531ce1d
XL
523 }
524
3b2f2976
XL
525 // Man pages
526 t!(fs::create_dir_all(image.join("share/man/man1")));
83c7162d 527 let man_src = builder.src.join("src/doc/man");
ff7c6d11 528 let man_dst = image.join("share/man/man1");
9fa01778
XL
529
530 // Reproducible builds: If SOURCE_DATE_EPOCH is set, use that as the time.
531 let time = env::var("SOURCE_DATE_EPOCH")
532 .map(|timestamp| {
dfeec247
XL
533 let epoch = timestamp
534 .parse()
535 .map_err(|err| format!("could not parse SOURCE_DATE_EPOCH: {}", err))
536 .unwrap();
9fa01778
XL
537
538 time::at(Timespec::new(epoch, 0))
539 })
540 .unwrap_or_else(|_| time::now());
541
542 let month_year = t!(time::strftime("%B %Y", &time));
ff7c6d11
XL
543 // don't use our `bootstrap::util::{copy, cp_r}`, because those try
544 // to hardlink, and we don't want to edit the source templates
83c7162d 545 for file_entry in builder.read_dir(&man_src) {
ff7c6d11
XL
546 let page_src = file_entry.path();
547 let page_dst = man_dst.join(file_entry.file_name());
548 t!(fs::copy(&page_src, &page_dst));
549 // template in month/year and version number
dfeec247
XL
550 builder.replace_in_file(
551 &page_dst,
552 &[
553 ("<INSERT DATE HERE>", &month_year),
1b1a35ee 554 ("<INSERT VERSION HERE>", &builder.version),
dfeec247
XL
555 ],
556 );
ff7c6d11 557 }
3b2f2976
XL
558
559 // Debugger scripts
dfeec247
XL
560 builder
561 .ensure(DebuggerScripts { sysroot: INTERNER.intern_path(image.to_owned()), host });
3b2f2976
XL
562
563 // Misc license info
564 let cp = |file: &str| {
83c7162d 565 builder.install(&builder.src.join(file), &image.join("share/doc/rust"), 0o644);
3b2f2976
XL
566 };
567 cp("COPYRIGHT");
568 cp("LICENSE-APACHE");
569 cp("LICENSE-MIT");
570 cp("README.md");
571 }
54a0048b
SL
572 }
573}
574
3b2f2976
XL
575#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
576pub struct DebuggerScripts {
577 pub sysroot: Interned<PathBuf>,
3dfed10e 578 pub host: TargetSelection,
3b2f2976 579}
a7813a04 580
3b2f2976
XL
581impl Step for DebuggerScripts {
582 type Output = ();
583
9fa01778 584 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
585 run.path("src/lldb_batchmode.py")
586 }
a7813a04 587
9fa01778 588 fn make_run(run: RunConfig<'_>) {
3b2f2976 589 run.builder.ensure(DebuggerScripts {
1b1a35ee
XL
590 sysroot: run
591 .builder
592 .sysroot(run.builder.compiler(run.builder.top_stage, run.build_triple())),
3b2f2976
XL
593 host: run.target,
594 });
595 }
a7813a04 596
3b2f2976 597 /// Copies debugger scripts for `target` into the `sysroot` specified.
9fa01778 598 fn run(self, builder: &Builder<'_>) {
3b2f2976
XL
599 let host = self.host;
600 let sysroot = self.sysroot;
601 let dst = sysroot.join("lib/rustlib/etc");
602 t!(fs::create_dir_all(&dst));
603 let cp_debugger_script = |file: &str| {
83c7162d 604 builder.install(&builder.src.join("src/etc/").join(file), &dst, 0o644);
3b2f2976
XL
605 };
606 if host.contains("windows-msvc") {
607 // windbg debugger scripts
dfeec247
XL
608 builder.install(
609 &builder.src.join("src/etc/rust-windbg.cmd"),
610 &sysroot.join("bin"),
611 0o755,
612 );
a7813a04 613
ff7c6d11 614 cp_debugger_script("natvis/intrinsic.natvis");
3b2f2976
XL
615 cp_debugger_script("natvis/liballoc.natvis");
616 cp_debugger_script("natvis/libcore.natvis");
60c5eb7d 617 cp_debugger_script("natvis/libstd.natvis");
3b2f2976 618 } else {
f035d41b 619 cp_debugger_script("rust_types.py");
3b2f2976
XL
620
621 // gdb debugger scripts
dfeec247
XL
622 builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755);
623 builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), 0o755);
3b2f2976
XL
624
625 cp_debugger_script("gdb_load_rust_pretty_printers.py");
f035d41b
XL
626 cp_debugger_script("gdb_lookup.py");
627 cp_debugger_script("gdb_providers.py");
3b2f2976
XL
628
629 // lldb debugger scripts
dfeec247 630 builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"), 0o755);
3b2f2976 631
f035d41b
XL
632 cp_debugger_script("lldb_lookup.py");
633 cp_debugger_script("lldb_providers.py");
6c58768f 634 cp_debugger_script("lldb_commands")
3b2f2976 635 }
a7813a04
XL
636 }
637}
638
e74abb32
XL
639fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
640 // The only true set of target libraries came from the build triple, so
641 // let's reduce redundant work by only producing archives from that host.
642 if compiler.host != builder.config.build {
643 builder.info("\tskipping, not a build host");
644 true
645 } else {
646 false
647 }
648}
649
650/// Copy stamped files into an image's `target/lib` directory.
3dfed10e
XL
651fn copy_target_libs(builder: &Builder<'_>, target: TargetSelection, image: &Path, stamp: &Path) {
652 let dst = image.join("lib/rustlib").join(target.triple).join("lib");
f035d41b 653 let self_contained_dst = dst.join("self-contained");
e74abb32 654 t!(fs::create_dir_all(&dst));
f035d41b
XL
655 t!(fs::create_dir_all(&self_contained_dst));
656 for (path, dependency_type) in builder.read_stamp_file(stamp) {
657 if dependency_type == DependencyType::TargetSelfContained {
658 builder.copy(&path, &self_contained_dst.join(path.file_name().unwrap()));
659 } else if dependency_type == DependencyType::Target || builder.config.build == target {
e74abb32
XL
660 builder.copy(&path, &dst.join(path.file_name().unwrap()));
661 }
662 }
663}
664
83c7162d 665#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976
XL
666pub struct Std {
667 pub compiler: Compiler,
3dfed10e 668 pub target: TargetSelection,
3b2f2976
XL
669}
670
671impl Step for Std {
672 type Output = PathBuf;
673 const DEFAULT: bool = true;
3b2f2976 674
9fa01778 675 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3dfed10e 676 run.path("library/std")
476ff2be
SL
677 }
678
9fa01778 679 fn make_run(run: RunConfig<'_>) {
3b2f2976 680 run.builder.ensure(Std {
dc9dc135
XL
681 compiler: run.builder.compiler_for(
682 run.builder.top_stage,
683 run.builder.config.build,
684 run.target,
685 ),
3b2f2976
XL
686 target: run.target,
687 });
688 }
689
9fa01778 690 fn run(self, builder: &Builder<'_>) -> PathBuf {
3b2f2976
XL
691 let compiler = self.compiler;
692 let target = self.target;
693
83c7162d 694 let name = pkgname(builder, "rust-std");
3dfed10e 695 let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple));
e74abb32
XL
696 if skip_host_target_lib(builder, compiler) {
697 return archive;
3b2f2976
XL
698 }
699
e74abb32 700 builder.ensure(compile::Std { compiler, target });
3b2f2976 701
3dfed10e 702 let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple));
3b2f2976
XL
703 let _ = fs::remove_dir_all(&image);
704
e74abb32
XL
705 let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
706 let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
3dfed10e 707 copy_target_libs(builder, target, &image, &stamp);
3b2f2976
XL
708
709 let mut cmd = rust_installer(builder);
710 cmd.arg("generate")
dfeec247
XL
711 .arg("--product-name=Rust")
712 .arg("--rel-manifest-dir=rustlib")
713 .arg("--success-message=std-is-standing-at-the-ready.")
714 .arg("--image-dir")
715 .arg(&image)
716 .arg("--work-dir")
717 .arg(&tmpdir(builder))
718 .arg("--output-dir")
719 .arg(&distdir(builder))
3dfed10e
XL
720 .arg(format!("--package-name={}-{}", name, target.triple))
721 .arg(format!("--component-name=rust-std-{}", target.triple))
dfeec247
XL
722 .arg("--legacy-manifest-dirs=rustlib,cargo");
723
724 builder
725 .info(&format!("Dist std stage{} ({} -> {})", compiler.stage, &compiler.host, target));
e1599b0c 726 let _time = timeit(builder);
83c7162d
XL
727 builder.run(&mut cmd);
728 builder.remove_dir(&image);
e74abb32
XL
729 archive
730 }
731}
732
733#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
734pub struct RustcDev {
735 pub compiler: Compiler,
3dfed10e 736 pub target: TargetSelection,
e74abb32
XL
737}
738
739impl Step for RustcDev {
740 type Output = PathBuf;
741 const DEFAULT: bool = true;
742 const ONLY_HOSTS: bool = true;
743
744 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
745 run.path("rustc-dev")
746 }
747
748 fn make_run(run: RunConfig<'_>) {
749 run.builder.ensure(RustcDev {
750 compiler: run.builder.compiler_for(
751 run.builder.top_stage,
752 run.builder.config.build,
753 run.target,
754 ),
755 target: run.target,
756 });
757 }
758
759 fn run(self, builder: &Builder<'_>) -> PathBuf {
760 let compiler = self.compiler;
761 let target = self.target;
762
763 let name = pkgname(builder, "rustc-dev");
3dfed10e 764 let archive = distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple));
e74abb32
XL
765 if skip_host_target_lib(builder, compiler) {
766 return archive;
767 }
768
769 builder.ensure(compile::Rustc { compiler, target });
770
3dfed10e 771 let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple));
e74abb32
XL
772 let _ = fs::remove_dir_all(&image);
773
774 let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
775 let stamp = compile::librustc_stamp(builder, compiler_to_use, target);
3dfed10e 776 copy_target_libs(builder, target, &image, &stamp);
e74abb32 777
1b1a35ee
XL
778 // Copy compiler sources.
779 let dst_src = image.join("lib/rustlib/rustc-src/rust");
780 t!(fs::create_dir_all(&dst_src));
781
782 let src_files = ["Cargo.lock"];
783 // This is the reduced set of paths which will become the rustc-dev component
784 // (essentially the compiler crates and all of their path dependencies).
785 copy_src_dirs(builder, &builder.src, &["compiler"], &[], &dst_src);
786 for file in src_files.iter() {
787 builder.copy(&builder.src.join(file), &dst_src.join(file));
788 }
789
e74abb32
XL
790 let mut cmd = rust_installer(builder);
791 cmd.arg("generate")
dfeec247
XL
792 .arg("--product-name=Rust")
793 .arg("--rel-manifest-dir=rustlib")
794 .arg("--success-message=Rust-is-ready-to-develop.")
795 .arg("--image-dir")
796 .arg(&image)
797 .arg("--work-dir")
798 .arg(&tmpdir(builder))
799 .arg("--output-dir")
800 .arg(&distdir(builder))
3dfed10e
XL
801 .arg(format!("--package-name={}-{}", name, target.triple))
802 .arg(format!("--component-name=rustc-dev-{}", target.triple))
dfeec247
XL
803 .arg("--legacy-manifest-dirs=rustlib,cargo");
804
805 builder.info(&format!(
806 "Dist rustc-dev stage{} ({} -> {})",
807 compiler.stage, &compiler.host, target
808 ));
e74abb32
XL
809 let _time = timeit(builder);
810 builder.run(&mut cmd);
811 builder.remove_dir(&image);
812 archive
3b2f2976 813 }
476ff2be
SL
814}
815
3b2f2976
XL
816#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
817pub struct Analysis {
818 pub compiler: Compiler,
3dfed10e 819 pub target: TargetSelection,
7cac9316
XL
820}
821
3b2f2976
XL
822impl Step for Analysis {
823 type Output = PathBuf;
824 const DEFAULT: bool = true;
476ff2be 825
9fa01778 826 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976 827 let builder = run.builder;
83c7162d 828 run.path("analysis").default_condition(builder.config.extended)
476ff2be
SL
829 }
830
9fa01778 831 fn make_run(run: RunConfig<'_>) {
3b2f2976 832 run.builder.ensure(Analysis {
dc9dc135
XL
833 // Find the actual compiler (handling the full bootstrap option) which
834 // produced the save-analysis data because that data isn't copied
835 // through the sysroot uplifting.
836 compiler: run.builder.compiler_for(
837 run.builder.top_stage,
838 run.builder.config.build,
839 run.target,
840 ),
3b2f2976
XL
841 target: run.target,
842 });
843 }
844
845 /// Creates a tarball of save-analysis metadata, if available.
9fa01778 846 fn run(self, builder: &Builder<'_>) -> PathBuf {
3b2f2976
XL
847 let compiler = self.compiler;
848 let target = self.target;
83c7162d 849 assert!(builder.config.extended);
83c7162d 850 let name = pkgname(builder, "rust-analysis");
3b2f2976 851
74b04a01 852 if compiler.host != builder.config.build {
3dfed10e 853 return distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple));
3b2f2976
XL
854 }
855
e1599b0c 856 builder.ensure(compile::Std { compiler, target });
3b2f2976 857
3dfed10e 858 let image = tmpdir(builder).join(format!("{}-{}-image", name, target.triple));
3b2f2976 859
dfeec247
XL
860 let src = builder
861 .stage_out(compiler, Mode::Std)
3dfed10e 862 .join(target.triple)
dfeec247
XL
863 .join(builder.cargo_dir())
864 .join("deps");
3b2f2976
XL
865
866 let image_src = src.join("save-analysis");
3dfed10e 867 let dst = image.join("lib/rustlib").join(target.triple).join("analysis");
3b2f2976 868 t!(fs::create_dir_all(&dst));
83c7162d
XL
869 builder.info(&format!("image_src: {:?}, dst: {:?}", image_src, dst));
870 builder.cp_r(&image_src, &dst);
3b2f2976
XL
871
872 let mut cmd = rust_installer(builder);
873 cmd.arg("generate")
dfeec247
XL
874 .arg("--product-name=Rust")
875 .arg("--rel-manifest-dir=rustlib")
876 .arg("--success-message=save-analysis-saved.")
877 .arg("--image-dir")
878 .arg(&image)
879 .arg("--work-dir")
880 .arg(&tmpdir(builder))
881 .arg("--output-dir")
882 .arg(&distdir(builder))
3dfed10e
XL
883 .arg(format!("--package-name={}-{}", name, target.triple))
884 .arg(format!("--component-name=rust-analysis-{}", target.triple))
dfeec247 885 .arg("--legacy-manifest-dirs=rustlib,cargo");
e1599b0c
XL
886
887 builder.info("Dist analysis");
888 let _time = timeit(builder);
83c7162d
XL
889 builder.run(&mut cmd);
890 builder.remove_dir(&image);
3dfed10e 891 distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))
3b2f2976 892 }
476ff2be
SL
893}
894
3dfed10e
XL
895/// Use the `builder` to make a filtered copy of `base`/X for X in (`src_dirs` - `exclude_dirs`) to
896/// `dst_dir`.
897fn copy_src_dirs(
898 builder: &Builder<'_>,
899 base: &Path,
900 src_dirs: &[&str],
901 exclude_dirs: &[&str],
902 dst_dir: &Path,
903) {
7cac9316
XL
904 fn filter_fn(exclude_dirs: &[&str], dir: &str, path: &Path) -> bool {
905 let spath = match path.to_str() {
906 Some(path) => path,
907 None => return false,
908 };
74b04a01 909 if spath.ends_with('~') || spath.ends_with(".pyc") {
dfeec247 910 return false;
7cac9316 911 }
9fa01778
XL
912
913 const LLVM_PROJECTS: &[&str] = &[
dfeec247
XL
914 "llvm-project/clang",
915 "llvm-project\\clang",
916 "llvm-project/libunwind",
917 "llvm-project\\libunwind",
918 "llvm-project/lld",
919 "llvm-project\\lld",
920 "llvm-project/lldb",
921 "llvm-project\\lldb",
922 "llvm-project/llvm",
923 "llvm-project\\llvm",
924 "llvm-project/compiler-rt",
925 "llvm-project\\compiler-rt",
9fa01778 926 ];
dfeec247
XL
927 if spath.contains("llvm-project")
928 && !spath.ends_with("llvm-project")
9fa01778
XL
929 && !LLVM_PROJECTS.iter().any(|path| spath.contains(path))
930 {
931 return false;
932 }
933
dfeec247
XL
934 const LLVM_TEST: &[&str] = &["llvm-project/llvm/test", "llvm-project\\llvm\\test"];
935 if LLVM_TEST.iter().any(|path| spath.contains(path))
936 && (spath.ends_with(".ll") || spath.ends_with(".td") || spath.ends_with(".s"))
937 {
938 return false;
7cac9316 939 }
8bb4bdeb 940
7cac9316
XL
941 let full_path = Path::new(dir).join(path);
942 if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) {
943 return false;
944 }
945
946 let excludes = [
dfeec247
XL
947 "CVS",
948 "RCS",
949 "SCCS",
950 ".git",
951 ".gitignore",
952 ".gitmodules",
953 ".gitattributes",
954 ".cvsignore",
955 ".svn",
956 ".arch-ids",
957 "{arch}",
958 "=RELEASE-ID",
959 "=meta-update",
960 "=update",
961 ".bzr",
962 ".bzrignore",
963 ".bzrtags",
964 ".hg",
965 ".hgignore",
966 ".hgrags",
967 "_darcs",
7cac9316 968 ];
dfeec247 969 !path.iter().map(|s| s.to_str().unwrap()).any(|s| excludes.contains(&s))
8bb4bdeb
XL
970 }
971
7cac9316
XL
972 // Copy the directories using our filter
973 for item in src_dirs {
974 let dst = &dst_dir.join(item);
975 t!(fs::create_dir_all(dst));
3dfed10e 976 builder.cp_filtered(&base.join(item), dst, &|path| filter_fn(exclude_dirs, item, path));
7cac9316
XL
977 }
978}
979
83c7162d 980#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976
XL
981pub struct Src;
982
983impl Step for Src {
984 /// The output path of the src installer tarball
985 type Output = PathBuf;
986 const DEFAULT: bool = true;
987 const ONLY_HOSTS: bool = true;
3b2f2976 988
9fa01778 989 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
990 run.path("src")
991 }
992
9fa01778 993 fn make_run(run: RunConfig<'_>) {
3b2f2976
XL
994 run.builder.ensure(Src);
995 }
7cac9316 996
3b2f2976 997 /// Creates the `rust-src` installer component
9fa01778 998 fn run(self, builder: &Builder<'_>) -> PathBuf {
83c7162d
XL
999 let name = pkgname(builder, "rust-src");
1000 let image = tmpdir(builder).join(format!("{}-image", name));
3b2f2976
XL
1001 let _ = fs::remove_dir_all(&image);
1002
3dfed10e
XL
1003 // A lot of tools expect the rust-src component to be entirely in this directory, so if you
1004 // change that (e.g. by adding another directory `lib/rustlib/src/foo` or
1005 // `lib/rustlib/src/rust/foo`), you will need to go around hunting for implicit assumptions
1006 // and fix them...
1007 //
1008 // NOTE: if you update the paths here, you also should update the "virtual" path
1009 // translation code in `imported_source_files` in `src/librustc_metadata/rmeta/decoder.rs`
1010 let dst_src = image.join("lib/rustlib/src/rust");
3b2f2976
XL
1011 t!(fs::create_dir_all(&dst_src));
1012
dfeec247 1013 let src_files = ["Cargo.lock"];
3b2f2976 1014 // This is the reduced set of paths which will become the rust-src component
3dfed10e
XL
1015 // (essentially libstd and all of its path dependencies).
1016 copy_src_dirs(
1017 builder,
1018 &builder.src,
1b1a35ee 1019 &["library", "src/llvm-project/libunwind"],
3dfed10e
XL
1020 &[
1021 // not needed and contains symlinks which rustup currently
1022 // chokes on when unpacking.
1023 "library/backtrace/crates",
1024 ],
1025 &dst_src,
1026 );
ea8adc8c 1027 for file in src_files.iter() {
83c7162d 1028 builder.copy(&builder.src.join(file), &dst_src.join(file));
ea8adc8c 1029 }
3b2f2976
XL
1030
1031 // Create source tarball in rust-installer format
1032 let mut cmd = rust_installer(builder);
1033 cmd.arg("generate")
dfeec247
XL
1034 .arg("--product-name=Rust")
1035 .arg("--rel-manifest-dir=rustlib")
1036 .arg("--success-message=Awesome-Source.")
1037 .arg("--image-dir")
1038 .arg(&image)
1039 .arg("--work-dir")
1040 .arg(&tmpdir(builder))
1041 .arg("--output-dir")
1042 .arg(&distdir(builder))
1043 .arg(format!("--package-name={}", name))
1044 .arg("--component-name=rust-src")
1045 .arg("--legacy-manifest-dirs=rustlib,cargo");
e1599b0c
XL
1046
1047 builder.info("Dist src");
1048 let _time = timeit(builder);
83c7162d 1049 builder.run(&mut cmd);
3b2f2976 1050
83c7162d
XL
1051 builder.remove_dir(&image);
1052 distdir(builder).join(&format!("{}.tar.gz", name))
3b2f2976 1053 }
7cac9316
XL
1054}
1055
83c7162d 1056#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976 1057pub struct PlainSourceTarball;
5bcae85e 1058
3b2f2976
XL
1059impl Step for PlainSourceTarball {
1060 /// Produces the location of the tarball generated
1061 type Output = PathBuf;
1062 const DEFAULT: bool = true;
1063 const ONLY_HOSTS: bool = true;
3b2f2976 1064
9fa01778 1065 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
1066 let builder = run.builder;
1067 run.path("src").default_condition(builder.config.rust_dist_src)
1068 }
5bcae85e 1069
9fa01778 1070 fn make_run(run: RunConfig<'_>) {
3b2f2976 1071 run.builder.ensure(PlainSourceTarball);
5bcae85e
SL
1072 }
1073
3b2f2976 1074 /// Creates the plain source tarball
9fa01778 1075 fn run(self, builder: &Builder<'_>) -> PathBuf {
3b2f2976 1076 // Make sure that the root folder of tarball has the correct name
83c7162d
XL
1077 let plain_name = format!("{}-src", pkgname(builder, "rustc"));
1078 let plain_dst_src = tmpdir(builder).join(&plain_name);
3b2f2976
XL
1079 let _ = fs::remove_dir_all(&plain_dst_src);
1080 t!(fs::create_dir_all(&plain_dst_src));
1081
1082 // This is the set of root paths which will become part of the source package
1083 let src_files = [
1084 "COPYRIGHT",
1085 "LICENSE-APACHE",
1086 "LICENSE-MIT",
1087 "CONTRIBUTING.md",
1088 "README.md",
1089 "RELEASES.md",
1090 "configure",
1091 "x.py",
ea8adc8c 1092 "config.toml.example",
a1dfa0c6
XL
1093 "Cargo.toml",
1094 "Cargo.lock",
3b2f2976 1095 ];
1b1a35ee 1096 let src_dirs = ["src", "compiler", "library"];
3b2f2976 1097
3dfed10e 1098 copy_src_dirs(builder, &builder.src, &src_dirs, &[], &plain_dst_src);
7cac9316 1099
3b2f2976
XL
1100 // Copy the files normally
1101 for item in &src_files {
83c7162d 1102 builder.copy(&builder.src.join(item), &plain_dst_src.join(item));
8bb4bdeb 1103 }
3b2f2976
XL
1104
1105 // Create the version file
83c7162d
XL
1106 builder.create(&plain_dst_src.join("version"), &builder.rust_version());
1107 if let Some(sha) = builder.rust_sha() {
1108 builder.create(&plain_dst_src.join("git-commit-hash"), &sha);
ea8adc8c 1109 }
3b2f2976
XL
1110
1111 // If we're building from git sources, we need to vendor a complete distribution.
83c7162d 1112 if builder.rust_info.is_git() {
3b2f2976 1113 // Vendor all Cargo dependencies
83c7162d 1114 let mut cmd = Command::new(&builder.initial_cargo);
f035d41b
XL
1115 cmd.arg("vendor")
1116 .arg("--sync")
1117 .arg(builder.src.join("./src/tools/rust-analyzer/Cargo.toml"))
1118 .current_dir(&plain_dst_src);
83c7162d 1119 builder.run(&mut cmd);
8bb4bdeb
XL
1120 }
1121
3b2f2976 1122 // Create plain source tarball
83c7162d
XL
1123 let plain_name = format!("rustc-{}-src", builder.rust_package_vers());
1124 let mut tarball = distdir(builder).join(&format!("{}.tar.gz", plain_name));
3b2f2976
XL
1125 tarball.set_extension(""); // strip .gz
1126 tarball.set_extension(""); // strip .tar
1127 if let Some(dir) = tarball.parent() {
83c7162d 1128 builder.create_dir(&dir);
3b2f2976 1129 }
8faf50e0 1130 builder.info("running installer");
3b2f2976
XL
1131 let mut cmd = rust_installer(builder);
1132 cmd.arg("tarball")
dfeec247
XL
1133 .arg("--input")
1134 .arg(&plain_name)
1135 .arg("--output")
1136 .arg(&tarball)
1137 .arg("--work-dir=.")
1138 .current_dir(tmpdir(builder));
e1599b0c
XL
1139
1140 builder.info("Create plain source tarball");
1141 let _time = timeit(builder);
83c7162d
XL
1142 builder.run(&mut cmd);
1143 distdir(builder).join(&format!("{}.tar.gz", plain_name))
8bb4bdeb 1144 }
5bcae85e
SL
1145}
1146
54a0048b
SL
1147// We have to run a few shell scripts, which choke quite a bit on both `\`
1148// characters and on `C:\` paths, so normalize both of them away.
c30ab7b3 1149pub fn sanitize_sh(path: &Path) -> String {
54a0048b
SL
1150 let path = path.to_str().unwrap().replace("\\", "/");
1151 return change_drive(&path).unwrap_or(path);
1152
1153 fn change_drive(s: &str) -> Option<String> {
1154 let mut ch = s.chars();
1155 let drive = ch.next().unwrap_or('C');
1156 if ch.next() != Some(':') {
dfeec247 1157 return None;
54a0048b
SL
1158 }
1159 if ch.next() != Some('/') {
dfeec247 1160 return None;
54a0048b
SL
1161 }
1162 Some(format!("/{}/{}", drive, &s[drive.len_utf8() + 2..]))
1163 }
1164}
9e0c209e 1165
83c7162d 1166#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976 1167pub struct Cargo {
dc9dc135 1168 pub compiler: Compiler,
3dfed10e 1169 pub target: TargetSelection,
3b2f2976
XL
1170}
1171
1172impl Step for Cargo {
1173 type Output = PathBuf;
3b2f2976
XL
1174 const ONLY_HOSTS: bool = true;
1175
9fa01778 1176 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
1177 run.path("cargo")
1178 }
1179
9fa01778 1180 fn make_run(run: RunConfig<'_>) {
3b2f2976 1181 run.builder.ensure(Cargo {
dc9dc135
XL
1182 compiler: run.builder.compiler_for(
1183 run.builder.top_stage,
1184 run.builder.config.build,
1185 run.target,
1186 ),
3b2f2976
XL
1187 target: run.target,
1188 });
1189 }
1190
9fa01778 1191 fn run(self, builder: &Builder<'_>) -> PathBuf {
dc9dc135 1192 let compiler = self.compiler;
3b2f2976
XL
1193 let target = self.target;
1194
83c7162d 1195 let src = builder.src.join("src/tools/cargo");
3b2f2976 1196 let etc = src.join("src/etc");
83c7162d
XL
1197 let release_num = builder.release_num("cargo");
1198 let name = pkgname(builder, "cargo");
1199 let version = builder.cargo_info.version(builder, &release_num);
3b2f2976 1200
83c7162d 1201 let tmp = tmpdir(builder);
3b2f2976
XL
1202 let image = tmp.join("cargo-image");
1203 drop(fs::remove_dir_all(&image));
83c7162d 1204 builder.create_dir(&image);
3b2f2976
XL
1205
1206 // Prepare the image directory
83c7162d
XL
1207 builder.create_dir(&image.join("share/zsh/site-functions"));
1208 builder.create_dir(&image.join("etc/bash_completion.d"));
dc9dc135 1209 let cargo = builder.ensure(tool::Cargo { compiler, target });
83c7162d 1210 builder.install(&cargo, &image.join("bin"), 0o755);
3b2f2976
XL
1211 for man in t!(etc.join("man").read_dir()) {
1212 let man = t!(man);
83c7162d 1213 builder.install(&man.path(), &image.join("share/man/man1"), 0o644);
3b2f2976 1214 }
83c7162d 1215 builder.install(&etc.join("_cargo"), &image.join("share/zsh/site-functions"), 0o644);
dfeec247 1216 builder.copy(&etc.join("cargo.bashcomp.sh"), &image.join("etc/bash_completion.d/cargo"));
3b2f2976 1217 let doc = image.join("share/doc/cargo");
83c7162d
XL
1218 builder.install(&src.join("README.md"), &doc, 0o644);
1219 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1220 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1221 builder.install(&src.join("LICENSE-THIRD-PARTY"), &doc, 0o644);
3b2f2976
XL
1222
1223 // Prepare the overlay
1224 let overlay = tmp.join("cargo-overlay");
1225 drop(fs::remove_dir_all(&overlay));
83c7162d
XL
1226 builder.create_dir(&overlay);
1227 builder.install(&src.join("README.md"), &overlay, 0o644);
1228 builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
1229 builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
1230 builder.install(&src.join("LICENSE-THIRD-PARTY"), &overlay, 0o644);
1231 builder.create(&overlay.join("version"), &version);
3b2f2976
XL
1232
1233 // Generate the installer tarball
1234 let mut cmd = rust_installer(builder);
1235 cmd.arg("generate")
dfeec247
XL
1236 .arg("--product-name=Rust")
1237 .arg("--rel-manifest-dir=rustlib")
1238 .arg("--success-message=Rust-is-ready-to-roll.")
1239 .arg("--image-dir")
1240 .arg(&image)
1241 .arg("--work-dir")
1242 .arg(&tmpdir(builder))
1243 .arg("--output-dir")
1244 .arg(&distdir(builder))
1245 .arg("--non-installed-overlay")
1246 .arg(&overlay)
3dfed10e 1247 .arg(format!("--package-name={}-{}", name, target.triple))
dfeec247
XL
1248 .arg("--component-name=cargo")
1249 .arg("--legacy-manifest-dirs=rustlib,cargo");
e1599b0c
XL
1250
1251 builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target));
1252 let _time = timeit(builder);
83c7162d 1253 builder.run(&mut cmd);
3dfed10e 1254 distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))
8bb4bdeb 1255 }
32a655c1
SL
1256}
1257
83c7162d 1258#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976 1259pub struct Rls {
dc9dc135 1260 pub compiler: Compiler,
3dfed10e 1261 pub target: TargetSelection,
cc61c64b
XL
1262}
1263
3b2f2976 1264impl Step for Rls {
abe05a73 1265 type Output = Option<PathBuf>;
3b2f2976
XL
1266 const ONLY_HOSTS: bool = true;
1267
9fa01778 1268 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976 1269 run.path("rls")
32a655c1
SL
1270 }
1271
9fa01778 1272 fn make_run(run: RunConfig<'_>) {
3b2f2976 1273 run.builder.ensure(Rls {
dc9dc135
XL
1274 compiler: run.builder.compiler_for(
1275 run.builder.top_stage,
1276 run.builder.config.build,
1277 run.target,
1278 ),
3b2f2976
XL
1279 target: run.target,
1280 });
32a655c1 1281 }
3b2f2976 1282
9fa01778 1283 fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
dc9dc135 1284 let compiler = self.compiler;
3b2f2976 1285 let target = self.target;
83c7162d 1286 assert!(builder.config.extended);
3b2f2976 1287
83c7162d
XL
1288 let src = builder.src.join("src/tools/rls");
1289 let release_num = builder.release_num("rls");
1290 let name = pkgname(builder, "rls");
1291 let version = builder.rls_info.version(builder, &release_num);
3b2f2976 1292
83c7162d 1293 let tmp = tmpdir(builder);
3b2f2976
XL
1294 let image = tmp.join("rls-image");
1295 drop(fs::remove_dir_all(&image));
1296 t!(fs::create_dir_all(&image));
1297
1298 // Prepare the image directory
abe05a73
XL
1299 // We expect RLS to build, because we've exited this step above if tool
1300 // state for RLS isn't testing.
dfeec247
XL
1301 let rls = builder
1302 .ensure(tool::Rls { compiler, target, extra_features: Vec::new() })
1303 .or_else(|| {
1304 missing_tool("RLS", builder.build.config.missing_tools);
1305 None
1306 })?;
ff7c6d11 1307
83c7162d 1308 builder.install(&rls, &image.join("bin"), 0o755);
3b2f2976 1309 let doc = image.join("share/doc/rls");
83c7162d
XL
1310 builder.install(&src.join("README.md"), &doc, 0o644);
1311 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1312 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
3b2f2976
XL
1313
1314 // Prepare the overlay
1315 let overlay = tmp.join("rls-overlay");
1316 drop(fs::remove_dir_all(&overlay));
1317 t!(fs::create_dir_all(&overlay));
83c7162d
XL
1318 builder.install(&src.join("README.md"), &overlay, 0o644);
1319 builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
1320 builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
1321 builder.create(&overlay.join("version"), &version);
3b2f2976
XL
1322
1323 // Generate the installer tarball
1324 let mut cmd = rust_installer(builder);
1325 cmd.arg("generate")
dfeec247
XL
1326 .arg("--product-name=Rust")
1327 .arg("--rel-manifest-dir=rustlib")
1328 .arg("--success-message=RLS-ready-to-serve.")
1329 .arg("--image-dir")
1330 .arg(&image)
1331 .arg("--work-dir")
1332 .arg(&tmpdir(builder))
1333 .arg("--output-dir")
1334 .arg(&distdir(builder))
1335 .arg("--non-installed-overlay")
1336 .arg(&overlay)
3dfed10e 1337 .arg(format!("--package-name={}-{}", name, target.triple))
dfeec247
XL
1338 .arg("--legacy-manifest-dirs=rustlib,cargo")
1339 .arg("--component-name=rls-preview");
3b2f2976 1340
3dfed10e 1341 builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target.triple));
e1599b0c 1342 let _time = timeit(builder);
83c7162d 1343 builder.run(&mut cmd);
3dfed10e 1344 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
abe05a73
XL
1345 }
1346}
1347
f035d41b
XL
1348#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1349pub struct RustAnalyzer {
1350 pub compiler: Compiler,
3dfed10e 1351 pub target: TargetSelection,
f035d41b
XL
1352}
1353
1354impl Step for RustAnalyzer {
3dfed10e 1355 type Output = Option<PathBuf>;
f035d41b
XL
1356 const ONLY_HOSTS: bool = true;
1357
1358 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
1359 run.path("rust-analyzer")
1360 }
1361
1362 fn make_run(run: RunConfig<'_>) {
1363 run.builder.ensure(RustAnalyzer {
1364 compiler: run.builder.compiler_for(
1365 run.builder.top_stage,
1366 run.builder.config.build,
1367 run.target,
1368 ),
1369 target: run.target,
1370 });
1371 }
1372
3dfed10e 1373 fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
f035d41b
XL
1374 let compiler = self.compiler;
1375 let target = self.target;
1376 assert!(builder.config.extended);
1377
3dfed10e
XL
1378 if target.contains("riscv64") {
1379 // riscv64 currently has an LLVM bug that makes rust-analyzer unable
1380 // to build. See #74813 for details.
1381 return None;
1382 }
1383
f035d41b
XL
1384 let src = builder.src.join("src/tools/rust-analyzer");
1385 let release_num = builder.release_num("rust-analyzer/crates/rust-analyzer");
1386 let name = pkgname(builder, "rust-analyzer");
1387 let version = builder.rust_analyzer_info.version(builder, &release_num);
1388
1389 let tmp = tmpdir(builder);
1390 let image = tmp.join("rust-analyzer-image");
1391 drop(fs::remove_dir_all(&image));
1392 builder.create_dir(&image);
1393
1394 // Prepare the image directory
1395 // We expect rust-analyer to always build, as it doesn't depend on rustc internals
1396 // and doesn't have associated toolstate.
1397 let rust_analyzer = builder
1398 .ensure(tool::RustAnalyzer { compiler, target, extra_features: Vec::new() })
1399 .expect("rust-analyzer always builds");
1400
1401 builder.install(&rust_analyzer, &image.join("bin"), 0o755);
1402 let doc = image.join("share/doc/rust-analyzer");
1403 builder.install(&src.join("README.md"), &doc, 0o644);
1404 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1405 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1406
1407 // Prepare the overlay
1408 let overlay = tmp.join("rust-analyzer-overlay");
1409 drop(fs::remove_dir_all(&overlay));
1410 t!(fs::create_dir_all(&overlay));
1411 builder.install(&src.join("README.md"), &overlay, 0o644);
1412 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1413 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1414 builder.create(&overlay.join("version"), &version);
1415
1416 // Generate the installer tarball
1417 let mut cmd = rust_installer(builder);
1418 cmd.arg("generate")
1419 .arg("--product-name=Rust")
1420 .arg("--rel-manifest-dir=rustlib")
1421 .arg("--success-message=rust-analyzer-ready-to-serve.")
1422 .arg("--image-dir")
1423 .arg(&image)
1424 .arg("--work-dir")
1425 .arg(&tmpdir(builder))
1426 .arg("--output-dir")
1427 .arg(&distdir(builder))
1428 .arg("--non-installed-overlay")
1429 .arg(&overlay)
3dfed10e 1430 .arg(format!("--package-name={}-{}", name, target.triple))
f035d41b
XL
1431 .arg("--legacy-manifest-dirs=rustlib,cargo")
1432 .arg("--component-name=rust-analyzer-preview");
1433
1434 builder.info(&format!("Dist rust-analyzer stage{} ({})", compiler.stage, target));
1435 let _time = timeit(builder);
1436 builder.run(&mut cmd);
3dfed10e 1437 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
f035d41b
XL
1438 }
1439}
1440
8faf50e0
XL
1441#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1442pub struct Clippy {
dc9dc135 1443 pub compiler: Compiler,
3dfed10e 1444 pub target: TargetSelection,
8faf50e0
XL
1445}
1446
1447impl Step for Clippy {
f9f354fc 1448 type Output = PathBuf;
8faf50e0
XL
1449 const ONLY_HOSTS: bool = true;
1450
9fa01778 1451 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
8faf50e0
XL
1452 run.path("clippy")
1453 }
1454
9fa01778 1455 fn make_run(run: RunConfig<'_>) {
8faf50e0 1456 run.builder.ensure(Clippy {
dc9dc135
XL
1457 compiler: run.builder.compiler_for(
1458 run.builder.top_stage,
1459 run.builder.config.build,
1460 run.target,
1461 ),
8faf50e0
XL
1462 target: run.target,
1463 });
1464 }
1465
f9f354fc 1466 fn run(self, builder: &Builder<'_>) -> PathBuf {
dc9dc135 1467 let compiler = self.compiler;
8faf50e0
XL
1468 let target = self.target;
1469 assert!(builder.config.extended);
1470
8faf50e0
XL
1471 let src = builder.src.join("src/tools/clippy");
1472 let release_num = builder.release_num("clippy");
1473 let name = pkgname(builder, "clippy");
1474 let version = builder.clippy_info.version(builder, &release_num);
1475
1476 let tmp = tmpdir(builder);
1477 let image = tmp.join("clippy-image");
1478 drop(fs::remove_dir_all(&image));
1479 builder.create_dir(&image);
1480
1481 // Prepare the image directory
1482 // We expect clippy to build, because we've exited this step above if tool
1483 // state for clippy isn't testing.
dfeec247
XL
1484 let clippy = builder
1485 .ensure(tool::Clippy { compiler, target, extra_features: Vec::new() })
f9f354fc 1486 .expect("clippy expected to build - essential tool");
dfeec247
XL
1487 let cargoclippy = builder
1488 .ensure(tool::CargoClippy { compiler, target, extra_features: Vec::new() })
f9f354fc 1489 .expect("clippy expected to build - essential tool");
8faf50e0
XL
1490
1491 builder.install(&clippy, &image.join("bin"), 0o755);
1492 builder.install(&cargoclippy, &image.join("bin"), 0o755);
1493 let doc = image.join("share/doc/clippy");
1494 builder.install(&src.join("README.md"), &doc, 0o644);
0bf4aa26
XL
1495 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1496 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
8faf50e0
XL
1497
1498 // Prepare the overlay
1499 let overlay = tmp.join("clippy-overlay");
1500 drop(fs::remove_dir_all(&overlay));
1501 t!(fs::create_dir_all(&overlay));
1502 builder.install(&src.join("README.md"), &overlay, 0o644);
0bf4aa26
XL
1503 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1504 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
8faf50e0
XL
1505 builder.create(&overlay.join("version"), &version);
1506
1507 // Generate the installer tarball
1508 let mut cmd = rust_installer(builder);
1509 cmd.arg("generate")
dfeec247
XL
1510 .arg("--product-name=Rust")
1511 .arg("--rel-manifest-dir=rustlib")
1512 .arg("--success-message=clippy-ready-to-serve.")
1513 .arg("--image-dir")
1514 .arg(&image)
1515 .arg("--work-dir")
1516 .arg(&tmpdir(builder))
1517 .arg("--output-dir")
1518 .arg(&distdir(builder))
1519 .arg("--non-installed-overlay")
1520 .arg(&overlay)
3dfed10e 1521 .arg(format!("--package-name={}-{}", name, target.triple))
dfeec247
XL
1522 .arg("--legacy-manifest-dirs=rustlib,cargo")
1523 .arg("--component-name=clippy-preview");
8faf50e0 1524
e1599b0c
XL
1525 builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target));
1526 let _time = timeit(builder);
8faf50e0 1527 builder.run(&mut cmd);
3dfed10e 1528 distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple))
8faf50e0
XL
1529 }
1530}
abe05a73 1531
0731742a
XL
1532#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1533pub struct Miri {
dc9dc135 1534 pub compiler: Compiler,
3dfed10e 1535 pub target: TargetSelection,
0731742a
XL
1536}
1537
1538impl Step for Miri {
1539 type Output = Option<PathBuf>;
1540 const ONLY_HOSTS: bool = true;
1541
9fa01778 1542 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
0731742a
XL
1543 run.path("miri")
1544 }
1545
9fa01778 1546 fn make_run(run: RunConfig<'_>) {
0731742a 1547 run.builder.ensure(Miri {
dc9dc135
XL
1548 compiler: run.builder.compiler_for(
1549 run.builder.top_stage,
1550 run.builder.config.build,
1551 run.target,
1552 ),
0731742a
XL
1553 target: run.target,
1554 });
1555 }
1556
9fa01778 1557 fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
dc9dc135 1558 let compiler = self.compiler;
0731742a
XL
1559 let target = self.target;
1560 assert!(builder.config.extended);
1561
0731742a
XL
1562 let src = builder.src.join("src/tools/miri");
1563 let release_num = builder.release_num("miri");
1564 let name = pkgname(builder, "miri");
1565 let version = builder.miri_info.version(builder, &release_num);
1566
1567 let tmp = tmpdir(builder);
1568 let image = tmp.join("miri-image");
1569 drop(fs::remove_dir_all(&image));
1570 builder.create_dir(&image);
1571
1572 // Prepare the image directory
f9f354fc
XL
1573 // We expect miri to build, because we've exited this step above if tool
1574 // state for miri isn't testing.
dfeec247
XL
1575 let miri = builder
1576 .ensure(tool::Miri { compiler, target, extra_features: Vec::new() })
1577 .or_else(|| {
f9f354fc 1578 missing_tool("miri", builder.build.config.missing_tools);
dfeec247
XL
1579 None
1580 })?;
1581 let cargomiri = builder
1582 .ensure(tool::CargoMiri { compiler, target, extra_features: Vec::new() })
1583 .or_else(|| {
f9f354fc 1584 missing_tool("cargo miri", builder.build.config.missing_tools);
dfeec247
XL
1585 None
1586 })?;
0731742a
XL
1587
1588 builder.install(&miri, &image.join("bin"), 0o755);
1589 builder.install(&cargomiri, &image.join("bin"), 0o755);
1590 let doc = image.join("share/doc/miri");
1591 builder.install(&src.join("README.md"), &doc, 0o644);
1592 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1593 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1594
1595 // Prepare the overlay
1596 let overlay = tmp.join("miri-overlay");
1597 drop(fs::remove_dir_all(&overlay));
1598 t!(fs::create_dir_all(&overlay));
1599 builder.install(&src.join("README.md"), &overlay, 0o644);
1600 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1601 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1602 builder.create(&overlay.join("version"), &version);
1603
1604 // Generate the installer tarball
1605 let mut cmd = rust_installer(builder);
1606 cmd.arg("generate")
dfeec247
XL
1607 .arg("--product-name=Rust")
1608 .arg("--rel-manifest-dir=rustlib")
1609 .arg("--success-message=miri-ready-to-serve.")
1610 .arg("--image-dir")
1611 .arg(&image)
1612 .arg("--work-dir")
1613 .arg(&tmpdir(builder))
1614 .arg("--output-dir")
1615 .arg(&distdir(builder))
1616 .arg("--non-installed-overlay")
1617 .arg(&overlay)
3dfed10e 1618 .arg(format!("--package-name={}-{}", name, target.triple))
dfeec247
XL
1619 .arg("--legacy-manifest-dirs=rustlib,cargo")
1620 .arg("--component-name=miri-preview");
0731742a 1621
e1599b0c
XL
1622 builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target));
1623 let _time = timeit(builder);
0731742a 1624 builder.run(&mut cmd);
3dfed10e 1625 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
0731742a
XL
1626 }
1627}
1628
83c7162d 1629#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
abe05a73 1630pub struct Rustfmt {
dc9dc135 1631 pub compiler: Compiler,
3dfed10e 1632 pub target: TargetSelection,
abe05a73
XL
1633}
1634
1635impl Step for Rustfmt {
1636 type Output = Option<PathBuf>;
abe05a73
XL
1637 const ONLY_HOSTS: bool = true;
1638
9fa01778 1639 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
abe05a73
XL
1640 run.path("rustfmt")
1641 }
1642
9fa01778 1643 fn make_run(run: RunConfig<'_>) {
abe05a73 1644 run.builder.ensure(Rustfmt {
dc9dc135
XL
1645 compiler: run.builder.compiler_for(
1646 run.builder.top_stage,
1647 run.builder.config.build,
1648 run.target,
1649 ),
abe05a73
XL
1650 target: run.target,
1651 });
1652 }
1653
9fa01778 1654 fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
dc9dc135 1655 let compiler = self.compiler;
abe05a73 1656 let target = self.target;
abe05a73 1657
83c7162d
XL
1658 let src = builder.src.join("src/tools/rustfmt");
1659 let release_num = builder.release_num("rustfmt");
1660 let name = pkgname(builder, "rustfmt");
1661 let version = builder.rustfmt_info.version(builder, &release_num);
abe05a73 1662
83c7162d 1663 let tmp = tmpdir(builder);
abe05a73
XL
1664 let image = tmp.join("rustfmt-image");
1665 drop(fs::remove_dir_all(&image));
83c7162d 1666 builder.create_dir(&image);
abe05a73
XL
1667
1668 // Prepare the image directory
dfeec247
XL
1669 let rustfmt = builder
1670 .ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() })
1671 .or_else(|| {
1672 missing_tool("Rustfmt", builder.build.config.missing_tools);
1673 None
1674 })?;
1675 let cargofmt = builder
1676 .ensure(tool::Cargofmt { compiler, target, extra_features: Vec::new() })
1677 .or_else(|| {
1678 missing_tool("Cargofmt", builder.build.config.missing_tools);
1679 None
1680 })?;
ff7c6d11 1681
83c7162d
XL
1682 builder.install(&rustfmt, &image.join("bin"), 0o755);
1683 builder.install(&cargofmt, &image.join("bin"), 0o755);
abe05a73 1684 let doc = image.join("share/doc/rustfmt");
83c7162d
XL
1685 builder.install(&src.join("README.md"), &doc, 0o644);
1686 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1687 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
abe05a73
XL
1688
1689 // Prepare the overlay
1690 let overlay = tmp.join("rustfmt-overlay");
1691 drop(fs::remove_dir_all(&overlay));
83c7162d
XL
1692 builder.create_dir(&overlay);
1693 builder.install(&src.join("README.md"), &overlay, 0o644);
1694 builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
1695 builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
1696 builder.create(&overlay.join("version"), &version);
abe05a73
XL
1697
1698 // Generate the installer tarball
1699 let mut cmd = rust_installer(builder);
1700 cmd.arg("generate")
dfeec247
XL
1701 .arg("--product-name=Rust")
1702 .arg("--rel-manifest-dir=rustlib")
1703 .arg("--success-message=rustfmt-ready-to-fmt.")
1704 .arg("--image-dir")
1705 .arg(&image)
1706 .arg("--work-dir")
1707 .arg(&tmpdir(builder))
1708 .arg("--output-dir")
1709 .arg(&distdir(builder))
1710 .arg("--non-installed-overlay")
1711 .arg(&overlay)
3dfed10e 1712 .arg(format!("--package-name={}-{}", name, target.triple))
dfeec247
XL
1713 .arg("--legacy-manifest-dirs=rustlib,cargo")
1714 .arg("--component-name=rustfmt-preview");
abe05a73 1715
e1599b0c
XL
1716 builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target));
1717 let _time = timeit(builder);
83c7162d 1718 builder.run(&mut cmd);
3dfed10e 1719 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
32a655c1 1720 }
3b2f2976 1721}
32a655c1 1722
83c7162d 1723#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976
XL
1724pub struct Extended {
1725 stage: u32,
3dfed10e
XL
1726 host: TargetSelection,
1727 target: TargetSelection,
3b2f2976
XL
1728}
1729
1730impl Step for Extended {
1731 type Output = ();
1732 const DEFAULT: bool = true;
3b2f2976
XL
1733 const ONLY_HOSTS: bool = true;
1734
9fa01778 1735 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
1736 let builder = run.builder;
1737 run.path("extended").default_condition(builder.config.extended)
1738 }
32a655c1 1739
9fa01778 1740 fn make_run(run: RunConfig<'_>) {
3b2f2976
XL
1741 run.builder.ensure(Extended {
1742 stage: run.builder.top_stage,
83c7162d 1743 host: run.builder.config.build,
3b2f2976
XL
1744 target: run.target,
1745 });
1746 }
1747
1748 /// Creates a combined installer for the specified target in the provided stage.
9fa01778 1749 fn run(self, builder: &Builder<'_>) {
3b2f2976 1750 let target = self.target;
dc9dc135
XL
1751 let stage = self.stage;
1752 let compiler = builder.compiler_for(self.stage, self.host, self.target);
3b2f2976 1753
dc9dc135 1754 builder.info(&format!("Dist extended stage{} ({})", compiler.stage, target));
3b2f2976 1755
dfeec247 1756 let rustc_installer = builder.ensure(Rustc { compiler: builder.compiler(stage, target) });
dc9dc135
XL
1757 let cargo_installer = builder.ensure(Cargo { compiler, target });
1758 let rustfmt_installer = builder.ensure(Rustfmt { compiler, target });
1759 let rls_installer = builder.ensure(Rls { compiler, target });
f035d41b 1760 let rust_analyzer_installer = builder.ensure(RustAnalyzer { compiler, target });
dc9dc135
XL
1761 let llvm_tools_installer = builder.ensure(LlvmTools { target });
1762 let clippy_installer = builder.ensure(Clippy { compiler, target });
1763 let miri_installer = builder.ensure(Miri { compiler, target });
3b2f2976 1764 let mingw_installer = builder.ensure(Mingw { host: target });
dc9dc135 1765 let analysis_installer = builder.ensure(Analysis { compiler, target });
3b2f2976 1766
dfeec247
XL
1767 let docs_installer = builder.ensure(Docs { host: target });
1768 let std_installer =
1769 builder.ensure(Std { compiler: builder.compiler(stage, target), target });
3b2f2976 1770
83c7162d 1771 let tmp = tmpdir(builder);
3b2f2976 1772 let overlay = tmp.join("extended-overlay");
83c7162d 1773 let etc = builder.src.join("src/etc/installer");
3b2f2976
XL
1774 let work = tmp.join("work");
1775
1776 let _ = fs::remove_dir_all(&overlay);
83c7162d
XL
1777 builder.install(&builder.src.join("COPYRIGHT"), &overlay, 0o644);
1778 builder.install(&builder.src.join("LICENSE-APACHE"), &overlay, 0o644);
1779 builder.install(&builder.src.join("LICENSE-MIT"), &overlay, 0o644);
1780 let version = builder.rust_version();
1781 builder.create(&overlay.join("version"), &version);
1782 if let Some(sha) = builder.rust_sha() {
1783 builder.create(&overlay.join("git-commit-hash"), &sha);
ea8adc8c 1784 }
83c7162d 1785 builder.install(&etc.join("README.md"), &overlay, 0o644);
3b2f2976
XL
1786
1787 // When rust-std package split from rustc, we needed to ensure that during
1788 // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering
1789 // the std files during uninstall. To do this ensure that rustc comes
1790 // before rust-std in the list below.
abe05a73
XL
1791 let mut tarballs = Vec::new();
1792 tarballs.push(rustc_installer);
1793 tarballs.push(cargo_installer);
1794 tarballs.extend(rls_installer.clone());
3dfed10e 1795 tarballs.extend(rust_analyzer_installer.clone());
f9f354fc 1796 tarballs.push(clippy_installer);
0731742a 1797 tarballs.extend(miri_installer.clone());
abe05a73 1798 tarballs.extend(rustfmt_installer.clone());
0bf4aa26 1799 tarballs.extend(llvm_tools_installer);
abe05a73
XL
1800 tarballs.push(analysis_installer);
1801 tarballs.push(std_installer);
83c7162d 1802 if builder.config.docs {
ea8adc8c
XL
1803 tarballs.push(docs_installer);
1804 }
3b2f2976
XL
1805 if target.contains("pc-windows-gnu") {
1806 tarballs.push(mingw_installer.unwrap());
1807 }
1808 let mut input_tarballs = tarballs[0].as_os_str().to_owned();
1809 for tarball in &tarballs[1..] {
1810 input_tarballs.push(",");
1811 input_tarballs.push(tarball);
32a655c1 1812 }
3b2f2976 1813
e1599b0c 1814 builder.info("building combined installer");
3b2f2976
XL
1815 let mut cmd = rust_installer(builder);
1816 cmd.arg("combine")
1817 .arg("--product-name=Rust")
1818 .arg("--rel-manifest-dir=rustlib")
1819 .arg("--success-message=Rust-is-ready-to-roll.")
dfeec247
XL
1820 .arg("--work-dir")
1821 .arg(&work)
1822 .arg("--output-dir")
1823 .arg(&distdir(builder))
3dfed10e 1824 .arg(format!("--package-name={}-{}", pkgname(builder, "rust"), target.triple))
3b2f2976 1825 .arg("--legacy-manifest-dirs=rustlib,cargo")
dfeec247
XL
1826 .arg("--input-tarballs")
1827 .arg(input_tarballs)
1828 .arg("--non-installed-overlay")
1829 .arg(&overlay);
e1599b0c 1830 let time = timeit(&builder);
83c7162d 1831 builder.run(&mut cmd);
e1599b0c 1832 drop(time);
32a655c1 1833
3b2f2976 1834 let mut license = String::new();
83c7162d
XL
1835 license += &builder.read(&builder.src.join("COPYRIGHT"));
1836 license += &builder.read(&builder.src.join("LICENSE-APACHE"));
1837 license += &builder.read(&builder.src.join("LICENSE-MIT"));
3b2f2976 1838 license.push_str("\n");
3b2f2976 1839 license.push_str("\n");
3b2f2976
XL
1840
1841 let rtf = r"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Arial;}}\nowwrap\fs18";
1842 let mut rtf = rtf.to_string();
1843 rtf.push_str("\n");
1844 for line in license.lines() {
1845 rtf.push_str(line);
1846 rtf.push_str("\\line ");
1847 }
1848 rtf.push_str("}");
1849
abe05a73
XL
1850 fn filter(contents: &str, marker: &str) -> String {
1851 let start = format!("tool-{}-start", marker);
1852 let end = format!("tool-{}-end", marker);
1853 let mut lines = Vec::new();
1854 let mut omitted = false;
1855 for line in contents.lines() {
1856 if line.contains(&start) {
1857 omitted = true;
1858 } else if line.contains(&end) {
1859 omitted = false;
1860 } else if !omitted {
1861 lines.push(line);
1862 }
1863 }
1864
1865 lines.join("\n")
1866 }
1867
1868 let xform = |p: &Path| {
0731742a 1869 let mut contents = t!(fs::read_to_string(p));
abe05a73
XL
1870 if rls_installer.is_none() {
1871 contents = filter(&contents, "rls");
1872 }
3dfed10e
XL
1873 if rust_analyzer_installer.is_none() {
1874 contents = filter(&contents, "rust-analyzer");
1875 }
0731742a
XL
1876 if miri_installer.is_none() {
1877 contents = filter(&contents, "miri");
1878 }
abe05a73
XL
1879 if rustfmt_installer.is_none() {
1880 contents = filter(&contents, "rustfmt");
1881 }
1882 let ret = tmp.join(p.file_name().unwrap());
0731742a
XL
1883 t!(fs::write(&ret, &contents));
1884 ret
abe05a73
XL
1885 };
1886
3b2f2976 1887 if target.contains("apple-darwin") {
e1599b0c 1888 builder.info("building pkg installer");
3b2f2976
XL
1889 let pkg = tmp.join("pkg");
1890 let _ = fs::remove_dir_all(&pkg);
3b2f2976
XL
1891
1892 let pkgbuild = |component: &str| {
1893 let mut cmd = Command::new("pkgbuild");
dfeec247
XL
1894 cmd.arg("--identifier")
1895 .arg(format!("org.rust-lang.{}", component))
1896 .arg("--scripts")
1897 .arg(pkg.join(component))
3b2f2976
XL
1898 .arg("--nopayload")
1899 .arg(pkg.join(component).with_extension("pkg"));
83c7162d 1900 builder.run(&mut cmd);
3b2f2976 1901 };
abe05a73
XL
1902
1903 let prepare = |name: &str| {
83c7162d 1904 builder.create_dir(&pkg.join(name));
dfeec247 1905 builder.cp_r(
3dfed10e 1906 &work.join(&format!("{}-{}", pkgname(builder, name), target.triple)),
dfeec247
XL
1907 &pkg.join(name),
1908 );
83c7162d 1909 builder.install(&etc.join("pkg/postinstall"), &pkg.join(name), 0o755);
abe05a73
XL
1910 pkgbuild(name);
1911 };
1912 prepare("rustc");
1913 prepare("cargo");
1914 prepare("rust-docs");
1915 prepare("rust-std");
1916 prepare("rust-analysis");
f9f354fc 1917 prepare("clippy");
abe05a73
XL
1918
1919 if rls_installer.is_some() {
1920 prepare("rls");
1921 }
3dfed10e
XL
1922 if rust_analyzer_installer.is_some() {
1923 prepare("rust-analyzer");
1924 }
0731742a
XL
1925 if miri_installer.is_some() {
1926 prepare("miri");
1927 }
3b2f2976
XL
1928
1929 // create an 'uninstall' package
83c7162d 1930 builder.install(&etc.join("pkg/postinstall"), &pkg.join("uninstall"), 0o755);
3b2f2976
XL
1931 pkgbuild("uninstall");
1932
83c7162d
XL
1933 builder.create_dir(&pkg.join("res"));
1934 builder.create(&pkg.join("res/LICENSE.txt"), &license);
1935 builder.install(&etc.join("gfx/rust-logo.png"), &pkg.join("res"), 0o644);
3b2f2976 1936 let mut cmd = Command::new("productbuild");
dfeec247
XL
1937 cmd.arg("--distribution")
1938 .arg(xform(&etc.join("pkg/Distribution.xml")))
1939 .arg("--resources")
1940 .arg(pkg.join("res"))
3dfed10e
XL
1941 .arg(distdir(builder).join(format!(
1942 "{}-{}.pkg",
1943 pkgname(builder, "rust"),
1944 target.triple
1945 )))
dfeec247
XL
1946 .arg("--package-path")
1947 .arg(&pkg);
e1599b0c 1948 let _time = timeit(builder);
83c7162d 1949 builder.run(&mut cmd);
3b2f2976
XL
1950 }
1951
1952 if target.contains("windows") {
1953 let exe = tmp.join("exe");
1954 let _ = fs::remove_dir_all(&exe);
3b2f2976 1955
abe05a73 1956 let prepare = |name: &str| {
83c7162d 1957 builder.create_dir(&exe.join(name));
abe05a73 1958 let dir = if name == "rust-std" || name == "rust-analysis" {
3dfed10e 1959 format!("{}-{}", name, target.triple)
abe05a73
XL
1960 } else if name == "rls" {
1961 "rls-preview".to_string()
f035d41b
XL
1962 } else if name == "rust-analyzer" {
1963 "rust-analyzer-preview".to_string()
8faf50e0
XL
1964 } else if name == "clippy" {
1965 "clippy-preview".to_string()
0731742a
XL
1966 } else if name == "miri" {
1967 "miri-preview".to_string()
abe05a73
XL
1968 } else {
1969 name.to_string()
1970 };
dfeec247 1971 builder.cp_r(
3dfed10e 1972 &work.join(&format!("{}-{}", pkgname(builder, name), target.triple)).join(dir),
dfeec247
XL
1973 &exe.join(name),
1974 );
83c7162d 1975 builder.remove(&exe.join(name).join("manifest.in"));
abe05a73
XL
1976 };
1977 prepare("rustc");
1978 prepare("cargo");
1979 prepare("rust-analysis");
1980 prepare("rust-docs");
1981 prepare("rust-std");
f9f354fc 1982 prepare("clippy");
abe05a73
XL
1983 if rls_installer.is_some() {
1984 prepare("rls");
1985 }
3dfed10e
XL
1986 if rust_analyzer_installer.is_some() {
1987 prepare("rust-analyzer");
1988 }
0731742a
XL
1989 if miri_installer.is_some() {
1990 prepare("miri");
1991 }
3b2f2976 1992 if target.contains("windows-gnu") {
abe05a73 1993 prepare("rust-mingw");
3b2f2976
XL
1994 }
1995
83c7162d 1996 builder.install(&etc.join("gfx/rust-logo.ico"), &exe, 0o644);
3b2f2976
XL
1997
1998 // Generate msi installer
1999 let wix = PathBuf::from(env::var_os("WIX").unwrap());
2000 let heat = wix.join("bin/heat.exe");
2001 let candle = wix.join("bin/candle.exe");
2002 let light = wix.join("bin/light.exe");
2003
2004 let heat_flags = ["-nologo", "-gg", "-sfrag", "-srd", "-sreg"];
dfeec247
XL
2005 builder.run(
2006 Command::new(&heat)
2007 .current_dir(&exe)
2008 .arg("dir")
2009 .arg("rustc")
2010 .args(&heat_flags)
2011 .arg("-cg")
2012 .arg("RustcGroup")
2013 .arg("-dr")
2014 .arg("Rustc")
2015 .arg("-var")
2016 .arg("var.RustcDir")
2017 .arg("-out")
2018 .arg(exe.join("RustcGroup.wxs")),
2019 );
2020 builder.run(
2021 Command::new(&heat)
2022 .current_dir(&exe)
2023 .arg("dir")
2024 .arg("rust-docs")
2025 .args(&heat_flags)
2026 .arg("-cg")
2027 .arg("DocsGroup")
2028 .arg("-dr")
2029 .arg("Docs")
2030 .arg("-var")
2031 .arg("var.DocsDir")
2032 .arg("-out")
2033 .arg(exe.join("DocsGroup.wxs"))
2034 .arg("-t")
2035 .arg(etc.join("msi/squash-components.xsl")),
2036 );
2037 builder.run(
2038 Command::new(&heat)
2039 .current_dir(&exe)
2040 .arg("dir")
2041 .arg("cargo")
2042 .args(&heat_flags)
2043 .arg("-cg")
2044 .arg("CargoGroup")
2045 .arg("-dr")
2046 .arg("Cargo")
2047 .arg("-var")
2048 .arg("var.CargoDir")
2049 .arg("-out")
2050 .arg(exe.join("CargoGroup.wxs"))
2051 .arg("-t")
2052 .arg(etc.join("msi/remove-duplicates.xsl")),
2053 );
2054 builder.run(
2055 Command::new(&heat)
2056 .current_dir(&exe)
2057 .arg("dir")
2058 .arg("rust-std")
2059 .args(&heat_flags)
2060 .arg("-cg")
2061 .arg("StdGroup")
2062 .arg("-dr")
2063 .arg("Std")
2064 .arg("-var")
2065 .arg("var.StdDir")
2066 .arg("-out")
2067 .arg(exe.join("StdGroup.wxs")),
2068 );
abe05a73 2069 if rls_installer.is_some() {
dfeec247
XL
2070 builder.run(
2071 Command::new(&heat)
2072 .current_dir(&exe)
2073 .arg("dir")
2074 .arg("rls")
2075 .args(&heat_flags)
2076 .arg("-cg")
2077 .arg("RlsGroup")
2078 .arg("-dr")
2079 .arg("Rls")
2080 .arg("-var")
2081 .arg("var.RlsDir")
2082 .arg("-out")
2083 .arg(exe.join("RlsGroup.wxs"))
2084 .arg("-t")
2085 .arg(etc.join("msi/remove-duplicates.xsl")),
2086 );
abe05a73 2087 }
3dfed10e
XL
2088 if rust_analyzer_installer.is_some() {
2089 builder.run(
2090 Command::new(&heat)
2091 .current_dir(&exe)
2092 .arg("dir")
2093 .arg("rust-analyzer")
2094 .args(&heat_flags)
2095 .arg("-cg")
2096 .arg("RustAnalyzerGroup")
2097 .arg("-dr")
2098 .arg("RustAnalyzer")
2099 .arg("-var")
2100 .arg("var.RustAnalyzerDir")
2101 .arg("-out")
2102 .arg(exe.join("RustAnalyzerGroup.wxs"))
2103 .arg("-t")
2104 .arg(etc.join("msi/remove-duplicates.xsl")),
2105 );
2106 }
f9f354fc
XL
2107 builder.run(
2108 Command::new(&heat)
2109 .current_dir(&exe)
2110 .arg("dir")
2111 .arg("clippy")
2112 .args(&heat_flags)
2113 .arg("-cg")
2114 .arg("ClippyGroup")
2115 .arg("-dr")
2116 .arg("Clippy")
2117 .arg("-var")
2118 .arg("var.ClippyDir")
2119 .arg("-out")
2120 .arg(exe.join("ClippyGroup.wxs"))
2121 .arg("-t")
2122 .arg(etc.join("msi/remove-duplicates.xsl")),
2123 );
0731742a 2124 if miri_installer.is_some() {
dfeec247
XL
2125 builder.run(
2126 Command::new(&heat)
2127 .current_dir(&exe)
2128 .arg("dir")
2129 .arg("miri")
2130 .args(&heat_flags)
2131 .arg("-cg")
2132 .arg("MiriGroup")
2133 .arg("-dr")
2134 .arg("Miri")
2135 .arg("-var")
2136 .arg("var.MiriDir")
2137 .arg("-out")
2138 .arg(exe.join("MiriGroup.wxs"))
2139 .arg("-t")
2140 .arg(etc.join("msi/remove-duplicates.xsl")),
2141 );
0731742a 2142 }
dfeec247
XL
2143 builder.run(
2144 Command::new(&heat)
2145 .current_dir(&exe)
2146 .arg("dir")
2147 .arg("rust-analysis")
2148 .args(&heat_flags)
2149 .arg("-cg")
2150 .arg("AnalysisGroup")
2151 .arg("-dr")
2152 .arg("Analysis")
2153 .arg("-var")
2154 .arg("var.AnalysisDir")
2155 .arg("-out")
2156 .arg(exe.join("AnalysisGroup.wxs"))
2157 .arg("-t")
2158 .arg(etc.join("msi/remove-duplicates.xsl")),
2159 );
3b2f2976 2160 if target.contains("windows-gnu") {
dfeec247
XL
2161 builder.run(
2162 Command::new(&heat)
2163 .current_dir(&exe)
2164 .arg("dir")
2165 .arg("rust-mingw")
2166 .args(&heat_flags)
2167 .arg("-cg")
2168 .arg("GccGroup")
2169 .arg("-dr")
2170 .arg("Gcc")
2171 .arg("-var")
2172 .arg("var.GccDir")
2173 .arg("-out")
2174 .arg(exe.join("GccGroup.wxs")),
2175 );
3b2f2976 2176 }
32a655c1 2177
3b2f2976 2178 let candle = |input: &Path| {
dfeec247
XL
2179 let output = exe.join(input.file_stem().unwrap()).with_extension("wixobj");
2180 let arch = if target.contains("x86_64") { "x64" } else { "x86" };
3b2f2976
XL
2181 let mut cmd = Command::new(&candle);
2182 cmd.current_dir(&exe)
2183 .arg("-nologo")
2184 .arg("-dRustcDir=rustc")
2185 .arg("-dDocsDir=rust-docs")
2186 .arg("-dCargoDir=cargo")
2187 .arg("-dStdDir=rust-std")
3b2f2976 2188 .arg("-dAnalysisDir=rust-analysis")
f9f354fc 2189 .arg("-dClippyDir=clippy")
dfeec247
XL
2190 .arg("-arch")
2191 .arg(&arch)
2192 .arg("-out")
2193 .arg(&output)
3b2f2976 2194 .arg(&input);
83c7162d 2195 add_env(builder, &mut cmd, target);
3b2f2976 2196
abe05a73
XL
2197 if rls_installer.is_some() {
2198 cmd.arg("-dRlsDir=rls");
2199 }
3dfed10e
XL
2200 if rust_analyzer_installer.is_some() {
2201 cmd.arg("-dRustAnalyzerDir=rust-analyzer");
2202 }
0731742a
XL
2203 if miri_installer.is_some() {
2204 cmd.arg("-dMiriDir=miri");
2205 }
3b2f2976
XL
2206 if target.contains("windows-gnu") {
2207 cmd.arg("-dGccDir=rust-mingw");
2208 }
83c7162d 2209 builder.run(&mut cmd);
3b2f2976 2210 };
abe05a73 2211 candle(&xform(&etc.join("msi/rust.wxs")));
3b2f2976
XL
2212 candle(&etc.join("msi/ui.wxs"));
2213 candle(&etc.join("msi/rustwelcomedlg.wxs"));
2214 candle("RustcGroup.wxs".as_ref());
2215 candle("DocsGroup.wxs".as_ref());
2216 candle("CargoGroup.wxs".as_ref());
2217 candle("StdGroup.wxs".as_ref());
f9f354fc 2218 candle("ClippyGroup.wxs".as_ref());
abe05a73
XL
2219 if rls_installer.is_some() {
2220 candle("RlsGroup.wxs".as_ref());
2221 }
3dfed10e
XL
2222 if rust_analyzer_installer.is_some() {
2223 candle("RustAnalyzerGroup.wxs".as_ref());
2224 }
0731742a
XL
2225 if miri_installer.is_some() {
2226 candle("MiriGroup.wxs".as_ref());
2227 }
3b2f2976 2228 candle("AnalysisGroup.wxs".as_ref());
32a655c1
SL
2229
2230 if target.contains("windows-gnu") {
3b2f2976 2231 candle("GccGroup.wxs".as_ref());
32a655c1 2232 }
32a655c1 2233
83c7162d
XL
2234 builder.create(&exe.join("LICENSE.rtf"), &rtf);
2235 builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644);
2236 builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644);
3b2f2976 2237
e1599b0c 2238 builder.info(&format!("building `msi` installer with {:?}", light));
3dfed10e 2239 let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target.triple);
3b2f2976
XL
2240 let mut cmd = Command::new(&light);
2241 cmd.arg("-nologo")
dfeec247
XL
2242 .arg("-ext")
2243 .arg("WixUIExtension")
2244 .arg("-ext")
2245 .arg("WixUtilExtension")
2246 .arg("-out")
2247 .arg(exe.join(&filename))
3b2f2976
XL
2248 .arg("rust.wixobj")
2249 .arg("ui.wixobj")
2250 .arg("rustwelcomedlg.wixobj")
2251 .arg("RustcGroup.wixobj")
2252 .arg("DocsGroup.wixobj")
2253 .arg("CargoGroup.wixobj")
2254 .arg("StdGroup.wixobj")
3b2f2976 2255 .arg("AnalysisGroup.wixobj")
f9f354fc 2256 .arg("ClippyGroup.wixobj")
3b2f2976 2257 .current_dir(&exe);
32a655c1 2258
abe05a73
XL
2259 if rls_installer.is_some() {
2260 cmd.arg("RlsGroup.wixobj");
2261 }
3dfed10e
XL
2262 if rust_analyzer_installer.is_some() {
2263 cmd.arg("RustAnalyzerGroup.wixobj");
2264 }
0731742a
XL
2265 if miri_installer.is_some() {
2266 cmd.arg("MiriGroup.wixobj");
2267 }
abe05a73 2268
3b2f2976
XL
2269 if target.contains("windows-gnu") {
2270 cmd.arg("GccGroup.wixobj");
2271 }
2272 // ICE57 wrongly complains about the shortcuts
2273 cmd.arg("-sice:ICE57");
2274
e1599b0c 2275 let _time = timeit(builder);
83c7162d 2276 builder.run(&mut cmd);
32a655c1 2277
83c7162d
XL
2278 if !builder.config.dry_run {
2279 t!(fs::rename(exe.join(&filename), distdir(builder).join(&filename)));
2280 }
3b2f2976 2281 }
32a655c1
SL
2282 }
2283}
2284
3dfed10e 2285fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
1b1a35ee 2286 let mut parts = builder.version.split('.');
83c7162d 2287 cmd.env("CFG_RELEASE_INFO", builder.rust_version())
1b1a35ee 2288 .env("CFG_RELEASE_NUM", &builder.version)
dfeec247
XL
2289 .env("CFG_RELEASE", builder.rust_release())
2290 .env("CFG_VER_MAJOR", parts.next().unwrap())
2291 .env("CFG_VER_MINOR", parts.next().unwrap())
2292 .env("CFG_VER_PATCH", parts.next().unwrap())
2293 .env("CFG_VER_BUILD", "0") // just needed to build
2294 .env("CFG_PACKAGE_VERS", builder.rust_package_vers())
2295 .env("CFG_PACKAGE_NAME", pkgname(builder, "rust"))
3dfed10e 2296 .env("CFG_BUILD", target.triple)
dfeec247 2297 .env("CFG_CHANNEL", &builder.config.channel);
32a655c1
SL
2298
2299 if target.contains("windows-gnu") {
dfeec247 2300 cmd.env("CFG_MINGW", "1").env("CFG_ABI", "GNU");
32a655c1 2301 } else {
dfeec247 2302 cmd.env("CFG_MINGW", "0").env("CFG_ABI", "MSVC");
32a655c1
SL
2303 }
2304
2305 if target.contains("x86_64") {
dfeec247 2306 cmd.env("CFG_PLATFORM", "x64");
32a655c1 2307 } else {
dfeec247 2308 cmd.env("CFG_PLATFORM", "x86");
32a655c1
SL
2309 }
2310}
2311
83c7162d 2312#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
3b2f2976
XL
2313pub struct HashSign;
2314
2315impl Step for HashSign {
2316 type Output = ();
3b2f2976 2317 const ONLY_HOSTS: bool = true;
3b2f2976 2318
9fa01778 2319 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
3b2f2976
XL
2320 run.path("hash-and-sign")
2321 }
2322
9fa01778 2323 fn make_run(run: RunConfig<'_>) {
3b2f2976
XL
2324 run.builder.ensure(HashSign);
2325 }
2326
9fa01778 2327 fn run(self, builder: &Builder<'_>) {
e1599b0c
XL
2328 // This gets called by `promote-release`
2329 // (https://github.com/rust-lang/rust-central-station/tree/master/promote-release).
3b2f2976 2330 let mut cmd = builder.tool_cmd(Tool::BuildManifest);
83c7162d
XL
2331 if builder.config.dry_run {
2332 return;
2333 }
2334 let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| {
3b2f2976
XL
2335 panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
2336 });
83c7162d 2337 let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
3b2f2976
XL
2338 panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
2339 });
e1599b0c
XL
2340 let pass = if env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err() {
2341 let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
2342 panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
2343 });
2344 t!(fs::read_to_string(&file))
2345 } else {
2346 String::new()
2347 };
3b2f2976
XL
2348
2349 let today = output(Command::new("date").arg("+%Y-%m-%d"));
2350
2351 cmd.arg(sign);
83c7162d 2352 cmd.arg(distdir(builder));
3b2f2976 2353 cmd.arg(today.trim());
0731742a 2354 cmd.arg(addr);
1b1a35ee
XL
2355 cmd.arg(&builder.config.channel);
2356 cmd.env("BUILD_MANIFEST_LEGACY", "1");
3b2f2976 2357
83c7162d 2358 builder.create_dir(&distdir(builder));
3b2f2976
XL
2359
2360 let mut child = t!(cmd.stdin(Stdio::piped()).spawn());
2361 t!(child.stdin.take().unwrap().write_all(pass.as_bytes()));
2362 let status = t!(child.wait());
2363 assert!(status.success());
2364 }
32a655c1 2365}
8faf50e0 2366
f9f354fc
XL
2367/// Maybe add libLLVM.so to the given destination lib-dir. It will only have
2368/// been built if LLVM tools are linked dynamically.
2369///
2370/// Note: This function does not yet support Windows, but we also don't support
2371/// linking LLVM tools dynamically on Windows yet.
3dfed10e 2372fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) {
1b1a35ee
XL
2373 if !builder.config.llvm_link_shared {
2374 // We do not need to copy LLVM files into the sysroot if it is not
2375 // dynamically linked; it is already included into librustc_llvm
2376 // statically.
2377 return;
2378 }
b7449926 2379
1b1a35ee
XL
2380 // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib
2381 // instead of libLLVM-11-rust-....dylib, as on linux. It's not entirely
2382 // clear why this is the case, though. llvm-config will emit the versioned
2383 // paths and we don't want those in the sysroot (as we're expecting
2384 // unversioned paths).
b7449926 2385 if target.contains("apple-darwin") {
1b1a35ee 2386 let src_libdir = builder.llvm_out(target).join("lib");
b7449926
XL
2387 let llvm_dylib_path = src_libdir.join("libLLVM.dylib");
2388 if llvm_dylib_path.exists() {
f9f354fc 2389 builder.install(&llvm_dylib_path, dst_libdir, 0o644);
b7449926 2390 }
1b1a35ee
XL
2391 } else if let Ok(llvm_config) = crate::native::prebuilt_llvm_config(builder, target) {
2392 let files = output(Command::new(llvm_config).arg("--libfiles"));
2393 for file in files.lines() {
2394 builder.install(Path::new(file), dst_libdir, 0o644);
2395 }
b7449926
XL
2396 }
2397}
2398
f9f354fc 2399/// Maybe add libLLVM.so to the target lib-dir for linking.
3dfed10e
XL
2400pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) {
2401 let dst_libdir = sysroot.join("lib/rustlib").join(&*target.triple).join("lib");
f9f354fc
XL
2402 maybe_install_llvm(builder, target, &dst_libdir);
2403}
2404
2405/// Maybe add libLLVM.so to the runtime lib-dir for rustc itself.
3dfed10e 2406pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) {
f9f354fc
XL
2407 let dst_libdir =
2408 sysroot.join(builder.sysroot_libdir_relative(Compiler { stage: 1, host: target }));
2409 maybe_install_llvm(builder, target, &dst_libdir);
2410}
2411
8faf50e0
XL
2412#[derive(Clone, Debug, Eq, Hash, PartialEq)]
2413pub struct LlvmTools {
3dfed10e 2414 pub target: TargetSelection,
8faf50e0
XL
2415}
2416
2417impl Step for LlvmTools {
2418 type Output = Option<PathBuf>;
2419 const ONLY_HOSTS: bool = true;
2420
9fa01778 2421 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
8faf50e0
XL
2422 run.path("llvm-tools")
2423 }
2424
9fa01778 2425 fn make_run(run: RunConfig<'_>) {
dfeec247 2426 run.builder.ensure(LlvmTools { target: run.target });
8faf50e0
XL
2427 }
2428
9fa01778 2429 fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
8faf50e0
XL
2430 let target = self.target;
2431 assert!(builder.config.extended);
2432
2433 /* run only if llvm-config isn't used */
2434 if let Some(config) = builder.config.target_config.get(&target) {
2435 if let Some(ref _s) = config.llvm_config {
dfeec247 2436 builder.info(&format!("Skipping LlvmTools ({}): external LLVM", target));
8faf50e0
XL
2437 return None;
2438 }
2439 }
2440
dc9dc135 2441 builder.info(&format!("Dist LlvmTools ({})", target));
e1599b0c 2442 let _time = timeit(builder);
9fa01778 2443 let src = builder.src.join("src/llvm-project/llvm");
8faf50e0
XL
2444 let name = pkgname(builder, "llvm-tools");
2445
2446 let tmp = tmpdir(builder);
2447 let image = tmp.join("llvm-tools-image");
2448 drop(fs::remove_dir_all(&image));
2449
2450 // Prepare the image directory
dfeec247 2451 let src_bindir = builder.llvm_out(target).join("bin");
3dfed10e 2452 let dst_bindir = image.join("lib/rustlib").join(&*target.triple).join("bin");
b7449926 2453 t!(fs::create_dir_all(&dst_bindir));
8faf50e0 2454 for tool in LLVM_TOOLS {
3dfed10e 2455 let exe = src_bindir.join(exe(tool, target));
b7449926 2456 builder.install(&exe, &dst_bindir, 0o755);
8faf50e0
XL
2457 }
2458
f9f354fc
XL
2459 // Copy libLLVM.so to the target lib dir as well, so the RPATH like
2460 // `$ORIGIN/../lib` can find it. It may also be used as a dependency
2461 // of `rustc-dev` to support the inherited `-lLLVM` when using the
2462 // compiler libraries.
2463 maybe_install_llvm_target(builder, target, &image);
2464
8faf50e0
XL
2465 // Prepare the overlay
2466 let overlay = tmp.join("llvm-tools-overlay");
2467 drop(fs::remove_dir_all(&overlay));
2468 builder.create_dir(&overlay);
2469 builder.install(&src.join("README.txt"), &overlay, 0o644);
2470 builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
2471 builder.create(&overlay.join("version"), &builder.llvm_tools_vers());
2472
2473 // Generate the installer tarball
2474 let mut cmd = rust_installer(builder);
2475 cmd.arg("generate")
2476 .arg("--product-name=Rust")
2477 .arg("--rel-manifest-dir=rustlib")
2478 .arg("--success-message=llvm-tools-installed.")
dfeec247
XL
2479 .arg("--image-dir")
2480 .arg(&image)
2481 .arg("--work-dir")
2482 .arg(&tmpdir(builder))
2483 .arg("--output-dir")
2484 .arg(&distdir(builder))
2485 .arg("--non-installed-overlay")
2486 .arg(&overlay)
3dfed10e 2487 .arg(format!("--package-name={}-{}", name, target.triple))
8faf50e0
XL
2488 .arg("--legacy-manifest-dirs=rustlib,cargo")
2489 .arg("--component-name=llvm-tools-preview");
2490
8faf50e0 2491 builder.run(&mut cmd);
3dfed10e 2492 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
8faf50e0
XL
2493 }
2494}
1b1a35ee
XL
2495
2496// Tarball intended for internal consumption to ease rustc/std development.
2497//
2498// Should not be considered stable by end users.
2499#[derive(Clone, Debug, Eq, Hash, PartialEq)]
2500pub struct RustDev {
2501 pub target: TargetSelection,
2502}
2503
2504impl Step for RustDev {
2505 type Output = Option<PathBuf>;
2506 const DEFAULT: bool = true;
2507 const ONLY_HOSTS: bool = true;
2508
2509 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
2510 run.path("rust-dev")
2511 }
2512
2513 fn make_run(run: RunConfig<'_>) {
2514 run.builder.ensure(RustDev { target: run.target });
2515 }
2516
2517 fn run(self, builder: &Builder<'_>) -> Option<PathBuf> {
2518 let target = self.target;
2519
2520 /* run only if llvm-config isn't used */
2521 if let Some(config) = builder.config.target_config.get(&target) {
2522 if let Some(ref _s) = config.llvm_config {
2523 builder.info(&format!("Skipping RustDev ({}): external LLVM", target));
2524 return None;
2525 }
2526 }
2527
2528 builder.info(&format!("Dist RustDev ({})", target));
2529 let _time = timeit(builder);
2530 let src = builder.src.join("src/llvm-project/llvm");
2531 let name = pkgname(builder, "rust-dev");
2532
2533 let tmp = tmpdir(builder);
2534 let image = tmp.join("rust-dev-image");
2535 drop(fs::remove_dir_all(&image));
2536
2537 // Prepare the image directory
2538 let dst_bindir = image.join("bin");
2539 t!(fs::create_dir_all(&dst_bindir));
2540
2541 let exe = builder.llvm_out(target).join("bin").join(exe("llvm-config", target));
2542 builder.install(&exe, &dst_bindir, 0o755);
2543 builder.install(&builder.llvm_filecheck(target), &dst_bindir, 0o755);
2544
2545 // Copy the include directory as well; needed mostly to build
2546 // librustc_llvm properly (e.g., llvm-config.h is in here). But also
2547 // just broadly useful to be able to link against the bundled LLVM.
2548 builder.cp_r(&builder.llvm_out(target).join("include"), &image.join("include"));
2549
2550 // Copy libLLVM.so to the target lib dir as well, so the RPATH like
2551 // `$ORIGIN/../lib` can find it. It may also be used as a dependency
2552 // of `rustc-dev` to support the inherited `-lLLVM` when using the
2553 // compiler libraries.
2554 maybe_install_llvm(builder, target, &image.join("lib"));
2555
2556 // Prepare the overlay
2557 let overlay = tmp.join("rust-dev-overlay");
2558 drop(fs::remove_dir_all(&overlay));
2559 builder.create_dir(&overlay);
2560 builder.install(&src.join("README.txt"), &overlay, 0o644);
2561 builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
2562 builder.create(&overlay.join("version"), &builder.rust_version());
2563
2564 // Generate the installer tarball
2565 let mut cmd = rust_installer(builder);
2566 cmd.arg("generate")
2567 .arg("--product-name=Rust")
2568 .arg("--rel-manifest-dir=rustlib")
2569 .arg("--success-message=rust-dev-installed.")
2570 .arg("--image-dir")
2571 .arg(&image)
2572 .arg("--work-dir")
2573 .arg(&tmpdir(builder))
2574 .arg("--output-dir")
2575 .arg(&distdir(builder))
2576 .arg("--non-installed-overlay")
2577 .arg(&overlay)
2578 .arg(format!("--package-name={}-{}", name, target.triple))
2579 .arg("--legacy-manifest-dirs=rustlib,cargo")
2580 .arg("--component-name=rust-dev");
2581
2582 builder.run(&mut cmd);
2583 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target.triple)))
2584 }
2585}
2586
2587/// Tarball containing a prebuilt version of the build-manifest tool, intented to be used by the
2588/// release process to avoid cloning the monorepo and building stuff.
2589///
2590/// Should not be considered stable by end users.
2591#[derive(Clone, Debug, Eq, Hash, PartialEq)]
2592pub struct BuildManifest {
2593 pub target: TargetSelection,
2594}
2595
2596impl Step for BuildManifest {
2597 type Output = PathBuf;
2598 const DEFAULT: bool = false;
2599 const ONLY_HOSTS: bool = true;
2600
2601 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
2602 run.path("src/tools/build-manifest")
2603 }
2604
2605 fn make_run(run: RunConfig<'_>) {
2606 run.builder.ensure(BuildManifest { target: run.target });
2607 }
2608
2609 fn run(self, builder: &Builder<'_>) -> PathBuf {
2610 let build_manifest = builder.tool_exe(Tool::BuildManifest);
2611
2612 let name = pkgname(builder, "build-manifest");
2613 let tmp = tmpdir(builder);
2614
2615 // Prepare the image.
2616 let image = tmp.join("build-manifest-image");
2617 let image_bin = image.join("bin");
2618 let _ = fs::remove_dir_all(&image);
2619 t!(fs::create_dir_all(&image_bin));
2620 builder.install(&build_manifest, &image_bin, 0o755);
2621
2622 // Prepare the overlay.
2623 let overlay = tmp.join("build-manifest-overlay");
2624 let _ = fs::remove_dir_all(&overlay);
2625 builder.create_dir(&overlay);
2626 builder.create(&overlay.join("version"), &builder.rust_version());
2627 for file in &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"] {
2628 builder.install(&builder.src.join(file), &overlay, 0o644);
2629 }
2630
2631 // Create the final tarball.
2632 let mut cmd = rust_installer(builder);
2633 cmd.arg("generate")
2634 .arg("--product-name=Rust")
2635 .arg("--rel-manifest-dir=rustlib")
2636 .arg("--success-message=build-manifest installed.")
2637 .arg("--image-dir")
2638 .arg(&image)
2639 .arg("--work-dir")
2640 .arg(&tmpdir(builder))
2641 .arg("--output-dir")
2642 .arg(&distdir(builder))
2643 .arg("--non-installed-overlay")
2644 .arg(&overlay)
2645 .arg(format!("--package-name={}-{}", name, self.target.triple))
2646 .arg("--legacy-manifest-dirs=rustlib,cargo")
2647 .arg("--component-name=build-manifest");
2648
2649 builder.run(&mut cmd);
2650 distdir(builder).join(format!("{}-{}.tar.gz", name, self.target.triple))
2651 }
2652}