Skip to content

Commit 141bb23

Browse files
committed
Auto merge of #76415 - Mark-Simulacrum:bootstrap-cross-compilation, r=alexcrichton
rustbuild: avoid trying to inversely cross-compile for build triple from host triples This changes rustbuild's cross compilation logic to better match what users expect, particularly, avoiding trying to inverse cross-compile for the build triple from host triples. That is, if build=A, host=B, target=B, we do not want to try and compile for A from B. Indeed, the only "known to run" triple when cross-compiling is the build triple A. When testing for a particular target we need to be able to run binaries compiled for that target though. The last commit also modifies the default set of host/target triples to avoid producing needless artifacts for the build triple: The new behavior is to respect --host and --target when passed as the *only* configured triples (no triples are implicitly added). The default for --host is the build triple, and the default for --target is the host triple(s), either configured or the default build triple. Fixes #76333 r? `@alexcrichton` if possible, otherwise we'll need to hunt down a reviewer
2 parents d778203 + 78125ec commit 141bb23

File tree

9 files changed

+99
-94
lines changed

9 files changed

+99
-94
lines changed

config.toml.example

+7-8
Original file line numberDiff line numberDiff line change
@@ -120,19 +120,18 @@
120120
# Defaults to host platform
121121
#build = "x86_64-unknown-linux-gnu"
122122

123-
# In addition to the build triple, other triples to produce full compiler
124-
# toolchains for. Each of these triples will be bootstrapped from the build
125-
# triple and then will continue to bootstrap themselves. This platform must
126-
# currently be able to run all of the triples provided here.
123+
# Which triples to produce a compiler toolchain for. Each of these triples will
124+
# be bootstrapped from the build triple themselves.
127125
#
128126
# Defaults to just the build triple
129127
#host = ["x86_64-unknown-linux-gnu"]
130128

131-
# In addition to all host triples, other triples to produce the standard library
132-
# for. Each host triple will be used to produce a copy of the standard library
133-
# for each target triple.
129+
# Which triples to build libraries (core/alloc/std/test/proc_macro) for. Each of
130+
# these triples will be bootstrapped from the build triple themselves.
134131
#
135-
# Defaults to just the build triple
132+
# Defaults to `host`. If you set this explicitly, you likely want to add all
133+
# host triples to this list as well in order for those host toolchains to be
134+
# able to compile programs for their native target.
136135
#target = ["x86_64-unknown-linux-gnu"]
137136

138137
# Use this directory to store build artifacts.

src/bootstrap/builder.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,16 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
8787

8888
pub struct RunConfig<'a> {
8989
pub builder: &'a Builder<'a>,
90-
pub host: TargetSelection,
9190
pub target: TargetSelection,
9291
pub path: PathBuf,
9392
}
9493

94+
impl RunConfig<'_> {
95+
pub fn build_triple(&self) -> TargetSelection {
96+
self.builder.build.build
97+
}
98+
}
99+
95100
struct StepDescription {
96101
default: bool,
97102
only_hosts: bool,
@@ -165,7 +170,6 @@ impl StepDescription {
165170
pathset, self.name, builder.config.exclude
166171
);
167172
}
168-
let hosts = &builder.hosts;
169173

170174
// Determine the targets participating in this rule.
171175
let targets = if self.only_hosts {
@@ -178,16 +182,9 @@ impl StepDescription {
178182
&builder.targets
179183
};
180184

181-
for host in hosts {
182-
for target in targets {
183-
let run = RunConfig {
184-
builder,
185-
path: pathset.path(builder),
186-
host: *host,
187-
target: *target,
188-
};
189-
(self.make_run)(run);
190-
}
185+
for target in targets {
186+
let run = RunConfig { builder, path: pathset.path(builder), target: *target };
187+
(self.make_run)(run);
191188
}
192189
}
193190

src/bootstrap/builder/tests.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,16 @@ mod dist {
217217
dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
218218
]
219219
);
220+
assert_eq!(
221+
first(builder.cache.all::<compile::Std>()),
222+
&[
223+
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
224+
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
225+
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
226+
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
227+
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
228+
],
229+
);
220230
assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]);
221231
}
222232

@@ -384,12 +394,9 @@ mod dist {
384394
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
385395
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
386396
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
387-
compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a },
388397
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
389398
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
390-
compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b },
391399
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
392-
compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c },
393400
]
394401
);
395402
assert!(!builder.cache.all::<compile::Assemble>().is_empty());
@@ -399,10 +406,8 @@ mod dist {
399406
compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
400407
compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
401408
compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a },
402-
compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: a },
403409
compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
404410
compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b },
405-
compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: b },
406411
]
407412
);
408413
}
@@ -425,12 +430,9 @@ mod dist {
425430
compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
426431
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
427432
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
428-
compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a },
429433
compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
430434
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
431-
compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b },
432435
compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
433-
compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c },
434436
]
435437
);
436438
assert_eq!(
@@ -439,15 +441,13 @@ mod dist {
439441
compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
440442
compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
441443
compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
442-
compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } },
443444
]
444445
);
445446
assert_eq!(
446447
first(builder.cache.all::<compile::Rustc>()),
447448
&[
448449
compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
449450
compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
450-
compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
451451
]
452452
);
453453
}

