bootstrap/core/build_steps/
run.rs
1use std::path::PathBuf;
7
8use crate::Mode;
9use crate::core::build_steps::dist::distdir;
10use crate::core::build_steps::test;
11use crate::core::build_steps::tool::{self, SourceType, Tool};
12use crate::core::build_steps::vendor::{Vendor, default_paths_to_vendor};
13use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
14use crate::core::config::TargetSelection;
15use crate::core::config::flags::get_completion;
16use crate::utils::exec::command;
17
18#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
19pub struct BuildManifest;
20
21impl Step for BuildManifest {
22 type Output = ();
23 const ONLY_HOSTS: bool = true;
24
25 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
26 run.path("src/tools/build-manifest")
27 }
28
29 fn make_run(run: RunConfig<'_>) {
30 run.builder.ensure(BuildManifest);
31 }
32
33 fn run(self, builder: &Builder<'_>) {
34 let mut cmd = builder.tool_cmd(Tool::BuildManifest);
37 let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| {
38 panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n")
39 });
40 let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
41 panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
42 });
43
44 let today = command("date").arg("+%Y-%m-%d").run_capture_stdout(builder).stdout();
45
46 cmd.arg(sign);
47 cmd.arg(distdir(builder));
48 cmd.arg(today.trim());
49 cmd.arg(addr);
50 cmd.arg(&builder.config.channel);
51
52 builder.create_dir(&distdir(builder));
53 cmd.run(builder);
54 }
55}
56
57#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
58pub struct BumpStage0;
59
60impl Step for BumpStage0 {
61 type Output = ();
62 const ONLY_HOSTS: bool = true;
63
64 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
65 run.path("src/tools/bump-stage0")
66 }
67
68 fn make_run(run: RunConfig<'_>) {
69 run.builder.ensure(BumpStage0);
70 }
71
72 fn run(self, builder: &Builder<'_>) -> Self::Output {
73 let mut cmd = builder.tool_cmd(Tool::BumpStage0);
74 cmd.args(builder.config.args());
75 cmd.run(builder);
76 }
77}
78
79#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
80pub struct ReplaceVersionPlaceholder;
81
82impl Step for ReplaceVersionPlaceholder {
83 type Output = ();
84 const ONLY_HOSTS: bool = true;
85
86 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
87 run.path("src/tools/replace-version-placeholder")
88 }
89
90 fn make_run(run: RunConfig<'_>) {
91 run.builder.ensure(ReplaceVersionPlaceholder);
92 }
93
94 fn run(self, builder: &Builder<'_>) -> Self::Output {
95 let mut cmd = builder.tool_cmd(Tool::ReplaceVersionPlaceholder);
96 cmd.arg(&builder.src);
97 cmd.run(builder);
98 }
99}
100
101#[derive(Debug, Clone, PartialEq, Eq, Hash)]
102pub struct Miri {
103 target: TargetSelection,
104}
105
106impl Step for Miri {
107 type Output = ();
108 const ONLY_HOSTS: bool = false;
109
110 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
111 run.path("src/tools/miri")
112 }
113
114 fn make_run(run: RunConfig<'_>) {
115 run.builder.ensure(Miri { target: run.target });
116 }
117
118 fn run(self, builder: &Builder<'_>) {
119 let host = builder.build.build;
120 let target = self.target;
121 let stage = builder.top_stage;
122 if stage == 0 {
123 eprintln!("miri cannot be run at stage 0");
124 std::process::exit(1);
125 }
126
127 let target_compiler = builder.compiler(stage, host);
129 let host_compiler = builder.compiler(stage - 1, host);
134
135 let miri_sysroot = test::Miri::build_miri_sysroot(builder, target_compiler, target);
137
138 let mut miri = tool::prepare_tool_cargo(
142 builder,
143 host_compiler,
144 Mode::ToolRustc,
145 host,
146 Kind::Run,
147 "src/tools/miri",
148 SourceType::InTree,
149 &[],
150 );
151 miri.add_rustc_lib_path(builder);
152 miri.arg("--").arg("--target").arg(target.rustc_target_arg());
153
154 miri.arg("--sysroot").arg(miri_sysroot);
156
157 miri.args(builder.config.args());
160
161 miri.into_cmd().run(builder);
162 }
163}
164
165#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
166pub struct CollectLicenseMetadata;
167
168impl Step for CollectLicenseMetadata {
169 type Output = PathBuf;
170 const ONLY_HOSTS: bool = true;
171
172 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
173 run.path("src/tools/collect-license-metadata")
174 }
175
176 fn make_run(run: RunConfig<'_>) {
177 run.builder.ensure(CollectLicenseMetadata);
178 }
179
180 fn run(self, builder: &Builder<'_>) -> Self::Output {
181 let Some(reuse) = &builder.config.reuse else {
182 panic!("REUSE is required to collect the license metadata");
183 };
184
185 let dest = builder.src.join("license-metadata.json");
186
187 let mut cmd = builder.tool_cmd(Tool::CollectLicenseMetadata);
188 cmd.env("REUSE_EXE", reuse);
189 cmd.env("DEST", &dest);
190 cmd.run(builder);
191
192 dest
193 }
194}
195
196#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
197pub struct GenerateCopyright;
198
199impl Step for GenerateCopyright {
200 type Output = Vec<PathBuf>;
201 const ONLY_HOSTS: bool = true;
202
203 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
204 run.path("src/tools/generate-copyright")
205 }
206
207 fn make_run(run: RunConfig<'_>) {
208 run.builder.ensure(GenerateCopyright);
209 }
210
211 fn run(self, builder: &Builder<'_>) -> Self::Output {
212 let license_metadata = builder.src.join("license-metadata.json");
213 let dest = builder.out.join("COPYRIGHT.html");
214 let dest_libstd = builder.out.join("COPYRIGHT-library.html");
215
216 let paths_to_vendor = default_paths_to_vendor(builder);
217 for (_, submodules) in &paths_to_vendor {
218 for submodule in submodules {
219 builder.build.require_submodule(submodule, None);
220 }
221 }
222 let cargo_manifests = paths_to_vendor
223 .into_iter()
224 .map(|(path, _submodules)| path.to_str().unwrap().to_string())
225 .inspect(|path| assert!(!path.contains(','), "{path} contains a comma in its name"))
226 .collect::<Vec<_>>()
227 .join(",");
228
229 let vendored_sources = if let Some(path) = builder.vendored_crates_path() {
230 path
231 } else {
232 let cache_dir = builder.out.join("tmp").join("generate-copyright-vendor");
233 builder.ensure(Vendor {
234 sync_args: Vec::new(),
235 versioned_dirs: true,
236 root_dir: builder.src.clone(),
237 output_dir: cache_dir.clone(),
238 });
239 cache_dir
240 };
241
242 let mut cmd = builder.tool_cmd(Tool::GenerateCopyright);
243 cmd.env("CARGO_MANIFESTS", &cargo_manifests);
244 cmd.env("LICENSE_METADATA", &license_metadata);
245 cmd.env("DEST", &dest);
246 cmd.env("DEST_LIBSTD", &dest_libstd);
247 cmd.env("SRC_DIR", &builder.src);
248 cmd.env("VENDOR_DIR", &vendored_sources);
249 cmd.env("CARGO", &builder.initial_cargo);
250 cmd.current_dir(&builder.src);
253 cmd.run(builder);
254
255 vec![dest, dest_libstd]
256 }
257}
258
259#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
260pub struct GenerateWindowsSys;
261
262impl Step for GenerateWindowsSys {
263 type Output = ();
264 const ONLY_HOSTS: bool = true;
265
266 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
267 run.path("src/tools/generate-windows-sys")
268 }
269
270 fn make_run(run: RunConfig<'_>) {
271 run.builder.ensure(GenerateWindowsSys);
272 }
273
274 fn run(self, builder: &Builder<'_>) {
275 let mut cmd = builder.tool_cmd(Tool::GenerateWindowsSys);
276 cmd.arg(&builder.src);
277 cmd.run(builder);
278 }
279}
280
281#[derive(Debug, Clone, PartialEq, Eq, Hash)]
282pub struct GenerateCompletions;
283
284macro_rules! generate_completions {
285 ( $( ( $shell:ident, $filename:expr ) ),* ) => {
286 $(
287 if let Some(comp) = get_completion($shell, &$filename) {
288 std::fs::write(&$filename, comp).expect(&format!("writing {} completion", stringify!($shell)));
289 }
290 )*
291 };
292}
293
294impl Step for GenerateCompletions {
295 type Output = ();
296
297 fn run(self, builder: &Builder<'_>) {
299 use clap_complete::shells::{Bash, Fish, PowerShell, Zsh};
300
301 generate_completions!(
302 (Bash, builder.src.join("src/etc/completions/x.py.sh")),
303 (Zsh, builder.src.join("src/etc/completions/x.py.zsh")),
304 (Fish, builder.src.join("src/etc/completions/x.py.fish")),
305 (PowerShell, builder.src.join("src/etc/completions/x.py.ps1")),
306 (Bash, builder.src.join("src/etc/completions/x.sh")),
307 (Zsh, builder.src.join("src/etc/completions/x.zsh")),
308 (Fish, builder.src.join("src/etc/completions/x.fish")),
309 (PowerShell, builder.src.join("src/etc/completions/x.ps1"))
310 );
311 }
312
313 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
314 run.alias("generate-completions")
315 }
316
317 fn make_run(run: RunConfig<'_>) {
318 run.builder.ensure(GenerateCompletions);
319 }
320}
321
322#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
323pub struct UnicodeTableGenerator;
324
325impl Step for UnicodeTableGenerator {
326 type Output = ();
327 const ONLY_HOSTS: bool = true;
328
329 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
330 run.path("src/tools/unicode-table-generator")
331 }
332
333 fn make_run(run: RunConfig<'_>) {
334 run.builder.ensure(UnicodeTableGenerator);
335 }
336
337 fn run(self, builder: &Builder<'_>) {
338 let mut cmd = builder.tool_cmd(Tool::UnicodeTableGenerator);
339 cmd.arg(builder.src.join("library/core/src/unicode/unicode_data.rs"));
340 cmd.run(builder);
341 }
342}
343
344#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)]
345pub struct FeaturesStatusDump;
346
347impl Step for FeaturesStatusDump {
348 type Output = ();
349 const ONLY_HOSTS: bool = true;
350
351 fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
352 run.path("src/tools/features-status-dump")
353 }
354
355 fn make_run(run: RunConfig<'_>) {
356 run.builder.ensure(FeaturesStatusDump);
357 }
358
359 fn run(self, builder: &Builder<'_>) {
360 let mut cmd = builder.tool_cmd(Tool::FeaturesStatusDump);
361
362 cmd.arg("--library-path");
363 cmd.arg(builder.src.join("library"));
364
365 cmd.arg("--compiler-path");
366 cmd.arg(builder.src.join("compiler"));
367
368 cmd.arg("--output-path");
369 cmd.arg(builder.out.join("features-status-dump.json"));
370
371 cmd.run(builder);
372 }
373}