]> git.proxmox.com Git - rustc.git/blob - src/bootstrap/dist.rs
New upstream version 1.29.0+dfsg1
[rustc.git] / src / bootstrap / dist.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Implementation of the various distribution aspects of the compiler.
12 //!
13 //! This module is responsible for creating tarballs of the standard library,
14 //! compiler, and documentation. This ends up being what we distribute to
15 //! everyone as well.
16 //!
17 //! No tarball is actually created literally in this file, but rather we shell
18 //! out to `rust-installer` still. This may one day be replaced with bits and
19 //! pieces of `rustup.rs`!
20
21 use std::env;
22 use std::fs::{self, File};
23 use std::io::{Read, Write};
24 use std::path::{PathBuf, Path};
25 use std::process::{Command, Stdio};
26
27 use build_helper::output;
28
29 use {Compiler, Mode, LLVM_TOOLS};
30 use channel;
31 use util::{libdir, is_dylib, exe};
32 use builder::{Builder, RunConfig, ShouldRun, Step};
33 use compile;
34 use native;
35 use tool::{self, Tool};
36 use cache::{INTERNER, Interned};
37 use time;
38
39 pub fn pkgname(builder: &Builder, component: &str) -> String {
40 if component == "cargo" {
41 format!("{}-{}", component, builder.cargo_package_vers())
42 } else if component == "rls" {
43 format!("{}-{}", component, builder.rls_package_vers())
44 } else if component == "clippy" {
45 format!("{}-{}", component, builder.clippy_package_vers())
46 } else if component == "rustfmt" {
47 format!("{}-{}", component, builder.rustfmt_package_vers())
48 } else if component == "llvm-tools" {
49 format!("{}-{}", component, builder.llvm_tools_package_vers())
50 } else {
51 assert!(component.starts_with("rust"));
52 format!("{}-{}", component, builder.rust_package_vers())
53 }
54 }
55
56 fn distdir(builder: &Builder) -> PathBuf {
57 builder.out.join("dist")
58 }
59
60 pub fn tmpdir(builder: &Builder) -> PathBuf {
61 builder.out.join("tmp/dist")
62 }
63
64 fn rust_installer(builder: &Builder) -> Command {
65 builder.tool_cmd(Tool::RustInstaller)
66 }
67
68 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
69 pub struct Docs {
70 pub stage: u32,
71 pub host: Interned<String>,
72 }
73
74 impl Step for Docs {
75 type Output = PathBuf;
76 const DEFAULT: bool = true;
77
78 fn should_run(run: ShouldRun) -> ShouldRun {
79 run.path("src/doc")
80 }
81
82 fn make_run(run: RunConfig) {
83 run.builder.ensure(Docs {
84 stage: run.builder.top_stage,
85 host: run.target,
86 });
87 }
88
89 /// Builds the `rust-docs` installer component.
90 fn run(self, builder: &Builder) -> PathBuf {
91 let host = self.host;
92
93 let name = pkgname(builder, "rust-docs");
94
95 builder.info(&format!("Dist docs ({})", host));
96 if !builder.config.docs {
97 builder.info("\tskipping - docs disabled");
98 return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
99 }
100
101 builder.default_doc(None);
102
103 let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
104 let _ = fs::remove_dir_all(&image);
105
106 let dst = image.join("share/doc/rust/html");
107 t!(fs::create_dir_all(&dst));
108 let src = builder.doc_out(host);
109 builder.cp_r(&src, &dst);
110
111 let mut cmd = rust_installer(builder);
112 cmd.arg("generate")
113 .arg("--product-name=Rust-Documentation")
114 .arg("--rel-manifest-dir=rustlib")
115 .arg("--success-message=Rust-documentation-is-installed.")
116 .arg("--image-dir").arg(&image)
117 .arg("--work-dir").arg(&tmpdir(builder))
118 .arg("--output-dir").arg(&distdir(builder))
119 .arg(format!("--package-name={}-{}", name, host))
120 .arg("--component-name=rust-docs")
121 .arg("--legacy-manifest-dirs=rustlib,cargo")
122 .arg("--bulk-dirs=share/doc/rust/html");
123 builder.run(&mut cmd);
124 builder.remove_dir(&image);
125
126 distdir(builder).join(format!("{}-{}.tar.gz", name, host))
127 }
128 }
129
130 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
131 pub struct RustcDocs {
132 pub stage: u32,
133 pub host: Interned<String>,
134 }
135
136 impl Step for RustcDocs {
137 type Output = PathBuf;
138 const DEFAULT: bool = true;
139
140 fn should_run(run: ShouldRun) -> ShouldRun {
141 run.path("src/librustc")
142 }
143
144 fn make_run(run: RunConfig) {
145 run.builder.ensure(RustcDocs {
146 stage: run.builder.top_stage,
147 host: run.target,
148 });
149 }
150
151 /// Builds the `rustc-docs` installer component.
152 fn run(self, builder: &Builder) -> PathBuf {
153 let host = self.host;
154
155 let name = pkgname(builder, "rustc-docs");
156
157 builder.info(&format!("Dist compiler docs ({})", host));
158 if !builder.config.compiler_docs {
159 builder.info("\tskipping - compiler docs disabled");
160 return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
161 }
162
163 builder.default_doc(None);
164
165 let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
166 let _ = fs::remove_dir_all(&image);
167
168 let dst = image.join("share/doc/rust/html");
169 t!(fs::create_dir_all(&dst));
170 let src = builder.compiler_doc_out(host);
171 builder.cp_r(&src, &dst);
172
173 let mut cmd = rust_installer(builder);
174 cmd.arg("generate")
175 .arg("--product-name=Rustc-Documentation")
176 .arg("--rel-manifest-dir=rustlib")
177 .arg("--success-message=Rustc-documentation-is-installed.")
178 .arg("--image-dir").arg(&image)
179 .arg("--work-dir").arg(&tmpdir(builder))
180 .arg("--output-dir").arg(&distdir(builder))
181 .arg(format!("--package-name={}-{}", name, host))
182 .arg("--component-name=rustc-docs")
183 .arg("--legacy-manifest-dirs=rustlib,cargo")
184 .arg("--bulk-dirs=share/doc/rust/html");
185 builder.run(&mut cmd);
186 builder.remove_dir(&image);
187
188 distdir(builder).join(format!("{}-{}.tar.gz", name, host))
189 }
190 }
191
192 fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> {
193 let mut found = Vec::with_capacity(files.len());
194
195 for file in files {
196 let file_path =
197 path.iter()
198 .map(|dir| dir.join(file))
199 .find(|p| p.exists());
200
201 if let Some(file_path) = file_path {
202 found.push(file_path);
203 } else {
204 panic!("Could not find '{}' in {:?}", file, path);
205 }
206 }
207
208 found
209 }
210
211 fn make_win_dist(
212 rust_root: &Path, plat_root: &Path, target_triple: Interned<String>, builder: &Builder
213 ) {
214 //Ask gcc where it keeps its stuff
215 let mut cmd = Command::new(builder.cc(target_triple));
216 cmd.arg("-print-search-dirs");
217 let gcc_out = output(&mut cmd);
218
219 let mut bin_path: Vec<_> = env::split_paths(&env::var_os("PATH").unwrap_or_default()).collect();
220 let mut lib_path = Vec::new();
221
222 for line in gcc_out.lines() {
223 let idx = line.find(':').unwrap();
224 let key = &line[..idx];
225 let trim_chars: &[_] = &[' ', '='];
226 let value =
227 line[(idx + 1)..]
228 .trim_left_matches(trim_chars)
229 .split(';')
230 .map(PathBuf::from);
231
232 if key == "programs" {
233 bin_path.extend(value);
234 } else if key == "libraries" {
235 lib_path.extend(value);
236 }
237 }
238
239 let target_tools = ["gcc.exe", "ld.exe", "dlltool.exe", "libwinpthread-1.dll"];
240 let mut rustc_dlls = vec!["libstdc++-6.dll", "libwinpthread-1.dll"];
241 if target_triple.starts_with("i686-") {
242 rustc_dlls.push("libgcc_s_dw2-1.dll");
243 } else {
244 rustc_dlls.push("libgcc_s_seh-1.dll");
245 }
246
247 let target_libs = [ //MinGW libs
248 "libgcc.a",
249 "libgcc_eh.a",
250 "libgcc_s.a",
251 "libm.a",
252 "libmingw32.a",
253 "libmingwex.a",
254 "libstdc++.a",
255 "libiconv.a",
256 "libmoldname.a",
257 "libpthread.a",
258 //Windows import libs
259 "libadvapi32.a",
260 "libbcrypt.a",
261 "libcomctl32.a",
262 "libcomdlg32.a",
263 "libcredui.a",
264 "libcrypt32.a",
265 "libdbghelp.a",
266 "libgdi32.a",
267 "libimagehlp.a",
268 "libiphlpapi.a",
269 "libkernel32.a",
270 "libmsimg32.a",
271 "libmsvcrt.a",
272 "libodbc32.a",
273 "libole32.a",
274 "liboleaut32.a",
275 "libopengl32.a",
276 "libpsapi.a",
277 "librpcrt4.a",
278 "libsecur32.a",
279 "libsetupapi.a",
280 "libshell32.a",
281 "libsynchronization.a",
282 "libuser32.a",
283 "libuserenv.a",
284 "libuuid.a",
285 "libwinhttp.a",
286 "libwinmm.a",
287 "libwinspool.a",
288 "libws2_32.a",
289 "libwsock32.a",
290 ];
291
292 //Find mingw artifacts we want to bundle
293 let target_tools = find_files(&target_tools, &bin_path);
294 let rustc_dlls = find_files(&rustc_dlls, &bin_path);
295 let target_libs = find_files(&target_libs, &lib_path);
296
297 // Copy runtime dlls next to rustc.exe
298 let dist_bin_dir = rust_root.join("bin/");
299 fs::create_dir_all(&dist_bin_dir).expect("creating dist_bin_dir failed");
300 for src in rustc_dlls {
301 builder.copy_to_folder(&src, &dist_bin_dir);
302 }
303
304 //Copy platform tools to platform-specific bin directory
305 let target_bin_dir = plat_root.join("lib").join("rustlib").join(target_triple).join("bin");
306 fs::create_dir_all(&target_bin_dir).expect("creating target_bin_dir failed");
307 for src in target_tools {
308 builder.copy_to_folder(&src, &target_bin_dir);
309 }
310
311 // Warn windows-gnu users that the bundled GCC cannot compile C files
312 builder.create(
313 &target_bin_dir.join("GCC-WARNING.txt"),
314 "gcc.exe contained in this folder cannot be used for compiling C files - it is only\
315 used as a linker. In order to be able to compile projects containing C code use\
316 the GCC provided by MinGW or Cygwin."
317 );
318
319 //Copy platform libs to platform-specific lib directory
320 let target_lib_dir = plat_root.join("lib").join("rustlib").join(target_triple).join("lib");
321 fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed");
322 for src in target_libs {
323 builder.copy_to_folder(&src, &target_lib_dir);
324 }
325 }
326
327 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
328 pub struct Mingw {
329 pub host: Interned<String>,
330 }
331
332 impl Step for Mingw {
333 type Output = Option<PathBuf>;
334 const DEFAULT: bool = true;
335
336 fn should_run(run: ShouldRun) -> ShouldRun {
337 run.never()
338 }
339
340 fn make_run(run: RunConfig) {
341 run.builder.ensure(Mingw { host: run.target });
342 }
343
344 /// Build the `rust-mingw` installer component.
345 ///
346 /// This contains all the bits and pieces to run the MinGW Windows targets
347 /// without any extra installed software (e.g. we bundle gcc, libraries, etc).
348 fn run(self, builder: &Builder) -> Option<PathBuf> {
349 let host = self.host;
350
351 if !host.contains("pc-windows-gnu") {
352 return None;
353 }
354
355 builder.info(&format!("Dist mingw ({})", host));
356 let name = pkgname(builder, "rust-mingw");
357 let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
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).
365 make_win_dist(&tmpdir(builder), &image, host, &builder);
366
367 let mut cmd = rust_installer(builder);
368 cmd.arg("generate")
369 .arg("--product-name=Rust-MinGW")
370 .arg("--rel-manifest-dir=rustlib")
371 .arg("--success-message=Rust-MinGW-is-installed.")
372 .arg("--image-dir").arg(&image)
373 .arg("--work-dir").arg(&tmpdir(builder))
374 .arg("--output-dir").arg(&distdir(builder))
375 .arg(format!("--package-name={}-{}", name, host))
376 .arg("--component-name=rust-mingw")
377 .arg("--legacy-manifest-dirs=rustlib,cargo");
378 builder.run(&mut cmd);
379 t!(fs::remove_dir_all(&image));
380 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, host)))
381 }
382 }
383
384 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
385 pub struct Rustc {
386 pub compiler: Compiler,
387 }
388
389 impl Step for Rustc {
390 type Output = PathBuf;
391 const DEFAULT: bool = true;
392 const ONLY_HOSTS: bool = true;
393
394 fn should_run(run: ShouldRun) -> ShouldRun {
395 run.path("src/librustc")
396 }
397
398 fn make_run(run: RunConfig) {
399 run.builder.ensure(Rustc {
400 compiler: run.builder.compiler(run.builder.top_stage, run.target),
401 });
402 }
403
404 /// Creates the `rustc` installer component.
405 fn run(self, builder: &Builder) -> PathBuf {
406 let compiler = self.compiler;
407 let host = self.compiler.host;
408
409 builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host));
410 let name = pkgname(builder, "rustc");
411 let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
412 let _ = fs::remove_dir_all(&image);
413 let overlay = tmpdir(builder).join(format!("{}-{}-overlay", name, host));
414 let _ = fs::remove_dir_all(&overlay);
415
416 // Prepare the rustc "image", what will actually end up getting installed
417 prepare_image(builder, compiler, &image);
418
419 // Prepare the overlay which is part of the tarball but won't actually be
420 // installed
421 let cp = |file: &str| {
422 builder.install(&builder.src.join(file), &overlay, 0o644);
423 };
424 cp("COPYRIGHT");
425 cp("LICENSE-APACHE");
426 cp("LICENSE-MIT");
427 cp("README.md");
428 // tiny morsel of metadata is used by rust-packaging
429 let version = builder.rust_version();
430 builder.create(&overlay.join("version"), &version);
431 if let Some(sha) = builder.rust_sha() {
432 builder.create(&overlay.join("git-commit-hash"), &sha);
433 }
434
435 // On MinGW we've got a few runtime DLL dependencies that we need to
436 // include. The first argument to this script is where to put these DLLs
437 // (the image we're creating), and the second argument is a junk directory
438 // to ignore all other MinGW stuff the script creates.
439 //
440 // On 32-bit MinGW we're always including a DLL which needs some extra
441 // licenses to distribute. On 64-bit MinGW we don't actually distribute
442 // anything requiring us to distribute a license, but it's likely the
443 // install will *also* include the rust-mingw package, which also needs
444 // licenses, so to be safe we just include it here in all MinGW packages.
445 if host.contains("pc-windows-gnu") {
446 make_win_dist(&image, &tmpdir(builder), host, builder);
447
448 let dst = image.join("share/doc");
449 t!(fs::create_dir_all(&dst));
450 builder.cp_r(&builder.src.join("src/etc/third-party"), &dst);
451 }
452
453 // Finally, wrap everything up in a nice tarball!
454 let mut cmd = rust_installer(builder);
455 cmd.arg("generate")
456 .arg("--product-name=Rust")
457 .arg("--rel-manifest-dir=rustlib")
458 .arg("--success-message=Rust-is-ready-to-roll.")
459 .arg("--image-dir").arg(&image)
460 .arg("--work-dir").arg(&tmpdir(builder))
461 .arg("--output-dir").arg(&distdir(builder))
462 .arg("--non-installed-overlay").arg(&overlay)
463 .arg(format!("--package-name={}-{}", name, host))
464 .arg("--component-name=rustc")
465 .arg("--legacy-manifest-dirs=rustlib,cargo");
466 builder.run(&mut cmd);
467 builder.remove_dir(&image);
468 builder.remove_dir(&overlay);
469
470 return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
471
472 fn prepare_image(builder: &Builder, compiler: Compiler, image: &Path) {
473 let host = compiler.host;
474 let src = builder.sysroot(compiler);
475 let libdir = libdir(&host);
476
477 // Copy rustc/rustdoc binaries
478 t!(fs::create_dir_all(image.join("bin")));
479 builder.cp_r(&src.join("bin"), &image.join("bin"));
480
481 builder.install(&builder.rustdoc(compiler.host), &image.join("bin"), 0o755);
482
483 // Copy runtime DLLs needed by the compiler
484 if libdir != "bin" {
485 for entry in builder.read_dir(&src.join(libdir)) {
486 let name = entry.file_name();
487 if let Some(s) = name.to_str() {
488 if is_dylib(s) {
489 builder.install(&entry.path(), &image.join(libdir), 0o644);
490 }
491 }
492 }
493 }
494
495 // Copy over the codegen backends
496 let backends_src = builder.sysroot_codegen_backends(compiler);
497 let backends_rel = backends_src.strip_prefix(&src).unwrap();
498 let backends_dst = image.join(&backends_rel);
499 t!(fs::create_dir_all(&backends_dst));
500 builder.cp_r(&backends_src, &backends_dst);
501
502 // Copy over lld if it's there
503 if builder.config.lld_enabled {
504 let exe = exe("rust-lld", &compiler.host);
505 let src = builder.sysroot_libdir(compiler, host)
506 .parent()
507 .unwrap()
508 .join("bin")
509 .join(&exe);
510 // for the rationale about this rename check `compile::copy_lld_to_sysroot`
511 let dst = image.join("lib/rustlib")
512 .join(&*host)
513 .join("bin")
514 .join(&exe);
515 t!(fs::create_dir_all(&dst.parent().unwrap()));
516 builder.copy(&src, &dst);
517 }
518
519 // Man pages
520 t!(fs::create_dir_all(image.join("share/man/man1")));
521 let man_src = builder.src.join("src/doc/man");
522 let man_dst = image.join("share/man/man1");
523 let month_year = t!(time::strftime("%B %Y", &time::now()));
524 // don't use our `bootstrap::util::{copy, cp_r}`, because those try
525 // to hardlink, and we don't want to edit the source templates
526 for file_entry in builder.read_dir(&man_src) {
527 let page_src = file_entry.path();
528 let page_dst = man_dst.join(file_entry.file_name());
529 t!(fs::copy(&page_src, &page_dst));
530 // template in month/year and version number
531 builder.replace_in_file(&page_dst,
532 &[("<INSERT DATE HERE>", &month_year),
533 ("<INSERT VERSION HERE>", channel::CFG_RELEASE_NUM)]);
534 }
535
536 // Debugger scripts
537 builder.ensure(DebuggerScripts {
538 sysroot: INTERNER.intern_path(image.to_owned()),
539 host,
540 });
541
542 // Misc license info
543 let cp = |file: &str| {
544 builder.install(&builder.src.join(file), &image.join("share/doc/rust"), 0o644);
545 };
546 cp("COPYRIGHT");
547 cp("LICENSE-APACHE");
548 cp("LICENSE-MIT");
549 cp("README.md");
550 }
551 }
552 }
553
554 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
555 pub struct DebuggerScripts {
556 pub sysroot: Interned<PathBuf>,
557 pub host: Interned<String>,
558 }
559
560 impl Step for DebuggerScripts {
561 type Output = ();
562
563 fn should_run(run: ShouldRun) -> ShouldRun {
564 run.path("src/lldb_batchmode.py")
565 }
566
567 fn make_run(run: RunConfig) {
568 run.builder.ensure(DebuggerScripts {
569 sysroot: run.builder.sysroot(run.builder.compiler(run.builder.top_stage, run.host)),
570 host: run.target,
571 });
572 }
573
574 /// Copies debugger scripts for `target` into the `sysroot` specified.
575 fn run(self, builder: &Builder) {
576 let host = self.host;
577 let sysroot = self.sysroot;
578 let dst = sysroot.join("lib/rustlib/etc");
579 t!(fs::create_dir_all(&dst));
580 let cp_debugger_script = |file: &str| {
581 builder.install(&builder.src.join("src/etc/").join(file), &dst, 0o644);
582 };
583 if host.contains("windows-msvc") {
584 // windbg debugger scripts
585 builder.install(&builder.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"),
586 0o755);
587
588 cp_debugger_script("natvis/intrinsic.natvis");
589 cp_debugger_script("natvis/liballoc.natvis");
590 cp_debugger_script("natvis/libcore.natvis");
591 } else {
592 cp_debugger_script("debugger_pretty_printers_common.py");
593
594 // gdb debugger scripts
595 builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"),
596 0o755);
597
598 cp_debugger_script("gdb_load_rust_pretty_printers.py");
599 cp_debugger_script("gdb_rust_pretty_printing.py");
600
601 // lldb debugger scripts
602 builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"),
603 0o755);
604
605 cp_debugger_script("lldb_rust_formatters.py");
606 }
607 }
608 }
609
610 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
611 pub struct Std {
612 pub compiler: Compiler,
613 pub target: Interned<String>,
614 }
615
616 impl Step for Std {
617 type Output = PathBuf;
618 const DEFAULT: bool = true;
619
620 fn should_run(run: ShouldRun) -> ShouldRun {
621 run.path("src/libstd")
622 }
623
624 fn make_run(run: RunConfig) {
625 run.builder.ensure(Std {
626 compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
627 target: run.target,
628 });
629 }
630
631 fn run(self, builder: &Builder) -> PathBuf {
632 let compiler = self.compiler;
633 let target = self.target;
634
635 let name = pkgname(builder, "rust-std");
636 builder.info(&format!("Dist std stage{} ({} -> {})",
637 compiler.stage, &compiler.host, target));
638
639 // The only true set of target libraries came from the build triple, so
640 // let's reduce redundant work by only producing archives from that host.
641 if compiler.host != builder.config.build {
642 builder.info("\tskipping, not a build host");
643 return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
644 }
645
646 // We want to package up as many target libraries as possible
647 // for the `rust-std` package, so if this is a host target we
648 // depend on librustc and otherwise we just depend on libtest.
649 if builder.hosts.iter().any(|t| t == target) {
650 builder.ensure(compile::Rustc { compiler, target });
651 } else {
652 if builder.no_std(target) == Some(true) {
653 // the `test` doesn't compile for no-std targets
654 builder.ensure(compile::Std { compiler, target });
655 } else {
656 builder.ensure(compile::Test { compiler, target });
657 }
658 }
659
660 let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
661 let _ = fs::remove_dir_all(&image);
662
663 let dst = image.join("lib/rustlib").join(target);
664 t!(fs::create_dir_all(&dst));
665 let mut src = builder.sysroot_libdir(compiler, target).to_path_buf();
666 src.pop(); // Remove the trailing /lib folder from the sysroot_libdir
667 builder.cp_filtered(&src, &dst, &|path| {
668 let name = path.file_name().and_then(|s| s.to_str());
669 name != Some(builder.config.rust_codegen_backends_dir.as_str()) &&
670 name != Some("bin")
671
672 });
673
674 let mut cmd = rust_installer(builder);
675 cmd.arg("generate")
676 .arg("--product-name=Rust")
677 .arg("--rel-manifest-dir=rustlib")
678 .arg("--success-message=std-is-standing-at-the-ready.")
679 .arg("--image-dir").arg(&image)
680 .arg("--work-dir").arg(&tmpdir(builder))
681 .arg("--output-dir").arg(&distdir(builder))
682 .arg(format!("--package-name={}-{}", name, target))
683 .arg(format!("--component-name=rust-std-{}", target))
684 .arg("--legacy-manifest-dirs=rustlib,cargo");
685 builder.run(&mut cmd);
686 builder.remove_dir(&image);
687 distdir(builder).join(format!("{}-{}.tar.gz", name, target))
688 }
689 }
690
691 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
692 pub struct Analysis {
693 pub compiler: Compiler,
694 pub target: Interned<String>,
695 }
696
697 impl Step for Analysis {
698 type Output = PathBuf;
699 const DEFAULT: bool = true;
700
701 fn should_run(run: ShouldRun) -> ShouldRun {
702 let builder = run.builder;
703 run.path("analysis").default_condition(builder.config.extended)
704 }
705
706 fn make_run(run: RunConfig) {
707 run.builder.ensure(Analysis {
708 compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
709 target: run.target,
710 });
711 }
712
713 /// Creates a tarball of save-analysis metadata, if available.
714 fn run(self, builder: &Builder) -> PathBuf {
715 let compiler = self.compiler;
716 let target = self.target;
717 assert!(builder.config.extended);
718 builder.info("Dist analysis");
719 let name = pkgname(builder, "rust-analysis");
720
721 if &compiler.host != builder.config.build {
722 builder.info("\tskipping, not a build host");
723 return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
724 }
725
726 builder.ensure(Std { compiler, target });
727
728 // Package save-analysis from stage1 if not doing a full bootstrap, as the
729 // stage2 artifacts is simply copied from stage1 in that case.
730 let compiler = if builder.force_use_stage1(compiler, target) {
731 builder.compiler(1, compiler.host)
732 } else {
733 compiler.clone()
734 };
735
736 let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
737
738 let src = builder.stage_out(compiler, Mode::Std)
739 .join(target).join(builder.cargo_dir()).join("deps");
740
741 let image_src = src.join("save-analysis");
742 let dst = image.join("lib/rustlib").join(target).join("analysis");
743 t!(fs::create_dir_all(&dst));
744 builder.info(&format!("image_src: {:?}, dst: {:?}", image_src, dst));
745 builder.cp_r(&image_src, &dst);
746
747 let mut cmd = rust_installer(builder);
748 cmd.arg("generate")
749 .arg("--product-name=Rust")
750 .arg("--rel-manifest-dir=rustlib")
751 .arg("--success-message=save-analysis-saved.")
752 .arg("--image-dir").arg(&image)
753 .arg("--work-dir").arg(&tmpdir(builder))
754 .arg("--output-dir").arg(&distdir(builder))
755 .arg(format!("--package-name={}-{}", name, target))
756 .arg(format!("--component-name=rust-analysis-{}", target))
757 .arg("--legacy-manifest-dirs=rustlib,cargo");
758 builder.run(&mut cmd);
759 builder.remove_dir(&image);
760 distdir(builder).join(format!("{}-{}.tar.gz", name, target))
761 }
762 }
763
764 fn copy_src_dirs(builder: &Builder, src_dirs: &[&str], exclude_dirs: &[&str], dst_dir: &Path) {
765 fn filter_fn(exclude_dirs: &[&str], dir: &str, path: &Path) -> bool {
766 let spath = match path.to_str() {
767 Some(path) => path,
768 None => return false,
769 };
770 if spath.ends_with("~") || spath.ends_with(".pyc") {
771 return false
772 }
773 if (spath.contains("llvm/test") || spath.contains("llvm\\test")) &&
774 (spath.ends_with(".ll") ||
775 spath.ends_with(".td") ||
776 spath.ends_with(".s")) {
777 return false
778 }
779 if spath.contains("test/emscripten") || spath.contains("test\\emscripten") {
780 return false
781 }
782
783 let full_path = Path::new(dir).join(path);
784 if exclude_dirs.iter().any(|excl| full_path == Path::new(excl)) {
785 return false;
786 }
787
788 let excludes = [
789 "CVS", "RCS", "SCCS", ".git", ".gitignore", ".gitmodules",
790 ".gitattributes", ".cvsignore", ".svn", ".arch-ids", "{arch}",
791 "=RELEASE-ID", "=meta-update", "=update", ".bzr", ".bzrignore",
792 ".bzrtags", ".hg", ".hgignore", ".hgrags", "_darcs",
793 ];
794 !path.iter()
795 .map(|s| s.to_str().unwrap())
796 .any(|s| excludes.contains(&s))
797 }
798
799 // Copy the directories using our filter
800 for item in src_dirs {
801 let dst = &dst_dir.join(item);
802 t!(fs::create_dir_all(dst));
803 builder.cp_filtered(
804 &builder.src.join(item), dst, &|path| filter_fn(exclude_dirs, item, path));
805 }
806 }
807
808 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
809 pub struct Src;
810
811 impl Step for Src {
812 /// The output path of the src installer tarball
813 type Output = PathBuf;
814 const DEFAULT: bool = true;
815 const ONLY_HOSTS: bool = true;
816
817 fn should_run(run: ShouldRun) -> ShouldRun {
818 run.path("src")
819 }
820
821 fn make_run(run: RunConfig) {
822 run.builder.ensure(Src);
823 }
824
825 /// Creates the `rust-src` installer component
826 fn run(self, builder: &Builder) -> PathBuf {
827 builder.info("Dist src");
828
829 let name = pkgname(builder, "rust-src");
830 let image = tmpdir(builder).join(format!("{}-image", name));
831 let _ = fs::remove_dir_all(&image);
832
833 let dst = image.join("lib/rustlib/src");
834 let dst_src = dst.join("rust");
835 t!(fs::create_dir_all(&dst_src));
836
837 let src_files = [
838 "src/Cargo.lock",
839 ];
840 // This is the reduced set of paths which will become the rust-src component
841 // (essentially libstd and all of its path dependencies)
842 let std_src_dirs = [
843 "src/build_helper",
844 "src/dlmalloc",
845 "src/liballoc",
846 "src/liballoc_jemalloc",
847 "src/liballoc_system",
848 "src/libbacktrace",
849 "src/libcompiler_builtins",
850 "src/libcore",
851 "src/liblibc",
852 "src/libpanic_abort",
853 "src/libpanic_unwind",
854 "src/librustc_asan",
855 "src/librustc_lsan",
856 "src/librustc_msan",
857 "src/librustc_tsan",
858 "src/libstd",
859 "src/libstd_unicode",
860 "src/libunwind",
861 "src/rustc/compiler_builtins_shim",
862 "src/rustc/libc_shim",
863 "src/rustc/dlmalloc_shim",
864 "src/libtest",
865 "src/libterm",
866 "src/jemalloc",
867 "src/libprofiler_builtins",
868 "src/stdsimd",
869 ];
870 let std_src_dirs_exclude = [
871 "src/libcompiler_builtins/compiler-rt/test",
872 "src/jemalloc/test/unit",
873 ];
874
875 copy_src_dirs(builder, &std_src_dirs[..], &std_src_dirs_exclude[..], &dst_src);
876 for file in src_files.iter() {
877 builder.copy(&builder.src.join(file), &dst_src.join(file));
878 }
879
880 // Create source tarball in rust-installer format
881 let mut cmd = rust_installer(builder);
882 cmd.arg("generate")
883 .arg("--product-name=Rust")
884 .arg("--rel-manifest-dir=rustlib")
885 .arg("--success-message=Awesome-Source.")
886 .arg("--image-dir").arg(&image)
887 .arg("--work-dir").arg(&tmpdir(builder))
888 .arg("--output-dir").arg(&distdir(builder))
889 .arg(format!("--package-name={}", name))
890 .arg("--component-name=rust-src")
891 .arg("--legacy-manifest-dirs=rustlib,cargo");
892 builder.run(&mut cmd);
893
894 builder.remove_dir(&image);
895 distdir(builder).join(&format!("{}.tar.gz", name))
896 }
897 }
898
899 const CARGO_VENDOR_VERSION: &str = "0.1.4";
900
901 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
902 pub struct PlainSourceTarball;
903
904 impl Step for PlainSourceTarball {
905 /// Produces the location of the tarball generated
906 type Output = PathBuf;
907 const DEFAULT: bool = true;
908 const ONLY_HOSTS: bool = true;
909
910 fn should_run(run: ShouldRun) -> ShouldRun {
911 let builder = run.builder;
912 run.path("src").default_condition(builder.config.rust_dist_src)
913 }
914
915 fn make_run(run: RunConfig) {
916 run.builder.ensure(PlainSourceTarball);
917 }
918
919 /// Creates the plain source tarball
920 fn run(self, builder: &Builder) -> PathBuf {
921 builder.info("Create plain source tarball");
922
923 // Make sure that the root folder of tarball has the correct name
924 let plain_name = format!("{}-src", pkgname(builder, "rustc"));
925 let plain_dst_src = tmpdir(builder).join(&plain_name);
926 let _ = fs::remove_dir_all(&plain_dst_src);
927 t!(fs::create_dir_all(&plain_dst_src));
928
929 // This is the set of root paths which will become part of the source package
930 let src_files = [
931 "COPYRIGHT",
932 "LICENSE-APACHE",
933 "LICENSE-MIT",
934 "CONTRIBUTING.md",
935 "README.md",
936 "RELEASES.md",
937 "configure",
938 "x.py",
939 "config.toml.example",
940 ];
941 let src_dirs = [
942 "src",
943 ];
944
945 copy_src_dirs(builder, &src_dirs[..], &[], &plain_dst_src);
946
947 // Copy the files normally
948 for item in &src_files {
949 builder.copy(&builder.src.join(item), &plain_dst_src.join(item));
950 }
951
952 // Create the version file
953 builder.create(&plain_dst_src.join("version"), &builder.rust_version());
954 if let Some(sha) = builder.rust_sha() {
955 builder.create(&plain_dst_src.join("git-commit-hash"), &sha);
956 }
957
958 // If we're building from git sources, we need to vendor a complete distribution.
959 if builder.rust_info.is_git() {
960 // Get cargo-vendor installed, if it isn't already.
961 let mut has_cargo_vendor = false;
962 let mut cmd = Command::new(&builder.initial_cargo);
963 for line in output(cmd.arg("install").arg("--list")).lines() {
964 has_cargo_vendor |= line.starts_with("cargo-vendor ");
965 }
966 if !has_cargo_vendor {
967 let mut cmd = builder.cargo(
968 builder.compiler(0, builder.config.build),
969 Mode::ToolBootstrap,
970 builder.config.build,
971 "install"
972 );
973 cmd.arg("--force")
974 .arg("--debug")
975 .arg("--vers").arg(CARGO_VENDOR_VERSION)
976 .arg("cargo-vendor");
977 if let Some(dir) = builder.openssl_install_dir(builder.config.build) {
978 builder.ensure(native::Openssl {
979 target: builder.config.build,
980 });
981 cmd.env("OPENSSL_DIR", dir);
982 }
983 builder.run(&mut cmd);
984 }
985
986 // Vendor all Cargo dependencies
987 let mut cmd = Command::new(&builder.initial_cargo);
988 cmd.arg("vendor")
989 .current_dir(&plain_dst_src.join("src"));
990 builder.run(&mut cmd);
991 }
992
993 // Create plain source tarball
994 let plain_name = format!("rustc-{}-src", builder.rust_package_vers());
995 let mut tarball = distdir(builder).join(&format!("{}.tar.gz", plain_name));
996 tarball.set_extension(""); // strip .gz
997 tarball.set_extension(""); // strip .tar
998 if let Some(dir) = tarball.parent() {
999 builder.create_dir(&dir);
1000 }
1001 builder.info("running installer");
1002 let mut cmd = rust_installer(builder);
1003 cmd.arg("tarball")
1004 .arg("--input").arg(&plain_name)
1005 .arg("--output").arg(&tarball)
1006 .arg("--work-dir=.")
1007 .current_dir(tmpdir(builder));
1008 builder.run(&mut cmd);
1009 distdir(builder).join(&format!("{}.tar.gz", plain_name))
1010 }
1011 }
1012
1013 // We have to run a few shell scripts, which choke quite a bit on both `\`
1014 // characters and on `C:\` paths, so normalize both of them away.
1015 pub fn sanitize_sh(path: &Path) -> String {
1016 let path = path.to_str().unwrap().replace("\\", "/");
1017 return change_drive(&path).unwrap_or(path);
1018
1019 fn change_drive(s: &str) -> Option<String> {
1020 let mut ch = s.chars();
1021 let drive = ch.next().unwrap_or('C');
1022 if ch.next() != Some(':') {
1023 return None
1024 }
1025 if ch.next() != Some('/') {
1026 return None
1027 }
1028 Some(format!("/{}/{}", drive, &s[drive.len_utf8() + 2..]))
1029 }
1030 }
1031
1032 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1033 pub struct Cargo {
1034 pub stage: u32,
1035 pub target: Interned<String>,
1036 }
1037
1038 impl Step for Cargo {
1039 type Output = PathBuf;
1040 const ONLY_HOSTS: bool = true;
1041
1042 fn should_run(run: ShouldRun) -> ShouldRun {
1043 run.path("cargo")
1044 }
1045
1046 fn make_run(run: RunConfig) {
1047 run.builder.ensure(Cargo {
1048 stage: run.builder.top_stage,
1049 target: run.target,
1050 });
1051 }
1052
1053 fn run(self, builder: &Builder) -> PathBuf {
1054 let stage = self.stage;
1055 let target = self.target;
1056
1057 builder.info(&format!("Dist cargo stage{} ({})", stage, target));
1058 let src = builder.src.join("src/tools/cargo");
1059 let etc = src.join("src/etc");
1060 let release_num = builder.release_num("cargo");
1061 let name = pkgname(builder, "cargo");
1062 let version = builder.cargo_info.version(builder, &release_num);
1063
1064 let tmp = tmpdir(builder);
1065 let image = tmp.join("cargo-image");
1066 drop(fs::remove_dir_all(&image));
1067 builder.create_dir(&image);
1068
1069 // Prepare the image directory
1070 builder.create_dir(&image.join("share/zsh/site-functions"));
1071 builder.create_dir(&image.join("etc/bash_completion.d"));
1072 let cargo = builder.ensure(tool::Cargo {
1073 compiler: builder.compiler(stage, builder.config.build),
1074 target
1075 });
1076 builder.install(&cargo, &image.join("bin"), 0o755);
1077 for man in t!(etc.join("man").read_dir()) {
1078 let man = t!(man);
1079 builder.install(&man.path(), &image.join("share/man/man1"), 0o644);
1080 }
1081 builder.install(&etc.join("_cargo"), &image.join("share/zsh/site-functions"), 0o644);
1082 builder.copy(&etc.join("cargo.bashcomp.sh"),
1083 &image.join("etc/bash_completion.d/cargo"));
1084 let doc = image.join("share/doc/cargo");
1085 builder.install(&src.join("README.md"), &doc, 0o644);
1086 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1087 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1088 builder.install(&src.join("LICENSE-THIRD-PARTY"), &doc, 0o644);
1089
1090 // Prepare the overlay
1091 let overlay = tmp.join("cargo-overlay");
1092 drop(fs::remove_dir_all(&overlay));
1093 builder.create_dir(&overlay);
1094 builder.install(&src.join("README.md"), &overlay, 0o644);
1095 builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
1096 builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
1097 builder.install(&src.join("LICENSE-THIRD-PARTY"), &overlay, 0o644);
1098 builder.create(&overlay.join("version"), &version);
1099
1100 // Generate the installer tarball
1101 let mut cmd = rust_installer(builder);
1102 cmd.arg("generate")
1103 .arg("--product-name=Rust")
1104 .arg("--rel-manifest-dir=rustlib")
1105 .arg("--success-message=Rust-is-ready-to-roll.")
1106 .arg("--image-dir").arg(&image)
1107 .arg("--work-dir").arg(&tmpdir(builder))
1108 .arg("--output-dir").arg(&distdir(builder))
1109 .arg("--non-installed-overlay").arg(&overlay)
1110 .arg(format!("--package-name={}-{}", name, target))
1111 .arg("--component-name=cargo")
1112 .arg("--legacy-manifest-dirs=rustlib,cargo");
1113 builder.run(&mut cmd);
1114 distdir(builder).join(format!("{}-{}.tar.gz", name, target))
1115 }
1116 }
1117
1118 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1119 pub struct Rls {
1120 pub stage: u32,
1121 pub target: Interned<String>,
1122 }
1123
1124 impl Step for Rls {
1125 type Output = Option<PathBuf>;
1126 const ONLY_HOSTS: bool = true;
1127
1128 fn should_run(run: ShouldRun) -> ShouldRun {
1129 run.path("rls")
1130 }
1131
1132 fn make_run(run: RunConfig) {
1133 run.builder.ensure(Rls {
1134 stage: run.builder.top_stage,
1135 target: run.target,
1136 });
1137 }
1138
1139 fn run(self, builder: &Builder) -> Option<PathBuf> {
1140 let stage = self.stage;
1141 let target = self.target;
1142 assert!(builder.config.extended);
1143
1144 builder.info(&format!("Dist RLS stage{} ({})", stage, target));
1145 let src = builder.src.join("src/tools/rls");
1146 let release_num = builder.release_num("rls");
1147 let name = pkgname(builder, "rls");
1148 let version = builder.rls_info.version(builder, &release_num);
1149
1150 let tmp = tmpdir(builder);
1151 let image = tmp.join("rls-image");
1152 drop(fs::remove_dir_all(&image));
1153 t!(fs::create_dir_all(&image));
1154
1155 // Prepare the image directory
1156 // We expect RLS to build, because we've exited this step above if tool
1157 // state for RLS isn't testing.
1158 let rls = builder.ensure(tool::Rls {
1159 compiler: builder.compiler(stage, builder.config.build),
1160 target, extra_features: Vec::new()
1161 }).or_else(|| { println!("Unable to build RLS, skipping dist"); None })?;
1162
1163 builder.install(&rls, &image.join("bin"), 0o755);
1164 let doc = image.join("share/doc/rls");
1165 builder.install(&src.join("README.md"), &doc, 0o644);
1166 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1167 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1168
1169 // Prepare the overlay
1170 let overlay = tmp.join("rls-overlay");
1171 drop(fs::remove_dir_all(&overlay));
1172 t!(fs::create_dir_all(&overlay));
1173 builder.install(&src.join("README.md"), &overlay, 0o644);
1174 builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
1175 builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
1176 builder.create(&overlay.join("version"), &version);
1177
1178 // Generate the installer tarball
1179 let mut cmd = rust_installer(builder);
1180 cmd.arg("generate")
1181 .arg("--product-name=Rust")
1182 .arg("--rel-manifest-dir=rustlib")
1183 .arg("--success-message=RLS-ready-to-serve.")
1184 .arg("--image-dir").arg(&image)
1185 .arg("--work-dir").arg(&tmpdir(builder))
1186 .arg("--output-dir").arg(&distdir(builder))
1187 .arg("--non-installed-overlay").arg(&overlay)
1188 .arg(format!("--package-name={}-{}", name, target))
1189 .arg("--legacy-manifest-dirs=rustlib,cargo")
1190 .arg("--component-name=rls-preview");
1191
1192 builder.run(&mut cmd);
1193 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
1194 }
1195 }
1196
1197 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1198 pub struct Clippy {
1199 pub stage: u32,
1200 pub target: Interned<String>,
1201 }
1202
1203 impl Step for Clippy {
1204 type Output = Option<PathBuf>;
1205 const ONLY_HOSTS: bool = true;
1206
1207 fn should_run(run: ShouldRun) -> ShouldRun {
1208 run.path("clippy")
1209 }
1210
1211 fn make_run(run: RunConfig) {
1212 run.builder.ensure(Clippy {
1213 stage: run.builder.top_stage,
1214 target: run.target,
1215 });
1216 }
1217
1218 fn run(self, builder: &Builder) -> Option<PathBuf> {
1219 let stage = self.stage;
1220 let target = self.target;
1221 assert!(builder.config.extended);
1222
1223 builder.info(&format!("Dist clippy stage{} ({})", stage, target));
1224 let src = builder.src.join("src/tools/clippy");
1225 let release_num = builder.release_num("clippy");
1226 let name = pkgname(builder, "clippy");
1227 let version = builder.clippy_info.version(builder, &release_num);
1228
1229 let tmp = tmpdir(builder);
1230 let image = tmp.join("clippy-image");
1231 drop(fs::remove_dir_all(&image));
1232 builder.create_dir(&image);
1233
1234 // Prepare the image directory
1235 // We expect clippy to build, because we've exited this step above if tool
1236 // state for clippy isn't testing.
1237 let clippy = builder.ensure(tool::Clippy {
1238 compiler: builder.compiler(stage, builder.config.build),
1239 target, extra_features: Vec::new()
1240 }).or_else(|| { println!("Unable to build clippy, skipping dist"); None })?;
1241 let cargoclippy = builder.ensure(tool::CargoClippy {
1242 compiler: builder.compiler(stage, builder.config.build),
1243 target, extra_features: Vec::new()
1244 }).or_else(|| { println!("Unable to build cargo clippy, skipping dist"); None })?;
1245
1246 builder.install(&clippy, &image.join("bin"), 0o755);
1247 builder.install(&cargoclippy, &image.join("bin"), 0o755);
1248 let doc = image.join("share/doc/clippy");
1249 builder.install(&src.join("README.md"), &doc, 0o644);
1250 builder.install(&src.join("LICENSE"), &doc, 0o644);
1251
1252 // Prepare the overlay
1253 let overlay = tmp.join("clippy-overlay");
1254 drop(fs::remove_dir_all(&overlay));
1255 t!(fs::create_dir_all(&overlay));
1256 builder.install(&src.join("README.md"), &overlay, 0o644);
1257 builder.install(&src.join("LICENSE"), &doc, 0o644);
1258 builder.create(&overlay.join("version"), &version);
1259
1260 // Generate the installer tarball
1261 let mut cmd = rust_installer(builder);
1262 cmd.arg("generate")
1263 .arg("--product-name=Rust")
1264 .arg("--rel-manifest-dir=rustlib")
1265 .arg("--success-message=clippy-ready-to-serve.")
1266 .arg("--image-dir").arg(&image)
1267 .arg("--work-dir").arg(&tmpdir(builder))
1268 .arg("--output-dir").arg(&distdir(builder))
1269 .arg("--non-installed-overlay").arg(&overlay)
1270 .arg(format!("--package-name={}-{}", name, target))
1271 .arg("--legacy-manifest-dirs=rustlib,cargo")
1272 .arg("--component-name=clippy-preview");
1273
1274 builder.run(&mut cmd);
1275 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
1276 }
1277 }
1278
1279 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1280 pub struct Rustfmt {
1281 pub stage: u32,
1282 pub target: Interned<String>,
1283 }
1284
1285 impl Step for Rustfmt {
1286 type Output = Option<PathBuf>;
1287 const ONLY_HOSTS: bool = true;
1288
1289 fn should_run(run: ShouldRun) -> ShouldRun {
1290 run.path("rustfmt")
1291 }
1292
1293 fn make_run(run: RunConfig) {
1294 run.builder.ensure(Rustfmt {
1295 stage: run.builder.top_stage,
1296 target: run.target,
1297 });
1298 }
1299
1300 fn run(self, builder: &Builder) -> Option<PathBuf> {
1301 let stage = self.stage;
1302 let target = self.target;
1303
1304 builder.info(&format!("Dist Rustfmt stage{} ({})", stage, target));
1305 let src = builder.src.join("src/tools/rustfmt");
1306 let release_num = builder.release_num("rustfmt");
1307 let name = pkgname(builder, "rustfmt");
1308 let version = builder.rustfmt_info.version(builder, &release_num);
1309
1310 let tmp = tmpdir(builder);
1311 let image = tmp.join("rustfmt-image");
1312 drop(fs::remove_dir_all(&image));
1313 builder.create_dir(&image);
1314
1315 // Prepare the image directory
1316 let rustfmt = builder.ensure(tool::Rustfmt {
1317 compiler: builder.compiler(stage, builder.config.build),
1318 target, extra_features: Vec::new()
1319 }).or_else(|| { println!("Unable to build Rustfmt, skipping dist"); None })?;
1320 let cargofmt = builder.ensure(tool::Cargofmt {
1321 compiler: builder.compiler(stage, builder.config.build),
1322 target, extra_features: Vec::new()
1323 }).or_else(|| { println!("Unable to build Cargofmt, skipping dist"); None })?;
1324
1325 builder.install(&rustfmt, &image.join("bin"), 0o755);
1326 builder.install(&cargofmt, &image.join("bin"), 0o755);
1327 let doc = image.join("share/doc/rustfmt");
1328 builder.install(&src.join("README.md"), &doc, 0o644);
1329 builder.install(&src.join("LICENSE-MIT"), &doc, 0o644);
1330 builder.install(&src.join("LICENSE-APACHE"), &doc, 0o644);
1331
1332 // Prepare the overlay
1333 let overlay = tmp.join("rustfmt-overlay");
1334 drop(fs::remove_dir_all(&overlay));
1335 builder.create_dir(&overlay);
1336 builder.install(&src.join("README.md"), &overlay, 0o644);
1337 builder.install(&src.join("LICENSE-MIT"), &overlay, 0o644);
1338 builder.install(&src.join("LICENSE-APACHE"), &overlay, 0o644);
1339 builder.create(&overlay.join("version"), &version);
1340
1341 // Generate the installer tarball
1342 let mut cmd = rust_installer(builder);
1343 cmd.arg("generate")
1344 .arg("--product-name=Rust")
1345 .arg("--rel-manifest-dir=rustlib")
1346 .arg("--success-message=rustfmt-ready-to-fmt.")
1347 .arg("--image-dir").arg(&image)
1348 .arg("--work-dir").arg(&tmpdir(builder))
1349 .arg("--output-dir").arg(&distdir(builder))
1350 .arg("--non-installed-overlay").arg(&overlay)
1351 .arg(format!("--package-name={}-{}", name, target))
1352 .arg("--legacy-manifest-dirs=rustlib,cargo")
1353 .arg("--component-name=rustfmt-preview");
1354
1355 builder.run(&mut cmd);
1356 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
1357 }
1358 }
1359
1360 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1361 pub struct Extended {
1362 stage: u32,
1363 host: Interned<String>,
1364 target: Interned<String>,
1365 }
1366
1367 impl Step for Extended {
1368 type Output = ();
1369 const DEFAULT: bool = true;
1370 const ONLY_HOSTS: bool = true;
1371
1372 fn should_run(run: ShouldRun) -> ShouldRun {
1373 let builder = run.builder;
1374 run.path("extended").default_condition(builder.config.extended)
1375 }
1376
1377 fn make_run(run: RunConfig) {
1378 run.builder.ensure(Extended {
1379 stage: run.builder.top_stage,
1380 host: run.builder.config.build,
1381 target: run.target,
1382 });
1383 }
1384
1385 /// Creates a combined installer for the specified target in the provided stage.
1386 fn run(self, builder: &Builder) {
1387 let stage = self.stage;
1388 let target = self.target;
1389
1390 builder.info(&format!("Dist extended stage{} ({})", stage, target));
1391
1392 let rustc_installer = builder.ensure(Rustc {
1393 compiler: builder.compiler(stage, target),
1394 });
1395 let cargo_installer = builder.ensure(Cargo { stage, target });
1396 let rustfmt_installer = builder.ensure(Rustfmt { stage, target });
1397 let rls_installer = builder.ensure(Rls { stage, target });
1398 let llvm_tools_installer = builder.ensure(LlvmTools { stage, target });
1399 let clippy_installer = builder.ensure(Clippy { stage, target });
1400 let mingw_installer = builder.ensure(Mingw { host: target });
1401 let analysis_installer = builder.ensure(Analysis {
1402 compiler: builder.compiler(stage, self.host),
1403 target
1404 });
1405
1406 let docs_installer = builder.ensure(Docs { stage, host: target, });
1407 let std_installer = builder.ensure(Std {
1408 compiler: builder.compiler(stage, self.host),
1409 target,
1410 });
1411
1412 let tmp = tmpdir(builder);
1413 let overlay = tmp.join("extended-overlay");
1414 let etc = builder.src.join("src/etc/installer");
1415 let work = tmp.join("work");
1416
1417 let _ = fs::remove_dir_all(&overlay);
1418 builder.install(&builder.src.join("COPYRIGHT"), &overlay, 0o644);
1419 builder.install(&builder.src.join("LICENSE-APACHE"), &overlay, 0o644);
1420 builder.install(&builder.src.join("LICENSE-MIT"), &overlay, 0o644);
1421 let version = builder.rust_version();
1422 builder.create(&overlay.join("version"), &version);
1423 if let Some(sha) = builder.rust_sha() {
1424 builder.create(&overlay.join("git-commit-hash"), &sha);
1425 }
1426 builder.install(&etc.join("README.md"), &overlay, 0o644);
1427
1428 // When rust-std package split from rustc, we needed to ensure that during
1429 // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering
1430 // the std files during uninstall. To do this ensure that rustc comes
1431 // before rust-std in the list below.
1432 let mut tarballs = Vec::new();
1433 tarballs.push(rustc_installer);
1434 tarballs.push(cargo_installer);
1435 tarballs.extend(rls_installer.clone());
1436 tarballs.extend(clippy_installer.clone());
1437 tarballs.extend(rustfmt_installer.clone());
1438 tarballs.extend(llvm_tools_installer.clone());
1439 tarballs.push(analysis_installer);
1440 tarballs.push(std_installer);
1441 if builder.config.docs {
1442 tarballs.push(docs_installer);
1443 }
1444 if target.contains("pc-windows-gnu") {
1445 tarballs.push(mingw_installer.unwrap());
1446 }
1447 let mut input_tarballs = tarballs[0].as_os_str().to_owned();
1448 for tarball in &tarballs[1..] {
1449 input_tarballs.push(",");
1450 input_tarballs.push(tarball);
1451 }
1452
1453 let mut cmd = rust_installer(builder);
1454 cmd.arg("combine")
1455 .arg("--product-name=Rust")
1456 .arg("--rel-manifest-dir=rustlib")
1457 .arg("--success-message=Rust-is-ready-to-roll.")
1458 .arg("--work-dir").arg(&work)
1459 .arg("--output-dir").arg(&distdir(builder))
1460 .arg(format!("--package-name={}-{}", pkgname(builder, "rust"), target))
1461 .arg("--legacy-manifest-dirs=rustlib,cargo")
1462 .arg("--input-tarballs").arg(input_tarballs)
1463 .arg("--non-installed-overlay").arg(&overlay);
1464 builder.run(&mut cmd);
1465
1466 let mut license = String::new();
1467 license += &builder.read(&builder.src.join("COPYRIGHT"));
1468 license += &builder.read(&builder.src.join("LICENSE-APACHE"));
1469 license += &builder.read(&builder.src.join("LICENSE-MIT"));
1470 license.push_str("\n");
1471 license.push_str("\n");
1472
1473 let rtf = r"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Arial;}}\nowwrap\fs18";
1474 let mut rtf = rtf.to_string();
1475 rtf.push_str("\n");
1476 for line in license.lines() {
1477 rtf.push_str(line);
1478 rtf.push_str("\\line ");
1479 }
1480 rtf.push_str("}");
1481
1482 fn filter(contents: &str, marker: &str) -> String {
1483 let start = format!("tool-{}-start", marker);
1484 let end = format!("tool-{}-end", marker);
1485 let mut lines = Vec::new();
1486 let mut omitted = false;
1487 for line in contents.lines() {
1488 if line.contains(&start) {
1489 omitted = true;
1490 } else if line.contains(&end) {
1491 omitted = false;
1492 } else if !omitted {
1493 lines.push(line);
1494 }
1495 }
1496
1497 lines.join("\n")
1498 }
1499
1500 let xform = |p: &Path| {
1501 let mut contents = String::new();
1502 t!(t!(File::open(p)).read_to_string(&mut contents));
1503 if rls_installer.is_none() {
1504 contents = filter(&contents, "rls");
1505 }
1506 if clippy_installer.is_none() {
1507 contents = filter(&contents, "clippy");
1508 }
1509 if rustfmt_installer.is_none() {
1510 contents = filter(&contents, "rustfmt");
1511 }
1512 let ret = tmp.join(p.file_name().unwrap());
1513 t!(t!(File::create(&ret)).write_all(contents.as_bytes()));
1514 return ret
1515 };
1516
1517 if target.contains("apple-darwin") {
1518 let pkg = tmp.join("pkg");
1519 let _ = fs::remove_dir_all(&pkg);
1520
1521 let pkgbuild = |component: &str| {
1522 let mut cmd = Command::new("pkgbuild");
1523 cmd.arg("--identifier").arg(format!("org.rust-lang.{}", component))
1524 .arg("--scripts").arg(pkg.join(component))
1525 .arg("--nopayload")
1526 .arg(pkg.join(component).with_extension("pkg"));
1527 builder.run(&mut cmd);
1528 };
1529
1530 let prepare = |name: &str| {
1531 builder.create_dir(&pkg.join(name));
1532 builder.cp_r(&work.join(&format!("{}-{}", pkgname(builder, name), target)),
1533 &pkg.join(name));
1534 builder.install(&etc.join("pkg/postinstall"), &pkg.join(name), 0o755);
1535 pkgbuild(name);
1536 };
1537 prepare("rustc");
1538 prepare("cargo");
1539 prepare("rust-docs");
1540 prepare("rust-std");
1541 prepare("rust-analysis");
1542
1543 if rls_installer.is_some() {
1544 prepare("rls");
1545 }
1546 if clippy_installer.is_some() {
1547 prepare("clippy");
1548 }
1549
1550 // create an 'uninstall' package
1551 builder.install(&etc.join("pkg/postinstall"), &pkg.join("uninstall"), 0o755);
1552 pkgbuild("uninstall");
1553
1554 builder.create_dir(&pkg.join("res"));
1555 builder.create(&pkg.join("res/LICENSE.txt"), &license);
1556 builder.install(&etc.join("gfx/rust-logo.png"), &pkg.join("res"), 0o644);
1557 let mut cmd = Command::new("productbuild");
1558 cmd.arg("--distribution").arg(xform(&etc.join("pkg/Distribution.xml")))
1559 .arg("--resources").arg(pkg.join("res"))
1560 .arg(distdir(builder).join(format!("{}-{}.pkg",
1561 pkgname(builder, "rust"),
1562 target)))
1563 .arg("--package-path").arg(&pkg);
1564 builder.run(&mut cmd);
1565 }
1566
1567 if target.contains("windows") {
1568 let exe = tmp.join("exe");
1569 let _ = fs::remove_dir_all(&exe);
1570
1571 let prepare = |name: &str| {
1572 builder.create_dir(&exe.join(name));
1573 let dir = if name == "rust-std" || name == "rust-analysis" {
1574 format!("{}-{}", name, target)
1575 } else if name == "rls" {
1576 "rls-preview".to_string()
1577 } else if name == "clippy" {
1578 "clippy-preview".to_string()
1579 } else {
1580 name.to_string()
1581 };
1582 builder.cp_r(&work.join(&format!("{}-{}", pkgname(builder, name), target))
1583 .join(dir),
1584 &exe.join(name));
1585 builder.remove(&exe.join(name).join("manifest.in"));
1586 };
1587 prepare("rustc");
1588 prepare("cargo");
1589 prepare("rust-analysis");
1590 prepare("rust-docs");
1591 prepare("rust-std");
1592 if rls_installer.is_some() {
1593 prepare("rls");
1594 }
1595 if clippy_installer.is_some() {
1596 prepare("clippy");
1597 }
1598 if target.contains("windows-gnu") {
1599 prepare("rust-mingw");
1600 }
1601
1602 builder.install(&xform(&etc.join("exe/rust.iss")), &exe, 0o644);
1603 builder.install(&etc.join("exe/modpath.iss"), &exe, 0o644);
1604 builder.install(&etc.join("exe/upgrade.iss"), &exe, 0o644);
1605 builder.install(&etc.join("gfx/rust-logo.ico"), &exe, 0o644);
1606 builder.create(&exe.join("LICENSE.txt"), &license);
1607
1608 // Generate exe installer
1609 let mut cmd = Command::new("iscc");
1610 cmd.arg("rust.iss")
1611 .current_dir(&exe);
1612 if target.contains("windows-gnu") {
1613 cmd.arg("/dMINGW");
1614 }
1615 add_env(builder, &mut cmd, target);
1616 builder.run(&mut cmd);
1617 builder.install(&exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)),
1618 &distdir(builder),
1619 0o755);
1620
1621 // Generate msi installer
1622 let wix = PathBuf::from(env::var_os("WIX").unwrap());
1623 let heat = wix.join("bin/heat.exe");
1624 let candle = wix.join("bin/candle.exe");
1625 let light = wix.join("bin/light.exe");
1626
1627 let heat_flags = ["-nologo", "-gg", "-sfrag", "-srd", "-sreg"];
1628 builder.run(Command::new(&heat)
1629 .current_dir(&exe)
1630 .arg("dir")
1631 .arg("rustc")
1632 .args(&heat_flags)
1633 .arg("-cg").arg("RustcGroup")
1634 .arg("-dr").arg("Rustc")
1635 .arg("-var").arg("var.RustcDir")
1636 .arg("-out").arg(exe.join("RustcGroup.wxs")));
1637 builder.run(Command::new(&heat)
1638 .current_dir(&exe)
1639 .arg("dir")
1640 .arg("rust-docs")
1641 .args(&heat_flags)
1642 .arg("-cg").arg("DocsGroup")
1643 .arg("-dr").arg("Docs")
1644 .arg("-var").arg("var.DocsDir")
1645 .arg("-out").arg(exe.join("DocsGroup.wxs"))
1646 .arg("-t").arg(etc.join("msi/squash-components.xsl")));
1647 builder.run(Command::new(&heat)
1648 .current_dir(&exe)
1649 .arg("dir")
1650 .arg("cargo")
1651 .args(&heat_flags)
1652 .arg("-cg").arg("CargoGroup")
1653 .arg("-dr").arg("Cargo")
1654 .arg("-var").arg("var.CargoDir")
1655 .arg("-out").arg(exe.join("CargoGroup.wxs"))
1656 .arg("-t").arg(etc.join("msi/remove-duplicates.xsl")));
1657 builder.run(Command::new(&heat)
1658 .current_dir(&exe)
1659 .arg("dir")
1660 .arg("rust-std")
1661 .args(&heat_flags)
1662 .arg("-cg").arg("StdGroup")
1663 .arg("-dr").arg("Std")
1664 .arg("-var").arg("var.StdDir")
1665 .arg("-out").arg(exe.join("StdGroup.wxs")));
1666 if rls_installer.is_some() {
1667 builder.run(Command::new(&heat)
1668 .current_dir(&exe)
1669 .arg("dir")
1670 .arg("rls")
1671 .args(&heat_flags)
1672 .arg("-cg").arg("RlsGroup")
1673 .arg("-dr").arg("Rls")
1674 .arg("-var").arg("var.RlsDir")
1675 .arg("-out").arg(exe.join("RlsGroup.wxs"))
1676 .arg("-t").arg(etc.join("msi/remove-duplicates.xsl")));
1677 }
1678 if clippy_installer.is_some() {
1679 builder.run(Command::new(&heat)
1680 .current_dir(&exe)
1681 .arg("dir")
1682 .arg("clippy")
1683 .args(&heat_flags)
1684 .arg("-cg").arg("ClippyGroup")
1685 .arg("-dr").arg("Clippy")
1686 .arg("-var").arg("var.ClippyDir")
1687 .arg("-out").arg(exe.join("ClippyGroup.wxs"))
1688 .arg("-t").arg(etc.join("msi/remove-duplicates.xsl")));
1689 }
1690 builder.run(Command::new(&heat)
1691 .current_dir(&exe)
1692 .arg("dir")
1693 .arg("rust-analysis")
1694 .args(&heat_flags)
1695 .arg("-cg").arg("AnalysisGroup")
1696 .arg("-dr").arg("Analysis")
1697 .arg("-var").arg("var.AnalysisDir")
1698 .arg("-out").arg(exe.join("AnalysisGroup.wxs"))
1699 .arg("-t").arg(etc.join("msi/remove-duplicates.xsl")));
1700 if target.contains("windows-gnu") {
1701 builder.run(Command::new(&heat)
1702 .current_dir(&exe)
1703 .arg("dir")
1704 .arg("rust-mingw")
1705 .args(&heat_flags)
1706 .arg("-cg").arg("GccGroup")
1707 .arg("-dr").arg("Gcc")
1708 .arg("-var").arg("var.GccDir")
1709 .arg("-out").arg(exe.join("GccGroup.wxs")));
1710 }
1711
1712 let candle = |input: &Path| {
1713 let output = exe.join(input.file_stem().unwrap())
1714 .with_extension("wixobj");
1715 let arch = if target.contains("x86_64") {"x64"} else {"x86"};
1716 let mut cmd = Command::new(&candle);
1717 cmd.current_dir(&exe)
1718 .arg("-nologo")
1719 .arg("-dRustcDir=rustc")
1720 .arg("-dDocsDir=rust-docs")
1721 .arg("-dCargoDir=cargo")
1722 .arg("-dStdDir=rust-std")
1723 .arg("-dAnalysisDir=rust-analysis")
1724 .arg("-arch").arg(&arch)
1725 .arg("-out").arg(&output)
1726 .arg(&input);
1727 add_env(builder, &mut cmd, target);
1728
1729 if rls_installer.is_some() {
1730 cmd.arg("-dRlsDir=rls");
1731 }
1732 if clippy_installer.is_some() {
1733 cmd.arg("-dClippyDir=clippy");
1734 }
1735 if target.contains("windows-gnu") {
1736 cmd.arg("-dGccDir=rust-mingw");
1737 }
1738 builder.run(&mut cmd);
1739 };
1740 candle(&xform(&etc.join("msi/rust.wxs")));
1741 candle(&etc.join("msi/ui.wxs"));
1742 candle(&etc.join("msi/rustwelcomedlg.wxs"));
1743 candle("RustcGroup.wxs".as_ref());
1744 candle("DocsGroup.wxs".as_ref());
1745 candle("CargoGroup.wxs".as_ref());
1746 candle("StdGroup.wxs".as_ref());
1747 if rls_installer.is_some() {
1748 candle("RlsGroup.wxs".as_ref());
1749 }
1750 if clippy_installer.is_some() {
1751 candle("ClippyGroup.wxs".as_ref());
1752 }
1753 candle("AnalysisGroup.wxs".as_ref());
1754
1755 if target.contains("windows-gnu") {
1756 candle("GccGroup.wxs".as_ref());
1757 }
1758
1759 builder.create(&exe.join("LICENSE.rtf"), &rtf);
1760 builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644);
1761 builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644);
1762
1763 let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target);
1764 let mut cmd = Command::new(&light);
1765 cmd.arg("-nologo")
1766 .arg("-ext").arg("WixUIExtension")
1767 .arg("-ext").arg("WixUtilExtension")
1768 .arg("-out").arg(exe.join(&filename))
1769 .arg("rust.wixobj")
1770 .arg("ui.wixobj")
1771 .arg("rustwelcomedlg.wixobj")
1772 .arg("RustcGroup.wixobj")
1773 .arg("DocsGroup.wixobj")
1774 .arg("CargoGroup.wixobj")
1775 .arg("StdGroup.wixobj")
1776 .arg("AnalysisGroup.wixobj")
1777 .current_dir(&exe);
1778
1779 if rls_installer.is_some() {
1780 cmd.arg("RlsGroup.wixobj");
1781 }
1782 if clippy_installer.is_some() {
1783 cmd.arg("ClippyGroup.wixobj");
1784 }
1785
1786 if target.contains("windows-gnu") {
1787 cmd.arg("GccGroup.wixobj");
1788 }
1789 // ICE57 wrongly complains about the shortcuts
1790 cmd.arg("-sice:ICE57");
1791
1792 builder.run(&mut cmd);
1793
1794 if !builder.config.dry_run {
1795 t!(fs::rename(exe.join(&filename), distdir(builder).join(&filename)));
1796 }
1797 }
1798 }
1799 }
1800
1801 fn add_env(builder: &Builder, cmd: &mut Command, target: Interned<String>) {
1802 let mut parts = channel::CFG_RELEASE_NUM.split('.');
1803 cmd.env("CFG_RELEASE_INFO", builder.rust_version())
1804 .env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM)
1805 .env("CFG_RELEASE", builder.rust_release())
1806 .env("CFG_VER_MAJOR", parts.next().unwrap())
1807 .env("CFG_VER_MINOR", parts.next().unwrap())
1808 .env("CFG_VER_PATCH", parts.next().unwrap())
1809 .env("CFG_VER_BUILD", "0") // just needed to build
1810 .env("CFG_PACKAGE_VERS", builder.rust_package_vers())
1811 .env("CFG_PACKAGE_NAME", pkgname(builder, "rust"))
1812 .env("CFG_BUILD", target)
1813 .env("CFG_CHANNEL", &builder.config.channel);
1814
1815 if target.contains("windows-gnu") {
1816 cmd.env("CFG_MINGW", "1")
1817 .env("CFG_ABI", "GNU");
1818 } else {
1819 cmd.env("CFG_MINGW", "0")
1820 .env("CFG_ABI", "MSVC");
1821 }
1822
1823 if target.contains("x86_64") {
1824 cmd.env("CFG_PLATFORM", "x64");
1825 } else {
1826 cmd.env("CFG_PLATFORM", "x86");
1827 }
1828 }
1829
1830 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1831 pub struct HashSign;
1832
1833 impl Step for HashSign {
1834 type Output = ();
1835 const ONLY_HOSTS: bool = true;
1836
1837 fn should_run(run: ShouldRun) -> ShouldRun {
1838 run.path("hash-and-sign")
1839 }
1840
1841 fn make_run(run: RunConfig) {
1842 run.builder.ensure(HashSign);
1843 }
1844
1845 fn run(self, builder: &Builder) {
1846 let mut cmd = builder.tool_cmd(Tool::BuildManifest);
1847 if builder.config.dry_run {
1848 return;
1849 }
1850 let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| {
1851 panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
1852 });
1853 let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
1854 panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
1855 });
1856 let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
1857 panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
1858 });
1859 let mut pass = String::new();
1860 t!(t!(File::open(&file)).read_to_string(&mut pass));
1861
1862 let today = output(Command::new("date").arg("+%Y-%m-%d"));
1863
1864 cmd.arg(sign);
1865 cmd.arg(distdir(builder));
1866 cmd.arg(today.trim());
1867 cmd.arg(builder.rust_package_vers());
1868 cmd.arg(builder.package_vers(&builder.release_num("cargo")));
1869 cmd.arg(builder.package_vers(&builder.release_num("rls")));
1870 cmd.arg(builder.package_vers(&builder.release_num("clippy")));
1871 cmd.arg(builder.package_vers(&builder.release_num("rustfmt")));
1872 cmd.arg(builder.llvm_tools_package_vers());
1873 cmd.arg(addr);
1874
1875 builder.create_dir(&distdir(builder));
1876
1877 let mut child = t!(cmd.stdin(Stdio::piped()).spawn());
1878 t!(child.stdin.take().unwrap().write_all(pass.as_bytes()));
1879 let status = t!(child.wait());
1880 assert!(status.success());
1881 }
1882 }
1883
1884 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
1885 pub struct LlvmTools {
1886 pub stage: u32,
1887 pub target: Interned<String>,
1888 }
1889
1890 impl Step for LlvmTools {
1891 type Output = Option<PathBuf>;
1892 const ONLY_HOSTS: bool = true;
1893
1894 fn should_run(run: ShouldRun) -> ShouldRun {
1895 run.path("llvm-tools")
1896 }
1897
1898 fn make_run(run: RunConfig) {
1899 run.builder.ensure(LlvmTools {
1900 stage: run.builder.top_stage,
1901 target: run.target,
1902 });
1903 }
1904
1905 fn run(self, builder: &Builder) -> Option<PathBuf> {
1906 let stage = self.stage;
1907 let target = self.target;
1908 assert!(builder.config.extended);
1909
1910 /* run only if llvm-config isn't used */
1911 if let Some(config) = builder.config.target_config.get(&target) {
1912 if let Some(ref _s) = config.llvm_config {
1913 builder.info(&format!("Skipping LlvmTools stage{} ({}): external LLVM",
1914 stage, target));
1915 return None;
1916 }
1917 }
1918
1919 builder.info(&format!("Dist LlvmTools stage{} ({})", stage, target));
1920 let src = builder.src.join("src/llvm");
1921 let name = pkgname(builder, "llvm-tools");
1922
1923 let tmp = tmpdir(builder);
1924 let image = tmp.join("llvm-tools-image");
1925 drop(fs::remove_dir_all(&image));
1926
1927 // Prepare the image directory
1928 let bindir = builder
1929 .llvm_out(target)
1930 .join("bin");
1931 let dst = image.join("lib/rustlib")
1932 .join(target)
1933 .join("bin");
1934 t!(fs::create_dir_all(&dst));
1935 for tool in LLVM_TOOLS {
1936 let exe = bindir.join(exe(tool, &target));
1937 builder.install(&exe, &dst, 0o755);
1938 }
1939
1940 // Prepare the overlay
1941 let overlay = tmp.join("llvm-tools-overlay");
1942 drop(fs::remove_dir_all(&overlay));
1943 builder.create_dir(&overlay);
1944 builder.install(&src.join("README.txt"), &overlay, 0o644);
1945 builder.install(&src.join("LICENSE.TXT"), &overlay, 0o644);
1946 builder.create(&overlay.join("version"), &builder.llvm_tools_vers());
1947
1948 // Generate the installer tarball
1949 let mut cmd = rust_installer(builder);
1950 cmd.arg("generate")
1951 .arg("--product-name=Rust")
1952 .arg("--rel-manifest-dir=rustlib")
1953 .arg("--success-message=llvm-tools-installed.")
1954 .arg("--image-dir").arg(&image)
1955 .arg("--work-dir").arg(&tmpdir(builder))
1956 .arg("--output-dir").arg(&distdir(builder))
1957 .arg("--non-installed-overlay").arg(&overlay)
1958 .arg(format!("--package-name={}-{}", name, target))
1959 .arg("--legacy-manifest-dirs=rustlib,cargo")
1960 .arg("--component-name=llvm-tools-preview");
1961
1962
1963 builder.run(&mut cmd);
1964 Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
1965 }
1966 }