Skip to content

Commit d9feb02

Browse files
committed
Auto merge of #114126 - ozkanonur:stage-support-for-clean, r=ozkanonur
clean stage-specific artifacts using `x clean --stage` fixes #109313
2 parents d4145ee + 78326cd commit d9feb02

File tree

5 files changed

+75
-31
lines changed

5 files changed

+75
-31
lines changed

src/bootstrap/clean.rs

+62-22
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,15 @@ impl Step for CleanAll {
2626
}
2727

2828
fn run(self, builder: &Builder<'_>) -> Self::Output {
29-
let Subcommand::Clean { all, .. } = builder.config.cmd else {
29+
let Subcommand::Clean { all, stage } = builder.config.cmd else {
3030
unreachable!("wrong subcommand?")
3131
};
32-
clean_default(builder.build, all)
32+
33+
if all && stage.is_some() {
34+
panic!("--all and --stage can't be used at the same time for `x clean`");
35+
}
36+
37+
clean(builder.build, all, stage)
3338
}
3439

3540
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -86,35 +91,70 @@ clean_crate_tree! {
8691
Std, Mode::Std, "sysroot";
8792
}
8893

89-
fn clean_default(build: &Build, all: bool) {
94+
fn clean(build: &Build, all: bool, stage: Option<u32>) {
9095
if build.config.dry_run() {
9196
return;
9297
}
9398

9499
rm_rf("tmp".as_ref());
95100

101+
// Clean the entire build directory
96102
if all {
97103
rm_rf(&build.out);
98-
} else {
99-
rm_rf(&build.out.join("tmp"));
100-
rm_rf(&build.out.join("dist"));
101-
rm_rf(&build.out.join("bootstrap"));
102-
rm_rf(&build.out.join("rustfmt.stamp"));
103-
104-
for host in &build.hosts {
105-
let entries = match build.out.join(host.triple).read_dir() {
106-
Ok(iter) => iter,
107-
Err(_) => continue,
108-
};
109-
110-
for entry in entries {
111-
let entry = t!(entry);
112-
if entry.file_name().to_str() == Some("llvm") {
113-
continue;
114-
}
115-
let path = t!(entry.path().canonicalize());
116-
rm_rf(&path);
104+
return;
105+
}
106+
107+
// Clean the target stage artifacts
108+
if let Some(stage) = stage {
109+
clean_specific_stage(build, stage);
110+
return;
111+
}
112+
113+
// Follow the default behaviour
114+
clean_default(build);
115+
}
116+
117+
fn clean_specific_stage(build: &Build, stage: u32) {
118+
for host in &build.hosts {
119+
let entries = match build.out.join(host.triple).read_dir() {
120+
Ok(iter) => iter,
121+
Err(_) => continue,
122+
};
123+
124+
for entry in entries {
125+
let entry = t!(entry);
126+
let stage_prefix = format!("stage{}", stage);
127+
128+
// if current entry is not related with the target stage, continue
129+
if !entry.file_name().to_str().unwrap_or("").contains(&stage_prefix) {
130+
continue;
131+
}
132+
133+
let path = t!(entry.path().canonicalize());
134+
rm_rf(&path);
135+
}
136+
}
137+
}
138+
139+
fn clean_default(build: &Build) {
140+
rm_rf(&build.out.join("tmp"));
141+
rm_rf(&build.out.join("dist"));
142+
rm_rf(&build.out.join("bootstrap"));
143+
rm_rf(&build.out.join("rustfmt.stamp"));
144+
145+
for host in &build.hosts {
146+
let entries = match build.out.join(host.triple).read_dir() {
147+
Ok(iter) => iter,
148+
Err(_) => continue,
149+
};
150+
151+
for entry in entries {
152+
let entry = t!(entry);
153+
if entry.file_name().to_str() == Some("llvm") {
154+
continue;
117155
}
156+
let path = t!(entry.path().canonicalize());
157+
rm_rf(&path);
118158
}
119159
}
120160
}

src/bootstrap/flags.rs

+4
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,11 @@ pub enum Subcommand {
366366
/// Clean out build directories
367367
Clean {
368368
#[arg(long)]
369+
/// Clean the entire build directory (not used by default)
369370
all: bool,
371+
#[arg(long, value_name = "N")]
372+
/// Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used.
373+
stage: Option<u32>,
370374
},
371375
/// Build distribution artifacts
372376
Dist,

src/etc/completions/x.py.fish

+2-2
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ complete -c x.py -n "__fish_seen_subcommand_from bench" -l json-output -d 'use m
305305
complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
306306
complete -c x.py -n "__fish_seen_subcommand_from bench" -l llvm-bolt-profile-generate -d 'generate BOLT profile for LLVM build'
307307
complete -c x.py -n "__fish_seen_subcommand_from bench" -s h -l help -d 'Print help'
308+
complete -c x.py -n "__fish_seen_subcommand_from clean" -l stage -d 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used' -r
308309
complete -c x.py -n "__fish_seen_subcommand_from clean" -l config -d 'TOML configuration file for build' -r -F
309310
complete -c x.py -n "__fish_seen_subcommand_from clean" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
310311
complete -c x.py -n "__fish_seen_subcommand_from clean" -l build -d 'build target of the stage0 compiler' -r -f
@@ -313,7 +314,6 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l target -d 'target tar
313314
complete -c x.py -n "__fish_seen_subcommand_from clean" -l exclude -d 'build paths to exclude' -r -F
314315
complete -c x.py -n "__fish_seen_subcommand_from clean" -l rustc-error-format -r -f
315316
complete -c x.py -n "__fish_seen_subcommand_from clean" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
316-
complete -c x.py -n "__fish_seen_subcommand_from clean" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
317317
complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
318318
complete -c x.py -n "__fish_seen_subcommand_from clean" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
319319
complete -c x.py -n "__fish_seen_subcommand_from clean" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
@@ -327,7 +327,7 @@ complete -c x.py -n "__fish_seen_subcommand_from clean" -l rust-profile-use -d '
327327
complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
328328
complete -c x.py -n "__fish_seen_subcommand_from clean" -l llvm-bolt-profile-use -d 'use BOLT profile for LLVM build' -r -F
329329
complete -c x.py -n "__fish_seen_subcommand_from clean" -l set -d 'override options in config.toml' -r -f
330-
complete -c x.py -n "__fish_seen_subcommand_from clean" -l all
330+
complete -c x.py -n "__fish_seen_subcommand_from clean" -l all -d 'Clean the entire build directory (not used by default)'
331331
complete -c x.py -n "__fish_seen_subcommand_from clean" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
332332
complete -c x.py -n "__fish_seen_subcommand_from clean" -s i -l incremental -d 'use incremental compilation'
333333
complete -c x.py -n "__fish_seen_subcommand_from clean" -l include-default-paths -d 'include default paths in addition to the provided ones'

src/etc/completions/x.py.ps1

+2-2
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
391391
break
392392
}
393393
'x.py;clean' {
394+
[CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'Clean a specific stage without touching other artifacts. By default, every stage is cleaned if this option is not used')
394395
[CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
395396
[CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
396397
[CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
@@ -399,7 +400,6 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
399400
[CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
400401
[CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
401402
[CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
402-
[CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
403403
[CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
404404
[CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
405405
[CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
@@ -414,7 +414,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
414414
[CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
415415
[CompletionResult]::new('--llvm-bolt-profile-use', 'llvm-bolt-profile-use', [CompletionResultType]::ParameterName, 'use BOLT profile for LLVM build')
416416
[CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
417-
[CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'all')
417+
[CompletionResult]::new('--all', 'all', [CompletionResultType]::ParameterName, 'Clean the entire build directory (not used by default)')
418418
[CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
419419
[CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
420420
[CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')

src/etc/completions/x.py.sh

+5-5
Original file line numberDiff line numberDiff line change
@@ -489,12 +489,16 @@ _x.py() {
489489
return 0
490490
;;
491491
x.py__clean)
492-
opts="-v -i -j -h --all --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
492+
opts="-v -i -j -h --all --stage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --llvm-bolt-profile-generate --llvm-bolt-profile-use --set --help [PATHS]... [ARGS]..."
493493
if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
494494
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
495495
return 0
496496
fi
497497
case "${prev}" in
498+
--stage)
499+
COMPREPLY=($(compgen -f "${cur}"))
500+
return 0
501+
;;
498502
--config)
499503
COMPREPLY=($(compgen -f "${cur}"))
500504
return 0
@@ -527,10 +531,6 @@ _x.py() {
527531
COMPREPLY=($(compgen -f "${cur}"))
528532
return 0
529533
;;
530-
--stage)
531-
COMPREPLY=("${cur}")
532-
return 0
533-
;;
534534
--keep-stage)
535535
COMPREPLY=("${cur}")
536536
return 0

0 commit comments

Comments
 (0)