src/bootstrap/compile.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl Step for Std {
4545

4646
fn make_run(run: RunConfig<'_>) {
4747
run.builder.ensure(Std {
48-
compiler: run.builder.compiler(run.builder.top_stage, run.host),
48+
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
4949
target: run.target,
5050
});
5151
}
@@ -385,7 +385,7 @@ impl Step for StartupObjects {
385385

386386
fn make_run(run: RunConfig<'_>) {
387387
run.builder.ensure(StartupObjects {
388-
compiler: run.builder.compiler(run.builder.top_stage, run.host),
388+
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
389389
target: run.target,
390390
});
391391
}
@@ -454,7 +454,7 @@ impl Step for Rustc {
454454

455455
fn make_run(run: RunConfig<'_>) {
456456
run.builder.ensure(Rustc {
457-
compiler: run.builder.compiler(run.builder.top_stage, run.host),
457+
compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
458458
target: run.target,
459459
});
460460
}

src/bootstrap/config.rs

+24-28
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,8 @@ struct TomlConfig {
273273
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
274274
struct Build {
275275
build: Option<String>,
276-
#[serde(default)]
277-
host: Vec<String>,
278-
#[serde(default)]
279-
target: Vec<String>,
276+
host: Option<Vec<String>>,
277+
target: Option<Vec<String>>,
280278
// This is ignored, the rust code always gets the build directory from the `BUILD_DIR` env variable
281279
build_dir: Option<String>,
282280
cargo: Option<String>,
@@ -505,11 +503,6 @@ impl Config {
505503
config.out = dir;
506504
}
507505

508-
// If --target was specified but --host wasn't specified, don't run any host-only tests.
509-
let has_hosts = !flags.host.is_empty();
510-
let has_targets = !flags.target.is_empty();
511-
config.skip_only_host_steps = !has_hosts && has_targets;
512-
513506
let toml = file
514507
.map(|file| {
515508
let contents = t!(fs::read_to_string(&file));
@@ -528,25 +521,28 @@ impl Config {
528521
.unwrap_or_else(TomlConfig::default);
529522

530523
let build = toml.build.clone().unwrap_or_default();
531-
// set by bootstrap.py
532-
config.hosts.push(config.build);
533-
for host in build.host.iter().map(|h| TargetSelection::from_user(h)) {
534-
if !config.hosts.contains(&host) {
535-
config.hosts.push(host);
536-
}
537-
}
538-
for target in config
539-
.hosts
540-
.iter()
541-
.copied()
542-
.chain(build.target.iter().map(|h| TargetSelection::from_user(h)))
543-
{
544-
if !config.targets.contains(&target) {
545-
config.targets.push(target);
546-
}
547-
}
548-
config.hosts = if !flags.host.is_empty() { flags.host } else { config.hosts };
549-
config.targets = if !flags.target.is_empty() { flags.target } else { config.targets };
524+
525+
// If --target was specified but --host wasn't specified, don't run any host-only tests.
526+
let has_hosts = build.host.is_some() || flags.host.is_some();
527+
let has_targets = build.target.is_some() || flags.target.is_some();
528+
config.skip_only_host_steps = !has_hosts && has_targets;
529+
530+
config.hosts = if let Some(arg_host) = flags.host.clone() {
531+
arg_host
532+
} else if let Some(file_host) = build.host {
533+
file_host.iter().map(|h| TargetSelection::from_user(h)).collect()
534+
} else {
535+
vec![config.build]
536+
};
537+
config.targets = if let Some(arg_target) = flags.target.clone() {
538+
arg_target
539+
} else if let Some(file_target) = build.target {
540+
file_target.iter().map(|h| TargetSelection::from_user(h)).collect()
541+
} else {
542+
// If target is *not* configured, then default to the host
543+
// toolchains.
544+
config.hosts.clone()
545+
};
550546

551547
config.nodejs = build.nodejs.map(PathBuf::from);
552548
config.gdb = build.gdb.map(PathBuf::from);

src/bootstrap/dist.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,9 @@ impl Step for DebuggerScripts {
605605

606606
fn make_run(run: RunConfig<'_>) {
607607
run.builder.ensure(DebuggerScripts {
608-
sysroot: run.builder.sysroot(run.builder.compiler(run.builder.top_stage, run.host)),
608+
sysroot: run
609+
.builder
610+
.sysroot(run.builder.compiler(run.builder.top_stage, run.build_triple())),
609611
host: run.target,
610612
});
611613
}

src/bootstrap/flags.rs

+22-10
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ pub struct Flags {
2020
pub stage: Option<u32>,
2121
pub keep_stage: Vec<u32>,
2222

23-
pub host: Vec<TargetSelection>,
24-
pub target: Vec<TargetSelection>,
23+
pub host: Option<Vec<TargetSelection>>,
24+
pub target: Option<Vec<TargetSelection>>,
2525
pub config: Option<PathBuf>,
2626
pub jobs: Option<u32>,
2727
pub cmd: Subcommand,
@@ -526,14 +526,26 @@ Arguments:
526526
.into_iter()
527527
.map(|j| j.parse().expect("`keep-stage` should be a number"))
528528
.collect(),
529-
host: split(&matches.opt_strs("host"))
530-
.into_iter()
531-
.map(|x| TargetSelection::from_user(&x))
532-
.collect::<Vec<_>>(),
533-
target: split(&matches.opt_strs("target"))
534-
.into_iter()
535-
.map(|x| TargetSelection::from_user(&x))
536-
.collect::<Vec<_>>(),
529+
host: if matches.opt_present("host") {
530+
Some(
531+
split(&matches.opt_strs("host"))
532+
.into_iter()
533+
.map(|x| TargetSelection::from_user(&x))
534+
.collect::<Vec<_>>(),
535+
)
536+
} else {
537+
None
538+
},
539+
target: if matches.opt_present("target") {
540+
Some(
541+
split(&matches.opt_strs("target"))
542+
.into_iter()
543+
.map(|x| TargetSelection::from_user(&x))
544+
.collect::<Vec<_>>(),
545+
)
546+
} else {
547+
None
548+
},
537549
config: cfg_file,
538550
jobs: matches.opt_str("jobs").map(|j| j.parse().expect("`jobs` should be a number")),
539551
cmd,

0 commit comments

Comments
 (0)