1 //! Implementation of the various distribution aspects of the compiler.
3 //! This module is responsible for creating tarballs of the standard library,
4 //! compiler, and documentation. This ends up being what we distribute to
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`!
14 use std
::path
::{Path, PathBuf}
;
15 use std
::process
::{Command, Stdio}
;
17 use build_helper
::{output, t}
;
19 use crate::builder
::{Builder, RunConfig, ShouldRun, Step}
;
20 use crate::cache
::{Interned, INTERNER}
;
22 use crate::config
::TargetSelection
;
23 use crate::tool
::{self, Tool}
;
24 use crate::util
::{exe, is_dylib, timeit}
;
25 use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS}
;
26 use time
::{self, Timespec}
;
28 pub fn pkgname(builder
: &Builder
<'_
>, component
: &str) -> String
{
29 format
!("{}-{}", component
, builder
.rust_package_vers())
32 pub(crate) fn distdir(builder
: &Builder
<'_
>) -> PathBuf
{
33 builder
.out
.join("dist")
36 pub fn tmpdir(builder
: &Builder
<'_
>) -> PathBuf
{
37 builder
.out
.join("tmp/dist")
40 fn rust_installer(builder
: &Builder
<'_
>) -> Command
{
41 builder
.tool_cmd(Tool
::RustInstaller
)
44 fn missing_tool(tool_name
: &str, skip
: bool
) {
46 println
!("Unable to build {}, skipping dist", tool_name
)
48 panic
!("Unable to build {}", tool_name
)
52 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
54 pub host
: TargetSelection
,
58 type Output
= PathBuf
;
59 const DEFAULT
: bool
= true;
61 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
65 fn make_run(run
: RunConfig
<'_
>) {
66 run
.builder
.ensure(Docs { host: run.target }
);
69 /// Builds the `rust-docs` installer component.
70 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
73 let name
= pkgname(builder
, "rust-docs");
75 if !builder
.config
.docs
{
76 return distdir(builder
).join(format
!("{}-{}.tar.gz", name
, host
.triple
));
79 builder
.default_doc(None
);
81 builder
.info(&format
!("Dist docs ({})", host
));
82 let _time
= timeit(builder
);
84 let image
= tmpdir(builder
).join(format
!("{}-{}-image", name
, host
.triple
));
85 let _
= fs
::remove_dir_all(&image
);
87 let dst
= image
.join("share/doc/rust/html");
88 t
!(fs
::create_dir_all(&dst
));
89 let src
= builder
.doc_out(host
);
90 builder
.cp_r(&src
, &dst
);
91 builder
.install(&builder
.src
.join("src/doc/robots.txt"), &dst
, 0o644);
93 let mut cmd
= rust_installer(builder
);
95 .arg("--product-name=Rust-Documentation")
96 .arg("--rel-manifest-dir=rustlib")
97 .arg("--success-message=Rust-documentation-is-installed.")
101 .arg(&tmpdir(builder
))
103 .arg(&distdir(builder
))
104 .arg(format
!("--package-name={}-{}", name
, host
.triple
))
105 .arg("--component-name=rust-docs")
106 .arg("--legacy-manifest-dirs=rustlib,cargo")
107 .arg("--bulk-dirs=share/doc/rust/html");
108 builder
.run(&mut cmd
);
109 builder
.remove_dir(&image
);
111 distdir(builder
).join(format
!("{}-{}.tar.gz", name
, host
.triple
))
115 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
116 pub struct RustcDocs
{
117 pub host
: TargetSelection
,
120 impl Step
for RustcDocs
{
121 type Output
= PathBuf
;
122 const DEFAULT
: bool
= true;
124 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
125 run
.path("src/librustc")
128 fn make_run(run
: RunConfig
<'_
>) {
129 run
.builder
.ensure(RustcDocs { host: run.target }
);
132 /// Builds the `rustc-docs` installer component.
133 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
134 let host
= self.host
;
136 let name
= pkgname(builder
, "rustc-docs");
138 if !builder
.config
.compiler_docs
{
139 return distdir(builder
).join(format
!("{}-{}.tar.gz", name
, host
.triple
));
142 builder
.default_doc(None
);
144 let image
= tmpdir(builder
).join(format
!("{}-{}-image", name
, host
.triple
));
145 let _
= fs
::remove_dir_all(&image
);
147 let dst
= image
.join("share/doc/rust/html/rustc");
148 t
!(fs
::create_dir_all(&dst
));
149 let src
= builder
.compiler_doc_out(host
);
150 builder
.cp_r(&src
, &dst
);
152 let mut cmd
= rust_installer(builder
);
154 .arg("--product-name=Rustc-Documentation")
155 .arg("--rel-manifest-dir=rustlib")
156 .arg("--success-message=Rustc-documentation-is-installed.")
160 .arg(&tmpdir(builder
))
162 .arg(&distdir(builder
))
163 .arg(format
!("--package-name={}-{}", name
, host
.triple
))
164 .arg("--component-name=rustc-docs")
165 .arg("--legacy-manifest-dirs=rustlib,cargo")
166 .arg("--bulk-dirs=share/doc/rust/html/rustc");
168 builder
.info(&format
!("Dist compiler docs ({})", host
));
169 let _time
= timeit(builder
);
170 builder
.run(&mut cmd
);
171 builder
.remove_dir(&image
);
173 distdir(builder
).join(format
!("{}-{}.tar.gz", name
, host
.triple
))
177 fn find_files(files
: &[&str], path
: &[PathBuf
]) -> Vec
<PathBuf
> {
178 let mut found
= Vec
::with_capacity(files
.len());
181 let file_path
= path
.iter().map(|dir
| dir
.join(file
)).find(|p
| p
.exists());
183 if let Some(file_path
) = file_path
{
184 found
.push(file_path
);
186 panic
!("Could not find '{}' in {:?}", file
, path
);
196 target
: TargetSelection
,
197 builder
: &Builder
<'_
>,
199 //Ask gcc where it keeps its stuff
200 let mut cmd
= Command
::new(builder
.cc(target
));
201 cmd
.arg("-print-search-dirs");
202 let gcc_out
= output(&mut cmd
);
204 let mut bin_path
: Vec
<_
> = env
::split_paths(&env
::var_os("PATH").unwrap_or_default()).collect();
205 let mut lib_path
= Vec
::new();
207 for line
in gcc_out
.lines() {
208 let idx
= line
.find('
:'
).unwrap();
209 let key
= &line
[..idx
];
210 let trim_chars
: &[_
] = &[' '
, '
='
];
211 let value
= env
::split_paths(line
[(idx
+ 1)..].trim_start_matches(trim_chars
));
213 if key
== "programs" {
214 bin_path
.extend(value
);
215 } else if key
== "libraries" {
216 lib_path
.extend(value
);
220 let compiler
= if target
== "i686-pc-windows-gnu" {
221 "i686-w64-mingw32-gcc.exe"
222 } else if target
== "x86_64-pc-windows-gnu" {
223 "x86_64-w64-mingw32-gcc.exe"
227 let target_tools
= [compiler
, "ld.exe", "dlltool.exe", "libwinpthread-1.dll"];
228 let mut rustc_dlls
= vec
!["libwinpthread-1.dll"];
229 if target
.starts_with("i686-") {
230 rustc_dlls
.push("libgcc_s_dw2-1.dll");
232 rustc_dlls
.push("libgcc_s_seh-1.dll");
247 //Windows import libs
270 "libsynchronization.a",
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
);
286 // Copy runtime dlls next to rustc.exe
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
{
290 builder
.copy_to_folder(&src
, &dist_bin_dir
);
293 //Copy platform tools to platform-specific bin directory
294 let target_bin_dir
= plat_root
299 .join("self-contained");
300 fs
::create_dir_all(&target_bin_dir
).expect("creating target_bin_dir failed");
301 for src
in target_tools
{
302 builder
.copy_to_folder(&src
, &target_bin_dir
);
305 // Warn windows-gnu users that the bundled GCC cannot compile C files
307 &target_bin_dir
.join("GCC-WARNING.txt"),
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 \
310 the GCC provided by MinGW or Cygwin.",
313 //Copy platform libs to platform-specific lib directory
314 let target_lib_dir
= plat_root
319 .join("self-contained");
320 fs
::create_dir_all(&target_lib_dir
).expect("creating target_lib_dir failed");
321 for src
in target_libs
{
322 builder
.copy_to_folder(&src
, &target_lib_dir
);
326 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
328 pub host
: TargetSelection
,
331 impl Step
for Mingw
{
332 type Output
= Option
<PathBuf
>;
333 const DEFAULT
: bool
= true;
335 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
339 fn make_run(run
: RunConfig
<'_
>) {
340 run
.builder
.ensure(Mingw { host: run.target }
);
343 /// Builds the `rust-mingw` installer component.
345 /// This contains all the bits and pieces to run the MinGW Windows targets
346 /// without any extra installed software (e.g., we bundle gcc, libraries, etc).
347 fn run(self, builder
: &Builder
<'_
>) -> Option
<PathBuf
> {
348 let host
= self.host
;
350 if !host
.contains("pc-windows-gnu") {
354 builder
.info(&format
!("Dist mingw ({})", host
));
355 let _time
= timeit(builder
);
356 let name
= pkgname(builder
, "rust-mingw");
357 let image
= tmpdir(builder
).join(format
!("{}-{}-image", name
, host
.triple
));
358 let _
= fs
::remove_dir_all(&image
);
359 t
!(fs
::create_dir_all(&image
));
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
);
367 let mut cmd
= rust_installer(builder
);
369 .arg("--product-name=Rust-MinGW")
370 .arg("--rel-manifest-dir=rustlib")
371 .arg("--success-message=Rust-MinGW-is-installed.")
375 .arg(&tmpdir(builder
))
377 .arg(&distdir(builder
))
378 .arg(format
!("--package-name={}-{}", name
, host
.triple
))
379 .arg("--component-name=rust-mingw")
380 .arg("--legacy-manifest-dirs=rustlib,cargo");
381 builder
.run(&mut cmd
);
382 t
!(fs
::remove_dir_all(&image
));
383 Some(distdir(builder
).join(format
!("{}-{}.tar.gz", name
, host
.triple
)))
387 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
389 pub compiler
: Compiler
,
392 impl Step
for Rustc
{
393 type Output
= PathBuf
;
394 const DEFAULT
: bool
= true;
395 const ONLY_HOSTS
: bool
= true;
397 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
398 run
.path("src/librustc")
401 fn make_run(run
: RunConfig
<'_
>) {
403 .ensure(Rustc { compiler: run.builder.compiler(run.builder.top_stage, run.target) }
);
406 /// Creates the `rustc` installer component.
407 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
408 let compiler
= self.compiler
;
409 let host
= self.compiler
.host
;
411 let name
= pkgname(builder
, "rustc");
412 let image
= tmpdir(builder
).join(format
!("{}-{}-image", name
, host
.triple
));
413 let _
= fs
::remove_dir_all(&image
);
414 let overlay
= tmpdir(builder
).join(format
!("{}-{}-overlay", name
, host
.triple
));
415 let _
= fs
::remove_dir_all(&overlay
);
417 // Prepare the rustc "image", what will actually end up getting installed
418 prepare_image(builder
, compiler
, &image
);
420 // Prepare the overlay which is part of the tarball but won't actually be
422 let cp
= |file
: &str| {
423 builder
.install(&builder
.src
.join(file
), &overlay
, 0o644);
426 cp("LICENSE-APACHE");
429 // tiny morsel of metadata is used by rust-packaging
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
);
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.
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") {
447 make_win_dist(&image
, &tmpdir(builder
), host
, builder
);
449 let dst
= image
.join("share/doc");
450 t
!(fs
::create_dir_all(&dst
));
451 builder
.cp_r(&builder
.src
.join("src/etc/third-party"), &dst
);
454 // Finally, wrap everything up in a nice tarball!
455 let mut cmd
= rust_installer(builder
);
457 .arg("--product-name=Rust")
458 .arg("--rel-manifest-dir=rustlib")
459 .arg("--success-message=Rust-is-ready-to-roll.")
463 .arg(&tmpdir(builder
))
465 .arg(&distdir(builder
))
466 .arg("--non-installed-overlay")
468 .arg(format
!("--package-name={}-{}", name
, host
.triple
))
469 .arg("--component-name=rustc")
470 .arg("--legacy-manifest-dirs=rustlib,cargo");
472 builder
.info(&format
!("Dist rustc stage{} ({})", compiler
.stage
, host
.triple
));
473 let _time
= timeit(builder
);
474 builder
.run(&mut cmd
);
475 builder
.remove_dir(&image
);
476 builder
.remove_dir(&overlay
);
478 return distdir(builder
).join(format
!("{}-{}.tar.gz", name
, host
.triple
));
480 fn prepare_image(builder
: &Builder
<'_
>, compiler
: Compiler
, image
: &Path
) {
481 let host
= compiler
.host
;
482 let src
= builder
.sysroot(compiler
);
484 // Copy rustc/rustdoc binaries
485 t
!(fs
::create_dir_all(image
.join("bin")));
486 builder
.cp_r(&src
.join("bin"), &image
.join("bin"));
488 builder
.install(&builder
.rustdoc(compiler
), &image
.join("bin"), 0o755);
490 let libdir_relative
= builder
.libdir_relative(compiler
);
492 // Copy runtime DLLs needed by the compiler
493 if libdir_relative
.to_str() != Some("bin") {
494 let libdir
= builder
.rustc_libdir(compiler
);
495 for entry
in builder
.read_dir(&libdir
) {
496 let name
= entry
.file_name();
497 if let Some(s
) = name
.to_str() {
499 // Don't use custom libdir here because ^lib/ will be resolved again
501 builder
.install(&entry
.path(), &image
.join("lib"), 0o644);
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.
512 maybe_install_llvm_runtime(builder
, host
, image
);
514 // Copy over lld if it's there
515 if builder
.config
.lld_enabled
{
516 let exe
= exe("rust-lld", compiler
.host
);
518 builder
.sysroot_libdir(compiler
, host
).parent().unwrap().join("bin").join(&exe
);
519 // for the rationale about this rename check `compile::copy_lld_to_sysroot`
520 let dst
= image
.join("lib/rustlib").join(&*host
.triple
).join("bin").join(&exe
);
521 t
!(fs
::create_dir_all(&dst
.parent().unwrap()));
522 builder
.copy(&src
, &dst
);
526 t
!(fs
::create_dir_all(image
.join("share/man/man1")));
527 let man_src
= builder
.src
.join("src/doc/man");
528 let man_dst
= image
.join("share/man/man1");
530 // Reproducible builds: If SOURCE_DATE_EPOCH is set, use that as the time.
531 let time
= env
::var("SOURCE_DATE_EPOCH")
533 let epoch
= timestamp
535 .map_err(|err
| format
!("could not parse SOURCE_DATE_EPOCH: {}", err
))
538 time
::at(Timespec
::new(epoch
, 0))
540 .unwrap_or_else(|_
| time
::now());
542 let month_year
= t
!(time
::strftime("%B %Y", &time
));
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
545 for file_entry
in builder
.read_dir(&man_src
) {
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
550 builder
.replace_in_file(
553 ("<INSERT DATE HERE>", &month_year
),
554 ("<INSERT VERSION HERE>", &builder
.version
),
561 .ensure(DebuggerScripts { sysroot: INTERNER.intern_path(image.to_owned()), host }
);
564 let cp
= |file
: &str| {
565 builder
.install(&builder
.src
.join(file
), &image
.join("share/doc/rust"), 0o644);
568 cp("LICENSE-APACHE");
575 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
576 pub struct DebuggerScripts
{
577 pub sysroot
: Interned
<PathBuf
>,
578 pub host
: TargetSelection
,
581 impl Step
for DebuggerScripts
{
584 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
585 run
.path("src/lldb_batchmode.py")
588 fn make_run(run
: RunConfig
<'_
>) {
589 run
.builder
.ensure(DebuggerScripts
{
592 .sysroot(run
.builder
.compiler(run
.builder
.top_stage
, run
.build_triple())),
597 /// Copies debugger scripts for `target` into the `sysroot` specified.
598 fn run(self, builder
: &Builder
<'_
>) {
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| {
604 builder
.install(&builder
.src
.join("src/etc/").join(file
), &dst
, 0o644);
606 if host
.contains("windows-msvc") {
607 // windbg debugger scripts
609 &builder
.src
.join("src/etc/rust-windbg.cmd"),
610 &sysroot
.join("bin"),
614 cp_debugger_script("natvis/intrinsic.natvis");
615 cp_debugger_script("natvis/liballoc.natvis");
616 cp_debugger_script("natvis/libcore.natvis");
617 cp_debugger_script("natvis/libstd.natvis");
619 cp_debugger_script("rust_types.py");
621 // gdb debugger scripts
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);
625 cp_debugger_script("gdb_load_rust_pretty_printers.py");
626 cp_debugger_script("gdb_lookup.py");
627 cp_debugger_script("gdb_providers.py");
629 // lldb debugger scripts
630 builder
.install(&builder
.src
.join("src/etc/rust-lldb"), &sysroot
.join("bin"), 0o755);
632 cp_debugger_script("lldb_lookup.py");
633 cp_debugger_script("lldb_providers.py");
634 cp_debugger_script("lldb_commands")
639 fn 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");
650 /// Copy stamped files into an image's `target/lib` directory.
651 fn copy_target_libs(builder
: &Builder
<'_
>, target
: TargetSelection
, image
: &Path
, stamp
: &Path
) {
652 let dst
= image
.join("lib/rustlib").join(target
.triple
).join("lib");
653 let self_contained_dst
= dst
.join("self-contained");
654 t
!(fs
::create_dir_all(&dst
));
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
{
660 builder
.copy(&path
, &dst
.join(path
.file_name().unwrap()));
665 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
667 pub compiler
: Compiler
,
668 pub target
: TargetSelection
,
672 type Output
= PathBuf
;
673 const DEFAULT
: bool
= true;
675 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
676 run
.path("library/std")
679 fn make_run(run
: RunConfig
<'_
>) {
680 run
.builder
.ensure(Std
{
681 compiler
: run
.builder
.compiler_for(
682 run
.builder
.top_stage
,
683 run
.builder
.config
.build
,
690 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
691 let compiler
= self.compiler
;
692 let target
= self.target
;
694 let name
= pkgname(builder
, "rust-std");
695 let archive
= distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
));
696 if skip_host_target_lib(builder
, compiler
) {
700 builder
.ensure(compile
::Std { compiler, target }
);
702 let image
= tmpdir(builder
).join(format
!("{}-{}-image", name
, target
.triple
));
703 let _
= fs
::remove_dir_all(&image
);
705 let compiler_to_use
= builder
.compiler_for(compiler
.stage
, compiler
.host
, target
);
706 let stamp
= compile
::libstd_stamp(builder
, compiler_to_use
, target
);
707 copy_target_libs(builder
, target
, &image
, &stamp
);
709 let mut cmd
= rust_installer(builder
);
711 .arg("--product-name=Rust")
712 .arg("--rel-manifest-dir=rustlib")
713 .arg("--success-message=std-is-standing-at-the-ready.")
717 .arg(&tmpdir(builder
))
719 .arg(&distdir(builder
))
720 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
721 .arg(format
!("--component-name=rust-std-{}", target
.triple
))
722 .arg("--legacy-manifest-dirs=rustlib,cargo");
725 .info(&format
!("Dist std stage{} ({} -> {})", compiler
.stage
, &compiler
.host
, target
));
726 let _time
= timeit(builder
);
727 builder
.run(&mut cmd
);
728 builder
.remove_dir(&image
);
733 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
734 pub struct RustcDev
{
735 pub compiler
: Compiler
,
736 pub target
: TargetSelection
,
739 impl Step
for RustcDev
{
740 type Output
= PathBuf
;
741 const DEFAULT
: bool
= true;
742 const ONLY_HOSTS
: bool
= true;
744 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
745 run
.path("rustc-dev")
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
,
759 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
760 let compiler
= self.compiler
;
761 let target
= self.target
;
763 let name
= pkgname(builder
, "rustc-dev");
764 let archive
= distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
));
765 if skip_host_target_lib(builder
, compiler
) {
769 builder
.ensure(compile
::Rustc { compiler, target }
);
771 let image
= tmpdir(builder
).join(format
!("{}-{}-image", name
, target
.triple
));
772 let _
= fs
::remove_dir_all(&image
);
774 let compiler_to_use
= builder
.compiler_for(compiler
.stage
, compiler
.host
, target
);
775 let stamp
= compile
::librustc_stamp(builder
, compiler_to_use
, target
);
776 copy_target_libs(builder
, target
, &image
, &stamp
);
778 // Copy compiler sources.
779 let dst_src
= image
.join("lib/rustlib/rustc-src/rust");
780 t
!(fs
::create_dir_all(&dst_src
));
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
));
790 let mut cmd
= rust_installer(builder
);
792 .arg("--product-name=Rust")
793 .arg("--rel-manifest-dir=rustlib")
794 .arg("--success-message=Rust-is-ready-to-develop.")
798 .arg(&tmpdir(builder
))
800 .arg(&distdir(builder
))
801 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
802 .arg(format
!("--component-name=rustc-dev-{}", target
.triple
))
803 .arg("--legacy-manifest-dirs=rustlib,cargo");
805 builder
.info(&format
!(
806 "Dist rustc-dev stage{} ({} -> {})",
807 compiler
.stage
, &compiler
.host
, target
809 let _time
= timeit(builder
);
810 builder
.run(&mut cmd
);
811 builder
.remove_dir(&image
);
816 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
817 pub struct Analysis
{
818 pub compiler
: Compiler
,
819 pub target
: TargetSelection
,
822 impl Step
for Analysis
{
823 type Output
= PathBuf
;
824 const DEFAULT
: bool
= true;
826 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
827 let builder
= run
.builder
;
828 run
.path("analysis").default_condition(builder
.config
.extended
)
831 fn make_run(run
: RunConfig
<'_
>) {
832 run
.builder
.ensure(Analysis
{
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
,
845 /// Creates a tarball of save-analysis metadata, if available.
846 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
847 let compiler
= self.compiler
;
848 let target
= self.target
;
849 assert
!(builder
.config
.extended
);
850 let name
= pkgname(builder
, "rust-analysis");
852 if compiler
.host
!= builder
.config
.build
{
853 return distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
));
856 builder
.ensure(compile
::Std { compiler, target }
);
858 let image
= tmpdir(builder
).join(format
!("{}-{}-image", name
, target
.triple
));
861 .stage_out(compiler
, Mode
::Std
)
863 .join(builder
.cargo_dir())
866 let image_src
= src
.join("save-analysis");
867 let dst
= image
.join("lib/rustlib").join(target
.triple
).join("analysis");
868 t
!(fs
::create_dir_all(&dst
));
869 builder
.info(&format
!("image_src: {:?}, dst: {:?}", image_src
, dst
));
870 builder
.cp_r(&image_src
, &dst
);
872 let mut cmd
= rust_installer(builder
);
874 .arg("--product-name=Rust")
875 .arg("--rel-manifest-dir=rustlib")
876 .arg("--success-message=save-analysis-saved.")
880 .arg(&tmpdir(builder
))
882 .arg(&distdir(builder
))
883 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
884 .arg(format
!("--component-name=rust-analysis-{}", target
.triple
))
885 .arg("--legacy-manifest-dirs=rustlib,cargo");
887 builder
.info("Dist analysis");
888 let _time
= timeit(builder
);
889 builder
.run(&mut cmd
);
890 builder
.remove_dir(&image
);
891 distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
))
895 /// Use the `builder` to make a filtered copy of `base`/X for X in (`src_dirs` - `exclude_dirs`) to
898 builder
: &Builder
<'_
>,
901 exclude_dirs
: &[&str],
904 fn filter_fn(exclude_dirs
: &[&str], dir
: &str, path
: &Path
) -> bool
{
905 let spath
= match path
.to_str() {
907 None
=> return false,
909 if spath
.ends_with('
~'
) || spath
.ends_with(".pyc") {
913 const LLVM_PROJECTS
: &[&str] = &[
914 "llvm-project/clang",
915 "llvm-project\\clang",
916 "llvm-project/libunwind",
917 "llvm-project\\libunwind",
921 "llvm-project\\lldb",
923 "llvm-project\\llvm",
924 "llvm-project/compiler-rt",
925 "llvm-project\\compiler-rt",
927 if spath
.contains("llvm-project")
928 && !spath
.ends_with("llvm-project")
929 && !LLVM_PROJECTS
.iter().any(|path
| spath
.contains(path
))
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"))
941 let full_path
= Path
::new(dir
).join(path
);
942 if exclude_dirs
.iter().any(|excl
| full_path
== Path
::new(excl
)) {
969 !path
.iter().map(|s
| s
.to_str().unwrap()).any(|s
| excludes
.contains(&s
))
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
));
976 builder
.cp_filtered(&base
.join(item
), dst
, &|path
| filter_fn(exclude_dirs
, item
, path
));
980 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
984 /// The output path of the src installer tarball
985 type Output
= PathBuf
;
986 const DEFAULT
: bool
= true;
987 const ONLY_HOSTS
: bool
= true;
989 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
993 fn make_run(run
: RunConfig
<'_
>) {
994 run
.builder
.ensure(Src
);
997 /// Creates the `rust-src` installer component
998 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
999 let name
= pkgname(builder
, "rust-src");
1000 let image
= tmpdir(builder
).join(format
!("{}-image", name
));
1001 let _
= fs
::remove_dir_all(&image
);
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
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");
1011 t
!(fs
::create_dir_all(&dst_src
));
1013 let src_files
= ["Cargo.lock"];
1014 // This is the reduced set of paths which will become the rust-src component
1015 // (essentially libstd and all of its path dependencies).
1019 &["library", "src/llvm-project/libunwind"],
1021 // not needed and contains symlinks which rustup currently
1022 // chokes on when unpacking.
1023 "library/backtrace/crates",
1027 for file
in src_files
.iter() {
1028 builder
.copy(&builder
.src
.join(file
), &dst_src
.join(file
));
1031 // Create source tarball in rust-installer format
1032 let mut cmd
= rust_installer(builder
);
1034 .arg("--product-name=Rust")
1035 .arg("--rel-manifest-dir=rustlib")
1036 .arg("--success-message=Awesome-Source.")
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");
1047 builder
.info("Dist src");
1048 let _time
= timeit(builder
);
1049 builder
.run(&mut cmd
);
1051 builder
.remove_dir(&image
);
1052 distdir(builder
).join(&format
!("{}.tar.gz", name
))
1056 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1057 pub struct PlainSourceTarball
;
1059 impl 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;
1065 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1066 let builder
= run
.builder
;
1067 run
.path("src").default_condition(builder
.config
.rust_dist_src
)
1070 fn make_run(run
: RunConfig
<'_
>) {
1071 run
.builder
.ensure(PlainSourceTarball
);
1074 /// Creates the plain source tarball
1075 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
1076 // Make sure that the root folder of tarball has the correct name
1077 let plain_name
= format
!("{}-src", pkgname(builder
, "rustc"));
1078 let plain_dst_src
= tmpdir(builder
).join(&plain_name
);
1079 let _
= fs
::remove_dir_all(&plain_dst_src
);
1080 t
!(fs
::create_dir_all(&plain_dst_src
));
1082 // This is the set of root paths which will become part of the source package
1092 "config.toml.example",
1096 let src_dirs
= ["src", "compiler", "library"];
1098 copy_src_dirs(builder
, &builder
.src
, &src_dirs
, &[], &plain_dst_src
);
1100 // Copy the files normally
1101 for item
in &src_files
{
1102 builder
.copy(&builder
.src
.join(item
), &plain_dst_src
.join(item
));
1105 // Create the version file
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
);
1111 // If we're building from git sources, we need to vendor a complete distribution.
1112 if builder
.rust_info
.is_git() {
1113 // Vendor all Cargo dependencies
1114 let mut cmd
= Command
::new(&builder
.initial_cargo
);
1117 .arg(builder
.src
.join("./src/tools/rust-analyzer/Cargo.toml"))
1118 .current_dir(&plain_dst_src
);
1119 builder
.run(&mut cmd
);
1122 // Create plain source tarball
1123 let plain_name
= format
!("rustc-{}-src", builder
.rust_package_vers());
1124 let mut tarball
= distdir(builder
).join(&format
!("{}.tar.gz", plain_name
));
1125 tarball
.set_extension(""); // strip .gz
1126 tarball
.set_extension(""); // strip .tar
1127 if let Some(dir
) = tarball
.parent() {
1128 builder
.create_dir(&dir
);
1130 builder
.info("running installer");
1131 let mut cmd
= rust_installer(builder
);
1137 .arg("--work-dir=.")
1138 .current_dir(tmpdir(builder
));
1140 builder
.info("Create plain source tarball");
1141 let _time
= timeit(builder
);
1142 builder
.run(&mut cmd
);
1143 distdir(builder
).join(&format
!("{}.tar.gz", plain_name
))
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.
1149 pub fn sanitize_sh(path
: &Path
) -> String
{
1150 let path
= path
.to_str().unwrap().replace("\\", "/");
1151 return change_drive(&path
).unwrap_or(path
);
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('
:'
) {
1159 if ch
.next() != Some('
/'
) {
1162 Some(format
!("/{}/{}", drive
, &s
[drive
.len_utf8() + 2..]))
1166 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1168 pub compiler
: Compiler
,
1169 pub target
: TargetSelection
,
1172 impl Step
for Cargo
{
1173 type Output
= PathBuf
;
1174 const ONLY_HOSTS
: bool
= true;
1176 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1180 fn make_run(run
: RunConfig
<'_
>) {
1181 run
.builder
.ensure(Cargo
{
1182 compiler
: run
.builder
.compiler_for(
1183 run
.builder
.top_stage
,
1184 run
.builder
.config
.build
,
1191 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
1192 let compiler
= self.compiler
;
1193 let target
= self.target
;
1195 let src
= builder
.src
.join("src/tools/cargo");
1196 let etc
= src
.join("src/etc");
1197 let release_num
= builder
.release_num("cargo");
1198 let name
= pkgname(builder
, "cargo");
1199 let version
= builder
.cargo_info
.version(builder
, &release_num
);
1201 let tmp
= tmpdir(builder
);
1202 let image
= tmp
.join("cargo-image");
1203 drop(fs
::remove_dir_all(&image
));
1204 builder
.create_dir(&image
);
1206 // Prepare the image directory
1207 builder
.create_dir(&image
.join("share/zsh/site-functions"));
1208 builder
.create_dir(&image
.join("etc/bash_completion.d"));
1209 let cargo
= builder
.ensure(tool
::Cargo { compiler, target }
);
1210 builder
.install(&cargo
, &image
.join("bin"), 0o755);
1211 for man
in t
!(etc
.join("man").read_dir()) {
1213 builder
.install(&man
.path(), &image
.join("share/man/man1"), 0o644);
1215 builder
.install(&etc
.join("_cargo"), &image
.join("share/zsh/site-functions"), 0o644);
1216 builder
.copy(&etc
.join("cargo.bashcomp.sh"), &image
.join("etc/bash_completion.d/cargo"));
1217 let doc
= image
.join("share/doc/cargo");
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);
1223 // Prepare the overlay
1224 let overlay
= tmp
.join("cargo-overlay");
1225 drop(fs
::remove_dir_all(&overlay
));
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
);
1233 // Generate the installer tarball
1234 let mut cmd
= rust_installer(builder
);
1236 .arg("--product-name=Rust")
1237 .arg("--rel-manifest-dir=rustlib")
1238 .arg("--success-message=Rust-is-ready-to-roll.")
1242 .arg(&tmpdir(builder
))
1243 .arg("--output-dir")
1244 .arg(&distdir(builder
))
1245 .arg("--non-installed-overlay")
1247 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
1248 .arg("--component-name=cargo")
1249 .arg("--legacy-manifest-dirs=rustlib,cargo");
1251 builder
.info(&format
!("Dist cargo stage{} ({})", compiler
.stage
, target
));
1252 let _time
= timeit(builder
);
1253 builder
.run(&mut cmd
);
1254 distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
))
1258 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1260 pub compiler
: Compiler
,
1261 pub target
: TargetSelection
,
1265 type Output
= Option
<PathBuf
>;
1266 const ONLY_HOSTS
: bool
= true;
1268 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1272 fn make_run(run
: RunConfig
<'_
>) {
1273 run
.builder
.ensure(Rls
{
1274 compiler
: run
.builder
.compiler_for(
1275 run
.builder
.top_stage
,
1276 run
.builder
.config
.build
,
1283 fn run(self, builder
: &Builder
<'_
>) -> Option
<PathBuf
> {
1284 let compiler
= self.compiler
;
1285 let target
= self.target
;
1286 assert
!(builder
.config
.extended
);
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
);
1293 let tmp
= tmpdir(builder
);
1294 let image
= tmp
.join("rls-image");
1295 drop(fs
::remove_dir_all(&image
));
1296 t
!(fs
::create_dir_all(&image
));
1298 // Prepare the image directory
1299 // We expect RLS to build, because we've exited this step above if tool
1300 // state for RLS isn't testing.
1302 .ensure(tool
::Rls { compiler, target, extra_features: Vec::new() }
)
1304 missing_tool("RLS", builder
.build
.config
.missing_tools
);
1308 builder
.install(&rls
, &image
.join("bin"), 0o755);
1309 let doc
= image
.join("share/doc/rls");
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);
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
));
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
);
1323 // Generate the installer tarball
1324 let mut cmd
= rust_installer(builder
);
1326 .arg("--product-name=Rust")
1327 .arg("--rel-manifest-dir=rustlib")
1328 .arg("--success-message=RLS-ready-to-serve.")
1332 .arg(&tmpdir(builder
))
1333 .arg("--output-dir")
1334 .arg(&distdir(builder
))
1335 .arg("--non-installed-overlay")
1337 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
1338 .arg("--legacy-manifest-dirs=rustlib,cargo")
1339 .arg("--component-name=rls-preview");
1341 builder
.info(&format
!("Dist RLS stage{} ({})", compiler
.stage
, target
.triple
));
1342 let _time
= timeit(builder
);
1343 builder
.run(&mut cmd
);
1344 Some(distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
)))
1348 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1349 pub struct RustAnalyzer
{
1350 pub compiler
: Compiler
,
1351 pub target
: TargetSelection
,
1354 impl Step
for RustAnalyzer
{
1355 type Output
= Option
<PathBuf
>;
1356 const ONLY_HOSTS
: bool
= true;
1358 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1359 run
.path("rust-analyzer")
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
,
1373 fn run(self, builder
: &Builder
<'_
>) -> Option
<PathBuf
> {
1374 let compiler
= self.compiler
;
1375 let target
= self.target
;
1376 assert
!(builder
.config
.extended
);
1378 if target
.contains("riscv64") {
1379 // riscv64 currently has an LLVM bug that makes rust-analyzer unable
1380 // to build. See #74813 for details.
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
);
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
);
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");
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);
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
);
1416 // Generate the installer tarball
1417 let mut cmd
= rust_installer(builder
);
1419 .arg("--product-name=Rust")
1420 .arg("--rel-manifest-dir=rustlib")
1421 .arg("--success-message=rust-analyzer-ready-to-serve.")
1425 .arg(&tmpdir(builder
))
1426 .arg("--output-dir")
1427 .arg(&distdir(builder
))
1428 .arg("--non-installed-overlay")
1430 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
1431 .arg("--legacy-manifest-dirs=rustlib,cargo")
1432 .arg("--component-name=rust-analyzer-preview");
1434 builder
.info(&format
!("Dist rust-analyzer stage{} ({})", compiler
.stage
, target
));
1435 let _time
= timeit(builder
);
1436 builder
.run(&mut cmd
);
1437 Some(distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
)))
1441 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1443 pub compiler
: Compiler
,
1444 pub target
: TargetSelection
,
1447 impl Step
for Clippy
{
1448 type Output
= PathBuf
;
1449 const ONLY_HOSTS
: bool
= true;
1451 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1455 fn make_run(run
: RunConfig
<'_
>) {
1456 run
.builder
.ensure(Clippy
{
1457 compiler
: run
.builder
.compiler_for(
1458 run
.builder
.top_stage
,
1459 run
.builder
.config
.build
,
1466 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
1467 let compiler
= self.compiler
;
1468 let target
= self.target
;
1469 assert
!(builder
.config
.extended
);
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
);
1476 let tmp
= tmpdir(builder
);
1477 let image
= tmp
.join("clippy-image");
1478 drop(fs
::remove_dir_all(&image
));
1479 builder
.create_dir(&image
);
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.
1484 let clippy
= builder
1485 .ensure(tool
::Clippy { compiler, target, extra_features: Vec::new() }
)
1486 .expect("clippy expected to build - essential tool");
1487 let cargoclippy
= builder
1488 .ensure(tool
::CargoClippy { compiler, target, extra_features: Vec::new() }
)
1489 .expect("clippy expected to build - essential tool");
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);
1495 builder
.install(&src
.join("LICENSE-APACHE"), &doc
, 0o644);
1496 builder
.install(&src
.join("LICENSE-MIT"), &doc
, 0o644);
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);
1503 builder
.install(&src
.join("LICENSE-APACHE"), &doc
, 0o644);
1504 builder
.install(&src
.join("LICENSE-MIT"), &doc
, 0o644);
1505 builder
.create(&overlay
.join("version"), &version
);
1507 // Generate the installer tarball
1508 let mut cmd
= rust_installer(builder
);
1510 .arg("--product-name=Rust")
1511 .arg("--rel-manifest-dir=rustlib")
1512 .arg("--success-message=clippy-ready-to-serve.")
1516 .arg(&tmpdir(builder
))
1517 .arg("--output-dir")
1518 .arg(&distdir(builder
))
1519 .arg("--non-installed-overlay")
1521 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
1522 .arg("--legacy-manifest-dirs=rustlib,cargo")
1523 .arg("--component-name=clippy-preview");
1525 builder
.info(&format
!("Dist clippy stage{} ({})", compiler
.stage
, target
));
1526 let _time
= timeit(builder
);
1527 builder
.run(&mut cmd
);
1528 distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
))
1532 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1534 pub compiler
: Compiler
,
1535 pub target
: TargetSelection
,
1538 impl Step
for Miri
{
1539 type Output
= Option
<PathBuf
>;
1540 const ONLY_HOSTS
: bool
= true;
1542 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1546 fn make_run(run
: RunConfig
<'_
>) {
1547 run
.builder
.ensure(Miri
{
1548 compiler
: run
.builder
.compiler_for(
1549 run
.builder
.top_stage
,
1550 run
.builder
.config
.build
,
1557 fn run(self, builder
: &Builder
<'_
>) -> Option
<PathBuf
> {
1558 let compiler
= self.compiler
;
1559 let target
= self.target
;
1560 assert
!(builder
.config
.extended
);
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
);
1567 let tmp
= tmpdir(builder
);
1568 let image
= tmp
.join("miri-image");
1569 drop(fs
::remove_dir_all(&image
));
1570 builder
.create_dir(&image
);
1572 // Prepare the image directory
1573 // We expect miri to build, because we've exited this step above if tool
1574 // state for miri isn't testing.
1576 .ensure(tool
::Miri { compiler, target, extra_features: Vec::new() }
)
1578 missing_tool("miri", true);
1581 let cargomiri
= builder
1582 .ensure(tool
::CargoMiri { compiler, target, extra_features: Vec::new() }
)
1584 missing_tool("cargo miri", true);
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);
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
);
1604 // Generate the installer tarball
1605 let mut cmd
= rust_installer(builder
);
1607 .arg("--product-name=Rust")
1608 .arg("--rel-manifest-dir=rustlib")
1609 .arg("--success-message=miri-ready-to-serve.")
1613 .arg(&tmpdir(builder
))
1614 .arg("--output-dir")
1615 .arg(&distdir(builder
))
1616 .arg("--non-installed-overlay")
1618 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
1619 .arg("--legacy-manifest-dirs=rustlib,cargo")
1620 .arg("--component-name=miri-preview");
1622 builder
.info(&format
!("Dist miri stage{} ({})", compiler
.stage
, target
));
1623 let _time
= timeit(builder
);
1624 builder
.run(&mut cmd
);
1625 Some(distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
)))
1629 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1630 pub struct Rustfmt
{
1631 pub compiler
: Compiler
,
1632 pub target
: TargetSelection
,
1635 impl Step
for Rustfmt
{
1636 type Output
= Option
<PathBuf
>;
1637 const ONLY_HOSTS
: bool
= true;
1639 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1643 fn make_run(run
: RunConfig
<'_
>) {
1644 run
.builder
.ensure(Rustfmt
{
1645 compiler
: run
.builder
.compiler_for(
1646 run
.builder
.top_stage
,
1647 run
.builder
.config
.build
,
1654 fn run(self, builder
: &Builder
<'_
>) -> Option
<PathBuf
> {
1655 let compiler
= self.compiler
;
1656 let target
= self.target
;
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
);
1663 let tmp
= tmpdir(builder
);
1664 let image
= tmp
.join("rustfmt-image");
1665 drop(fs
::remove_dir_all(&image
));
1666 builder
.create_dir(&image
);
1668 // Prepare the image directory
1669 let rustfmt
= builder
1670 .ensure(tool
::Rustfmt { compiler, target, extra_features: Vec::new() }
)
1672 missing_tool("Rustfmt", builder
.build
.config
.missing_tools
);
1675 let cargofmt
= builder
1676 .ensure(tool
::Cargofmt { compiler, target, extra_features: Vec::new() }
)
1678 missing_tool("Cargofmt", builder
.build
.config
.missing_tools
);
1682 builder
.install(&rustfmt
, &image
.join("bin"), 0o755);
1683 builder
.install(&cargofmt
, &image
.join("bin"), 0o755);
1684 let doc
= image
.join("share/doc/rustfmt");
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);
1689 // Prepare the overlay
1690 let overlay
= tmp
.join("rustfmt-overlay");
1691 drop(fs
::remove_dir_all(&overlay
));
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
);
1698 // Generate the installer tarball
1699 let mut cmd
= rust_installer(builder
);
1701 .arg("--product-name=Rust")
1702 .arg("--rel-manifest-dir=rustlib")
1703 .arg("--success-message=rustfmt-ready-to-fmt.")
1707 .arg(&tmpdir(builder
))
1708 .arg("--output-dir")
1709 .arg(&distdir(builder
))
1710 .arg("--non-installed-overlay")
1712 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
1713 .arg("--legacy-manifest-dirs=rustlib,cargo")
1714 .arg("--component-name=rustfmt-preview");
1716 builder
.info(&format
!("Dist Rustfmt stage{} ({})", compiler
.stage
, target
));
1717 let _time
= timeit(builder
);
1718 builder
.run(&mut cmd
);
1719 Some(distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
)))
1723 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
1724 pub struct Extended
{
1726 host
: TargetSelection
,
1727 target
: TargetSelection
,
1730 impl Step
for Extended
{
1732 const DEFAULT
: bool
= true;
1733 const ONLY_HOSTS
: bool
= true;
1735 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
1736 let builder
= run
.builder
;
1737 run
.path("extended").default_condition(builder
.config
.extended
)
1740 fn make_run(run
: RunConfig
<'_
>) {
1741 run
.builder
.ensure(Extended
{
1742 stage
: run
.builder
.top_stage
,
1743 host
: run
.builder
.config
.build
,
1748 /// Creates a combined installer for the specified target in the provided stage.
1749 fn run(self, builder
: &Builder
<'_
>) {
1750 let target
= self.target
;
1751 let stage
= self.stage
;
1752 let compiler
= builder
.compiler_for(self.stage
, self.host
, self.target
);
1754 builder
.info(&format
!("Dist extended stage{} ({})", compiler
.stage
, target
));
1756 let rustc_installer
= builder
.ensure(Rustc { compiler: builder.compiler(stage, target) }
);
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 }
);
1760 let rust_analyzer_installer
= builder
.ensure(RustAnalyzer { compiler, target }
);
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 }
);
1764 let mingw_installer
= builder
.ensure(Mingw { host: target }
);
1765 let analysis_installer
= builder
.ensure(Analysis { compiler, target }
);
1767 let docs_installer
= builder
.ensure(Docs { host: target }
);
1769 builder
.ensure(Std { compiler: builder.compiler(stage, target), target }
);
1771 let tmp
= tmpdir(builder
);
1772 let overlay
= tmp
.join("extended-overlay");
1773 let etc
= builder
.src
.join("src/etc/installer");
1774 let work
= tmp
.join("work");
1776 let _
= fs
::remove_dir_all(&overlay
);
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
);
1785 builder
.install(&etc
.join("README.md"), &overlay
, 0o644);
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.
1791 let mut tarballs
= Vec
::new();
1792 tarballs
.push(rustc_installer
);
1793 tarballs
.push(cargo_installer
);
1794 tarballs
.extend(rls_installer
.clone());
1795 tarballs
.extend(rust_analyzer_installer
.clone());
1796 tarballs
.push(clippy_installer
);
1797 tarballs
.extend(miri_installer
.clone());
1798 tarballs
.extend(rustfmt_installer
.clone());
1799 tarballs
.extend(llvm_tools_installer
);
1800 tarballs
.push(analysis_installer
);
1801 tarballs
.push(std_installer
);
1802 if builder
.config
.docs
{
1803 tarballs
.push(docs_installer
);
1805 if target
.contains("pc-windows-gnu") {
1806 tarballs
.push(mingw_installer
.unwrap());
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
);
1814 builder
.info("building combined installer");
1815 let mut cmd
= rust_installer(builder
);
1817 .arg("--product-name=Rust")
1818 .arg("--rel-manifest-dir=rustlib")
1819 .arg("--success-message=Rust-is-ready-to-roll.")
1822 .arg("--output-dir")
1823 .arg(&distdir(builder
))
1824 .arg(format
!("--package-name={}-{}", pkgname(builder
, "rust"), target
.triple
))
1825 .arg("--legacy-manifest-dirs=rustlib,cargo")
1826 .arg("--input-tarballs")
1827 .arg(input_tarballs
)
1828 .arg("--non-installed-overlay")
1830 let time
= timeit(&builder
);
1831 builder
.run(&mut cmd
);
1834 let mut license
= String
::new();
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"));
1838 license
.push_str("\n");
1839 license
.push_str("\n");
1841 let rtf
= r
"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil\fcharset0 Arial;}}\nowwrap\fs18";
1842 let mut rtf
= rtf
.to_string();
1844 for line
in license
.lines() {
1846 rtf
.push_str("\\line ");
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
) {
1858 } else if line
.contains(&end
) {
1860 } else if !omitted
{
1868 let xform
= |p
: &Path
| {
1869 let mut contents
= t
!(fs
::read_to_string(p
));
1870 if rls_installer
.is_none() {
1871 contents
= filter(&contents
, "rls");
1873 if rust_analyzer_installer
.is_none() {
1874 contents
= filter(&contents
, "rust-analyzer");
1876 if miri_installer
.is_none() {
1877 contents
= filter(&contents
, "miri");
1879 if rustfmt_installer
.is_none() {
1880 contents
= filter(&contents
, "rustfmt");
1882 let ret
= tmp
.join(p
.file_name().unwrap());
1883 t
!(fs
::write(&ret
, &contents
));
1887 if target
.contains("apple-darwin") {
1888 builder
.info("building pkg installer");
1889 let pkg
= tmp
.join("pkg");
1890 let _
= fs
::remove_dir_all(&pkg
);
1892 let pkgbuild
= |component
: &str| {
1893 let mut cmd
= Command
::new("pkgbuild");
1894 cmd
.arg("--identifier")
1895 .arg(format
!("org.rust-lang.{}", component
))
1897 .arg(pkg
.join(component
))
1899 .arg(pkg
.join(component
).with_extension("pkg"));
1900 builder
.run(&mut cmd
);
1903 let prepare
= |name
: &str| {
1904 builder
.create_dir(&pkg
.join(name
));
1906 &work
.join(&format
!("{}-{}", pkgname(builder
, name
), target
.triple
)),
1909 builder
.install(&etc
.join("pkg/postinstall"), &pkg
.join(name
), 0o755);
1914 prepare("rust-docs");
1915 prepare("rust-std");
1916 prepare("rust-analysis");
1919 if rls_installer
.is_some() {
1922 if rust_analyzer_installer
.is_some() {
1923 prepare("rust-analyzer");
1925 if miri_installer
.is_some() {
1929 // create an 'uninstall' package
1930 builder
.install(&etc
.join("pkg/postinstall"), &pkg
.join("uninstall"), 0o755);
1931 pkgbuild("uninstall");
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);
1936 let mut cmd
= Command
::new("productbuild");
1937 cmd
.arg("--distribution")
1938 .arg(xform(&etc
.join("pkg/Distribution.xml")))
1940 .arg(pkg
.join("res"))
1941 .arg(distdir(builder
).join(format
!(
1943 pkgname(builder
, "rust"),
1946 .arg("--package-path")
1948 let _time
= timeit(builder
);
1949 builder
.run(&mut cmd
);
1952 if target
.contains("windows") {
1953 let exe
= tmp
.join("exe");
1954 let _
= fs
::remove_dir_all(&exe
);
1956 let prepare
= |name
: &str| {
1957 builder
.create_dir(&exe
.join(name
));
1958 let dir
= if name
== "rust-std" || name
== "rust-analysis" {
1959 format
!("{}-{}", name
, target
.triple
)
1960 } else if name
== "rls" {
1961 "rls-preview".to_string()
1962 } else if name
== "rust-analyzer" {
1963 "rust-analyzer-preview".to_string()
1964 } else if name
== "clippy" {
1965 "clippy-preview".to_string()
1966 } else if name
== "miri" {
1967 "miri-preview".to_string()
1972 &work
.join(&format
!("{}-{}", pkgname(builder
, name
), target
.triple
)).join(dir
),
1975 builder
.remove(&exe
.join(name
).join("manifest.in"));
1979 prepare("rust-analysis");
1980 prepare("rust-docs");
1981 prepare("rust-std");
1983 if rls_installer
.is_some() {
1986 if rust_analyzer_installer
.is_some() {
1987 prepare("rust-analyzer");
1989 if miri_installer
.is_some() {
1992 if target
.contains("windows-gnu") {
1993 prepare("rust-mingw");
1996 builder
.install(&etc
.join("gfx/rust-logo.ico"), &exe
, 0o644);
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");
2004 let heat_flags
= ["-nologo", "-gg", "-sfrag", "-srd", "-sreg"];
2016 .arg("var.RustcDir")
2018 .arg(exe
.join("RustcGroup.wxs")),
2033 .arg(exe
.join("DocsGroup.wxs"))
2035 .arg(etc
.join("msi/squash-components.xsl")),
2048 .arg("var.CargoDir")
2050 .arg(exe
.join("CargoGroup.wxs"))
2052 .arg(etc
.join("msi/remove-duplicates.xsl")),
2067 .arg(exe
.join("StdGroup.wxs")),
2069 if rls_installer
.is_some() {
2083 .arg(exe
.join("RlsGroup.wxs"))
2085 .arg(etc
.join("msi/remove-duplicates.xsl")),
2088 if rust_analyzer_installer
.is_some() {
2093 .arg("rust-analyzer")
2096 .arg("RustAnalyzerGroup")
2098 .arg("RustAnalyzer")
2100 .arg("var.RustAnalyzerDir")
2102 .arg(exe
.join("RustAnalyzerGroup.wxs"))
2104 .arg(etc
.join("msi/remove-duplicates.xsl")),
2118 .arg("var.ClippyDir")
2120 .arg(exe
.join("ClippyGroup.wxs"))
2122 .arg(etc
.join("msi/remove-duplicates.xsl")),
2124 if miri_installer
.is_some() {
2138 .arg(exe
.join("MiriGroup.wxs"))
2140 .arg(etc
.join("msi/remove-duplicates.xsl")),
2147 .arg("rust-analysis")
2150 .arg("AnalysisGroup")
2154 .arg("var.AnalysisDir")
2156 .arg(exe
.join("AnalysisGroup.wxs"))
2158 .arg(etc
.join("msi/remove-duplicates.xsl")),
2160 if target
.contains("windows-gnu") {
2174 .arg(exe
.join("GccGroup.wxs")),
2178 let candle
= |input
: &Path
| {
2179 let output
= exe
.join(input
.file_stem().unwrap()).with_extension("wixobj");
2180 let arch
= if target
.contains("x86_64") { "x64" }
else { "x86" }
;
2181 let mut cmd
= Command
::new(&candle
);
2182 cmd
.current_dir(&exe
)
2184 .arg("-dRustcDir=rustc")
2185 .arg("-dDocsDir=rust-docs")
2186 .arg("-dCargoDir=cargo")
2187 .arg("-dStdDir=rust-std")
2188 .arg("-dAnalysisDir=rust-analysis")
2189 .arg("-dClippyDir=clippy")
2195 add_env(builder
, &mut cmd
, target
);
2197 if rls_installer
.is_some() {
2198 cmd
.arg("-dRlsDir=rls");
2200 if rust_analyzer_installer
.is_some() {
2201 cmd
.arg("-dRustAnalyzerDir=rust-analyzer");
2203 if miri_installer
.is_some() {
2204 cmd
.arg("-dMiriDir=miri");
2206 if target
.contains("windows-gnu") {
2207 cmd
.arg("-dGccDir=rust-mingw");
2209 builder
.run(&mut cmd
);
2211 candle(&xform(&etc
.join("msi/rust.wxs")));
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());
2218 candle("ClippyGroup.wxs".as_ref());
2219 if rls_installer
.is_some() {
2220 candle("RlsGroup.wxs".as_ref());
2222 if rust_analyzer_installer
.is_some() {
2223 candle("RustAnalyzerGroup.wxs".as_ref());
2225 if miri_installer
.is_some() {
2226 candle("MiriGroup.wxs".as_ref());
2228 candle("AnalysisGroup.wxs".as_ref());
2230 if target
.contains("windows-gnu") {
2231 candle("GccGroup.wxs".as_ref());
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);
2238 builder
.info(&format
!("building `msi` installer with {:?}", light
));
2239 let filename
= format
!("{}-{}.msi", pkgname(builder
, "rust"), target
.triple
);
2240 let mut cmd
= Command
::new(&light
);
2243 .arg("WixUIExtension")
2245 .arg("WixUtilExtension")
2247 .arg(exe
.join(&filename
))
2250 .arg("rustwelcomedlg.wixobj")
2251 .arg("RustcGroup.wixobj")
2252 .arg("DocsGroup.wixobj")
2253 .arg("CargoGroup.wixobj")
2254 .arg("StdGroup.wixobj")
2255 .arg("AnalysisGroup.wixobj")
2256 .arg("ClippyGroup.wixobj")
2259 if rls_installer
.is_some() {
2260 cmd
.arg("RlsGroup.wixobj");
2262 if rust_analyzer_installer
.is_some() {
2263 cmd
.arg("RustAnalyzerGroup.wixobj");
2265 if miri_installer
.is_some() {
2266 cmd
.arg("MiriGroup.wixobj");
2269 if target
.contains("windows-gnu") {
2270 cmd
.arg("GccGroup.wixobj");
2272 // ICE57 wrongly complains about the shortcuts
2273 cmd
.arg("-sice:ICE57");
2275 let _time
= timeit(builder
);
2276 builder
.run(&mut cmd
);
2278 if !builder
.config
.dry_run
{
2279 t
!(fs
::rename(exe
.join(&filename
), distdir(builder
).join(&filename
)));
2285 fn add_env(builder
: &Builder
<'_
>, cmd
: &mut Command
, target
: TargetSelection
) {
2286 let mut parts
= builder
.version
.split('
.'
);
2287 cmd
.env("CFG_RELEASE_INFO", builder
.rust_version())
2288 .env("CFG_RELEASE_NUM", &builder
.version
)
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"))
2296 .env("CFG_BUILD", target
.triple
)
2297 .env("CFG_CHANNEL", &builder
.config
.channel
);
2299 if target
.contains("windows-gnu") {
2300 cmd
.env("CFG_MINGW", "1").env("CFG_ABI", "GNU");
2302 cmd
.env("CFG_MINGW", "0").env("CFG_ABI", "MSVC");
2305 if target
.contains("x86_64") {
2306 cmd
.env("CFG_PLATFORM", "x64");
2308 cmd
.env("CFG_PLATFORM", "x86");
2312 #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
2313 pub struct HashSign
;
2315 impl Step
for HashSign
{
2317 const ONLY_HOSTS
: bool
= true;
2319 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2320 run
.path("hash-and-sign")
2323 fn make_run(run
: RunConfig
<'_
>) {
2324 run
.builder
.ensure(HashSign
);
2327 fn run(self, builder
: &Builder
<'_
>) {
2328 // This gets called by `promote-release`
2329 // (https://github.com/rust-lang/rust-central-station/tree/master/promote-release).
2330 let mut cmd
= builder
.tool_cmd(Tool
::BuildManifest
);
2331 if builder
.config
.dry_run
{
2334 let sign
= builder
.config
.dist_sign_folder
.as_ref().unwrap_or_else(|| {
2335 panic
!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
2337 let addr
= builder
.config
.dist_upload_addr
.as_ref().unwrap_or_else(|| {
2338 panic
!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
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")
2344 t
!(fs
::read_to_string(&file
))
2349 let today
= output(Command
::new("date").arg("+%Y-%m-%d"));
2352 cmd
.arg(distdir(builder
));
2353 cmd
.arg(today
.trim());
2355 cmd
.arg(&builder
.config
.channel
);
2356 cmd
.env("BUILD_MANIFEST_LEGACY", "1");
2358 builder
.create_dir(&distdir(builder
));
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());
2367 /// Maybe add libLLVM.so to the given destination lib-dir. It will only have
2368 /// been built if LLVM tools are linked dynamically.
2370 /// Note: This function does not yet support Windows, but we also don't support
2371 /// linking LLVM tools dynamically on Windows yet.
2372 fn maybe_install_llvm(builder
: &Builder
<'_
>, target
: TargetSelection
, dst_libdir
: &Path
) {
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
2380 if let Some(config
) = builder
.config
.target_config
.get(&target
) {
2381 if config
.llvm_config
.is_some() && !builder
.config
.llvm_from_ci
{
2382 // If the LLVM was externally provided, then we don't currently copy
2383 // artifacts into the sysroot. This is not necessarily the right
2384 // choice (in particular, it will require the LLVM dylib to be in
2385 // the linker's load path at runtime), but the common use case for
2386 // external LLVMs is distribution provided LLVMs, and in that case
2387 // they're usually in the standard search path (e.g., /usr/lib) and
2388 // copying them here is going to cause problems as we may end up
2389 // with the wrong files and isn't what distributions want.
2391 // This behavior may be revisited in the future though.
2393 // If the LLVM is coming from ourselves (just from CI) though, we
2394 // still want to install it, as it otherwise won't be available.
2399 // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib
2400 // instead of libLLVM-11-rust-....dylib, as on linux. It's not entirely
2401 // clear why this is the case, though. llvm-config will emit the versioned
2402 // paths and we don't want those in the sysroot (as we're expecting
2403 // unversioned paths).
2404 if target
.contains("apple-darwin") {
2405 let src_libdir
= builder
.llvm_out(target
).join("lib");
2406 let llvm_dylib_path
= src_libdir
.join("libLLVM.dylib");
2407 if llvm_dylib_path
.exists() {
2408 builder
.install(&llvm_dylib_path
, dst_libdir
, 0o644);
2410 } else if let Ok(llvm_config
) = crate::native
::prebuilt_llvm_config(builder
, target
) {
2411 let files
= output(Command
::new(llvm_config
).arg("--libfiles"));
2412 for file
in files
.lines() {
2413 builder
.install(Path
::new(file
), dst_libdir
, 0o644);
2418 /// Maybe add libLLVM.so to the target lib-dir for linking.
2419 pub fn maybe_install_llvm_target(builder
: &Builder
<'_
>, target
: TargetSelection
, sysroot
: &Path
) {
2420 let dst_libdir
= sysroot
.join("lib/rustlib").join(&*target
.triple
).join("lib");
2421 maybe_install_llvm(builder
, target
, &dst_libdir
);
2424 /// Maybe add libLLVM.so to the runtime lib-dir for rustc itself.
2425 pub fn maybe_install_llvm_runtime(builder
: &Builder
<'_
>, target
: TargetSelection
, sysroot
: &Path
) {
2427 sysroot
.join(builder
.sysroot_libdir_relative(Compiler { stage: 1, host: target }
));
2428 maybe_install_llvm(builder
, target
, &dst_libdir
);
2431 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
2432 pub struct LlvmTools
{
2433 pub target
: TargetSelection
,
2436 impl Step
for LlvmTools
{
2437 type Output
= Option
<PathBuf
>;
2438 const ONLY_HOSTS
: bool
= true;
2440 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2441 run
.path("llvm-tools")
2444 fn make_run(run
: RunConfig
<'_
>) {
2445 run
.builder
.ensure(LlvmTools { target: run.target }
);
2448 fn run(self, builder
: &Builder
<'_
>) -> Option
<PathBuf
> {
2449 let target
= self.target
;
2450 assert
!(builder
.config
.extended
);
2452 /* run only if llvm-config isn't used */
2453 if let Some(config
) = builder
.config
.target_config
.get(&target
) {
2454 if let Some(ref _s
) = config
.llvm_config
{
2455 builder
.info(&format
!("Skipping LlvmTools ({}): external LLVM", target
));
2460 builder
.info(&format
!("Dist LlvmTools ({})", target
));
2461 let _time
= timeit(builder
);
2462 let src
= builder
.src
.join("src/llvm-project/llvm");
2463 let name
= pkgname(builder
, "llvm-tools");
2465 let tmp
= tmpdir(builder
);
2466 let image
= tmp
.join("llvm-tools-image");
2467 drop(fs
::remove_dir_all(&image
));
2469 // Prepare the image directory
2470 let src_bindir
= builder
.llvm_out(target
).join("bin");
2471 let dst_bindir
= image
.join("lib/rustlib").join(&*target
.triple
).join("bin");
2472 t
!(fs
::create_dir_all(&dst_bindir
));
2473 for tool
in LLVM_TOOLS
{
2474 let exe
= src_bindir
.join(exe(tool
, target
));
2475 builder
.install(&exe
, &dst_bindir
, 0o755);
2478 // Copy libLLVM.so to the target lib dir as well, so the RPATH like
2479 // `$ORIGIN/../lib` can find it. It may also be used as a dependency
2480 // of `rustc-dev` to support the inherited `-lLLVM` when using the
2481 // compiler libraries.
2482 maybe_install_llvm_target(builder
, target
, &image
);
2484 // Prepare the overlay
2485 let overlay
= tmp
.join("llvm-tools-overlay");
2486 drop(fs
::remove_dir_all(&overlay
));
2487 builder
.create_dir(&overlay
);
2488 builder
.install(&src
.join("README.txt"), &overlay
, 0o644);
2489 builder
.install(&src
.join("LICENSE.TXT"), &overlay
, 0o644);
2490 builder
.create(&overlay
.join("version"), &builder
.llvm_tools_vers());
2492 // Generate the installer tarball
2493 let mut cmd
= rust_installer(builder
);
2495 .arg("--product-name=Rust")
2496 .arg("--rel-manifest-dir=rustlib")
2497 .arg("--success-message=llvm-tools-installed.")
2501 .arg(&tmpdir(builder
))
2502 .arg("--output-dir")
2503 .arg(&distdir(builder
))
2504 .arg("--non-installed-overlay")
2506 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
2507 .arg("--legacy-manifest-dirs=rustlib,cargo")
2508 .arg("--component-name=llvm-tools-preview");
2510 builder
.run(&mut cmd
);
2511 Some(distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
)))
2515 // Tarball intended for internal consumption to ease rustc/std development.
2517 // Should not be considered stable by end users.
2518 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
2519 pub struct RustDev
{
2520 pub target
: TargetSelection
,
2523 impl Step
for RustDev
{
2524 type Output
= Option
<PathBuf
>;
2525 const DEFAULT
: bool
= true;
2526 const ONLY_HOSTS
: bool
= true;
2528 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2529 run
.path("rust-dev")
2532 fn make_run(run
: RunConfig
<'_
>) {
2533 run
.builder
.ensure(RustDev { target: run.target }
);
2536 fn run(self, builder
: &Builder
<'_
>) -> Option
<PathBuf
> {
2537 let target
= self.target
;
2539 /* run only if llvm-config isn't used */
2540 if let Some(config
) = builder
.config
.target_config
.get(&target
) {
2541 if let Some(ref _s
) = config
.llvm_config
{
2542 builder
.info(&format
!("Skipping RustDev ({}): external LLVM", target
));
2547 builder
.info(&format
!("Dist RustDev ({})", target
));
2548 let _time
= timeit(builder
);
2549 let src
= builder
.src
.join("src/llvm-project/llvm");
2550 let name
= pkgname(builder
, "rust-dev");
2552 let tmp
= tmpdir(builder
);
2553 let image
= tmp
.join("rust-dev-image");
2554 drop(fs
::remove_dir_all(&image
));
2556 // Prepare the image directory
2557 let dst_bindir
= image
.join("bin");
2558 t
!(fs
::create_dir_all(&dst_bindir
));
2560 let exe
= builder
.llvm_out(target
).join("bin").join(exe("llvm-config", target
));
2561 builder
.install(&exe
, &dst_bindir
, 0o755);
2562 builder
.install(&builder
.llvm_filecheck(target
), &dst_bindir
, 0o755);
2564 // Copy the include directory as well; needed mostly to build
2565 // librustc_llvm properly (e.g., llvm-config.h is in here). But also
2566 // just broadly useful to be able to link against the bundled LLVM.
2567 builder
.cp_r(&builder
.llvm_out(target
).join("include"), &image
.join("include"));
2569 // Copy libLLVM.so to the target lib dir as well, so the RPATH like
2570 // `$ORIGIN/../lib` can find it. It may also be used as a dependency
2571 // of `rustc-dev` to support the inherited `-lLLVM` when using the
2572 // compiler libraries.
2573 maybe_install_llvm(builder
, target
, &image
.join("lib"));
2575 // Prepare the overlay
2576 let overlay
= tmp
.join("rust-dev-overlay");
2577 drop(fs
::remove_dir_all(&overlay
));
2578 builder
.create_dir(&overlay
);
2579 builder
.install(&src
.join("README.txt"), &overlay
, 0o644);
2580 builder
.install(&src
.join("LICENSE.TXT"), &overlay
, 0o644);
2581 builder
.create(&overlay
.join("version"), &builder
.rust_version());
2583 // Generate the installer tarball
2584 let mut cmd
= rust_installer(builder
);
2586 .arg("--product-name=Rust")
2587 .arg("--rel-manifest-dir=rustlib")
2588 .arg("--success-message=rust-dev-installed.")
2592 .arg(&tmpdir(builder
))
2593 .arg("--output-dir")
2594 .arg(&distdir(builder
))
2595 .arg("--non-installed-overlay")
2597 .arg(format
!("--package-name={}-{}", name
, target
.triple
))
2598 .arg("--legacy-manifest-dirs=rustlib,cargo")
2599 .arg("--component-name=rust-dev");
2601 builder
.run(&mut cmd
);
2602 Some(distdir(builder
).join(format
!("{}-{}.tar.gz", name
, target
.triple
)))
2606 /// Tarball containing a prebuilt version of the build-manifest tool, intented to be used by the
2607 /// release process to avoid cloning the monorepo and building stuff.
2609 /// Should not be considered stable by end users.
2610 #[derive(Clone, Debug, Eq, Hash, PartialEq)]
2611 pub struct BuildManifest
{
2612 pub target
: TargetSelection
,
2615 impl Step
for BuildManifest
{
2616 type Output
= PathBuf
;
2617 const DEFAULT
: bool
= false;
2618 const ONLY_HOSTS
: bool
= true;
2620 fn should_run(run
: ShouldRun
<'_
>) -> ShouldRun
<'_
> {
2621 run
.path("src/tools/build-manifest")
2624 fn make_run(run
: RunConfig
<'_
>) {
2625 run
.builder
.ensure(BuildManifest { target: run.target }
);
2628 fn run(self, builder
: &Builder
<'_
>) -> PathBuf
{
2629 let build_manifest
= builder
.tool_exe(Tool
::BuildManifest
);
2631 let name
= pkgname(builder
, "build-manifest");
2632 let tmp
= tmpdir(builder
);
2634 // Prepare the image.
2635 let image
= tmp
.join("build-manifest-image");
2636 let image_bin
= image
.join("bin");
2637 let _
= fs
::remove_dir_all(&image
);
2638 t
!(fs
::create_dir_all(&image_bin
));
2639 builder
.install(&build_manifest
, &image_bin
, 0o755);
2641 // Prepare the overlay.
2642 let overlay
= tmp
.join("build-manifest-overlay");
2643 let _
= fs
::remove_dir_all(&overlay
);
2644 builder
.create_dir(&overlay
);
2645 builder
.create(&overlay
.join("version"), &builder
.rust_version());
2646 for file
in &["COPYRIGHT", "LICENSE-APACHE", "LICENSE-MIT", "README.md"] {
2647 builder
.install(&builder
.src
.join(file
), &overlay
, 0o644);
2650 // Create the final tarball.
2651 let mut cmd
= rust_installer(builder
);
2653 .arg("--product-name=Rust")
2654 .arg("--rel-manifest-dir=rustlib")
2655 .arg("--success-message=build-manifest installed.")
2659 .arg(&tmpdir(builder
))
2660 .arg("--output-dir")
2661 .arg(&distdir(builder
))
2662 .arg("--non-installed-overlay")
2664 .arg(format
!("--package-name={}-{}", name
, self.target
.triple
))
2665 .arg("--legacy-manifest-dirs=rustlib,cargo")
2666 .arg("--component-name=build-manifest");
2668 builder
.run(&mut cmd
);
2669 distdir(builder
).join(format
!("{}-{}.tar.gz", name
, self.target
.triple
))