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