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