Skip to content

Commit 1812539

Browse files
authored
Rollup merge of rust-lang#74251 - shepmaster:bootstrap-target-files, r=Mark-Simulacrum
Teach bootstrap about target files vs target triples `rustc` allows passing in predefined target triples as well as JSON target specification files. This change allows bootstrap to have the first inkling about those differences. This allows building a cross-compiler for an out-of-tree architecture (even though that compiler won't work for other reasons). Even if no one ever uses this functionality, I think the newtype around the `Interned<String>` improves the readability of the code.
2 parents 8ed197f + c24b96d commit 1812539

17 files changed

+391
-317
lines changed

src/bootstrap/builder.rs

+29-30
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use build_helper::{output, t};
1616
use crate::cache::{Cache, Interned, INTERNER};
1717
use crate::check;
1818
use crate::compile;
19+
use crate::config::TargetSelection;
1920
use crate::dist;
2021
use crate::doc;
2122
use crate::flags::Subcommand;
@@ -86,8 +87,8 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
8687

8788
pub struct RunConfig<'a> {
8889
pub builder: &'a Builder<'a>,
89-
pub host: Interned<String>,
90-
pub target: Interned<String>,
90+
pub host: TargetSelection,
91+
pub target: TargetSelection,
9192
pub path: PathBuf,
9293
}
9394

@@ -576,7 +577,7 @@ impl<'a> Builder<'a> {
576577
/// not take `Compiler` since all `Compiler` instances are meant to be
577578
/// obtained through this function, since it ensures that they are valid
578579
/// (i.e., built and assembled).
579-
pub fn compiler(&self, stage: u32, host: Interned<String>) -> Compiler {
580+
pub fn compiler(&self, stage: u32, host: TargetSelection) -> Compiler {
580581
self.ensure(compile::Assemble { target_compiler: Compiler { stage, host } })
581582
}
582583

@@ -594,8 +595,8 @@ impl<'a> Builder<'a> {
594595
pub fn compiler_for(
595596
&self,
596597
stage: u32,
597-
host: Interned<String>,
598-
target: Interned<String>,
598+
host: TargetSelection,
599+
target: TargetSelection,
599600
) -> Compiler {
600601
if self.build.force_use_stage1(Compiler { stage, host }, target) {
601602
self.compiler(1, self.config.build)
@@ -610,15 +611,11 @@ impl<'a> Builder<'a> {
610611

611612
/// Returns the libdir where the standard library and other artifacts are
612613
/// found for a compiler's sysroot.
613-
pub fn sysroot_libdir(
614-
&self,
615-
compiler: Compiler,
616-
target: Interned<String>,
617-
) -> Interned<PathBuf> {
614+
pub fn sysroot_libdir(&self, compiler: Compiler, target: TargetSelection) -> Interned<PathBuf> {
618615
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
619616
struct Libdir {
620617
compiler: Compiler,
621-
target: Interned<String>,
618+
target: TargetSelection,
622619
}
623620
impl Step for Libdir {
624621
type Output = Interned<PathBuf>;
@@ -633,7 +630,7 @@ impl<'a> Builder<'a> {
633630
.sysroot(self.compiler)
634631
.join(lib)
635632
.join("rustlib")
636-
.join(self.target)
633+
.join(self.target.triple)
637634
.join("lib");
638635
let _ = fs::remove_dir_all(&sysroot);
639636
t!(fs::create_dir_all(&sysroot));
@@ -656,7 +653,7 @@ impl<'a> Builder<'a> {
656653
Some(relative_libdir) if compiler.stage >= 1 => {
657654
self.sysroot(compiler).join(relative_libdir)
658655
}
659-
_ => self.sysroot(compiler).join(libdir(&compiler.host)),
656+
_ => self.sysroot(compiler).join(libdir(compiler.host)),
660657
}
661658
}
662659
}
@@ -668,11 +665,11 @@ impl<'a> Builder<'a> {
668665
/// Windows.
669666
pub fn libdir_relative(&self, compiler: Compiler) -> &Path {
670667
if compiler.is_snapshot(self) {
671-
libdir(&self.config.build).as_ref()
668+
libdir(self.config.build).as_ref()
672669
} else {
673670
match self.config.libdir_relative() {
674671
Some(relative_libdir) if compiler.stage >= 1 => relative_libdir,
675-
_ => libdir(&compiler.host).as_ref(),
672+
_ => libdir(compiler.host).as_ref(),
676673
}
677674
}
678675
}
@@ -707,7 +704,7 @@ impl<'a> Builder<'a> {
707704
if compiler.is_snapshot(self) {
708705
self.initial_rustc.clone()
709706
} else {
710-
self.sysroot(compiler).join("bin").join(exe("rustc", &compiler.host))
707+
self.sysroot(compiler).join("bin").join(exe("rustc", compiler.host))
711708
}
712709
}
713710

@@ -741,7 +738,7 @@ impl<'a> Builder<'a> {
741738
///
742739
/// Note that this returns `None` if LLVM is disabled, or if we're in a
743740
/// check build or dry-run, where there's no need to build all of LLVM.
744-
fn llvm_config(&self, target: Interned<String>) -> Option<PathBuf> {
741+
fn llvm_config(&self, target: TargetSelection) -> Option<PathBuf> {
745742
if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run {
746743
let llvm_config = self.ensure(native::Llvm { target });
747744
if llvm_config.is_file() {
@@ -763,7 +760,7 @@ impl<'a> Builder<'a> {
763760
compiler: Compiler,
764761
mode: Mode,
765762
source_type: SourceType,
766-
target: Interned<String>,
763+
target: TargetSelection,
767764
cmd: &str,
768765
) -> Cargo {
769766
let mut cargo = Command::new(&self.initial_cargo);
@@ -794,7 +791,7 @@ impl<'a> Builder<'a> {
794791
}
795792

796793
if cmd != "install" {
797-
cargo.arg("--target").arg(target);
794+
cargo.arg("--target").arg(target.rustc_target_arg());
798795
} else {
799796
assert_eq!(target, compiler.host);
800797
}
@@ -820,7 +817,7 @@ impl<'a> Builder<'a> {
820817
compiler.stage
821818
};
822819

823-
let mut rustflags = Rustflags::new(&target);
820+
let mut rustflags = Rustflags::new(target);
824821
if stage != 0 {
825822
if let Ok(s) = env::var("CARGOFLAGS_NOT_BOOTSTRAP") {
826823
cargo.args(s.split_whitespace());
@@ -993,7 +990,7 @@ impl<'a> Builder<'a> {
993990
// argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
994991
// fun to pass a flag to a tool to pass a flag to pass a flag to a tool
995992
// to change a flag in a binary?
996-
if self.config.rust_rpath && util::use_host_linker(&target) {
993+
if self.config.rust_rpath && util::use_host_linker(target) {
997994
let rpath = if target.contains("apple") {
998995
// Note that we need to take one extra step on macOS to also pass
999996
// `-Wl,-instal_name,@rpath/...` to get things to work right. To
@@ -1021,7 +1018,7 @@ impl<'a> Builder<'a> {
10211018
}
10221019

10231020
if let Some(target_linker) = self.linker(target, can_use_lld) {
1024-
let target = crate::envify(&target);
1021+
let target = crate::envify(&target.triple);
10251022
cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
10261023
}
10271024
if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
@@ -1192,21 +1189,23 @@ impl<'a> Builder<'a> {
11921189
}
11931190
};
11941191
let cc = ccacheify(&self.cc(target));
1195-
cargo.env(format!("CC_{}", target), &cc);
1192+
cargo.env(format!("CC_{}", target.triple), &cc);
11961193

11971194
let cflags = self.cflags(target, GitRepo::Rustc).join(" ");
1198-
cargo.env(format!("CFLAGS_{}", target), cflags.clone());
1195+
cargo.env(format!("CFLAGS_{}", target.triple), cflags.clone());
11991196

12001197
if let Some(ar) = self.ar(target) {
12011198
let ranlib = format!("{} s", ar.display());
1202-
cargo.env(format!("AR_{}", target), ar).env(format!("RANLIB_{}", target), ranlib);
1199+
cargo
1200+
.env(format!("AR_{}", target.triple), ar)
1201+
.env(format!("RANLIB_{}", target.triple), ranlib);
12031202
}
12041203

12051204
if let Ok(cxx) = self.cxx(target) {
12061205
let cxx = ccacheify(&cxx);
12071206
cargo
1208-
.env(format!("CXX_{}", target), &cxx)
1209-
.env(format!("CXXFLAGS_{}", target), cflags);
1207+
.env(format!("CXX_{}", target.triple), &cxx)
1208+
.env(format!("CXXFLAGS_{}", target.triple), cflags);
12101209
}
12111210
}
12121211

@@ -1240,7 +1239,7 @@ impl<'a> Builder<'a> {
12401239
// Environment variables *required* throughout the build
12411240
//
12421241
// FIXME: should update code to not require this env var
1243-
cargo.env("CFG_COMPILER_HOST_TRIPLE", target);
1242+
cargo.env("CFG_COMPILER_HOST_TRIPLE", target.triple);
12441243

12451244
// Set this for all builds to make sure doc builds also get it.
12461245
cargo.env("CFG_RELEASE_CHANNEL", &self.config.channel);
@@ -1396,15 +1395,15 @@ mod tests;
13961395
struct Rustflags(String);
13971396

13981397
impl Rustflags {
1399-
fn new(target: &str) -> Rustflags {
1398+
fn new(target: TargetSelection) -> Rustflags {
14001399
let mut ret = Rustflags(String::new());
14011400

14021401
// Inherit `RUSTFLAGS` by default ...
14031402
ret.env("RUSTFLAGS");
14041403

14051404
// ... and also handle target-specific env RUSTFLAGS if they're
14061405
// configured.
1407-
let target_specific = format!("CARGO_TARGET_{}_RUSTFLAGS", crate::envify(target));
1406+
let target_specific = format!("CARGO_TARGET_{}_RUSTFLAGS", crate::envify(&target.triple));
14081407
ret.env(&target_specific);
14091408

14101409
ret

src/bootstrap/builder/tests.rs

+28-28
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::*;
2-
use crate::config::Config;
2+
use crate::config::{Config, TargetSelection};
33
use std::thread;
44

55
use pretty_assertions::assert_eq;
@@ -17,16 +17,16 @@ fn configure(host: &[&str], target: &[&str]) -> Config {
1717
.join(&thread::current().name().unwrap_or("unknown").replace(":", "-"));
1818
t!(fs::create_dir_all(&dir));
1919
config.out = dir;
20-
config.build = INTERNER.intern_str("A");
20+
config.build = TargetSelection::from_user("A");
2121
config.hosts = vec![config.build]
2222
.into_iter()
23-
.chain(host.iter().map(|s| INTERNER.intern_str(s)))
23+
.chain(host.iter().map(|s| TargetSelection::from_user(s)))
2424
.collect::<Vec<_>>();
2525
config.targets = config
2626
.hosts
2727
.clone()
2828
.into_iter()
29-
.chain(target.iter().map(|s| INTERNER.intern_str(s)))
29+
.chain(target.iter().map(|s| TargetSelection::from_user(s)))
3030
.collect::<Vec<_>>();
3131
config
3232
}
@@ -41,7 +41,7 @@ fn dist_baseline() {
4141
let mut builder = Builder::new(&build);
4242
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
4343

44-
let a = INTERNER.intern_str("A");
44+
let a = TargetSelection::from_user("A");
4545

4646
assert_eq!(first(builder.cache.all::<dist::Docs>()), &[dist::Docs { host: a },]);
4747
assert_eq!(first(builder.cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]);
@@ -67,8 +67,8 @@ fn dist_with_targets() {
6767
let mut builder = Builder::new(&build);
6868
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
6969

70-
let a = INTERNER.intern_str("A");
71-
let b = INTERNER.intern_str("B");
70+
let a = TargetSelection::from_user("A");
71+
let b = TargetSelection::from_user("B");
7272

7373
assert_eq!(
7474
first(builder.cache.all::<dist::Docs>()),
@@ -98,8 +98,8 @@ fn dist_with_hosts() {
9898
let mut builder = Builder::new(&build);
9999
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
100100

101-
let a = INTERNER.intern_str("A");
102-
let b = INTERNER.intern_str("B");
101+
let a = TargetSelection::from_user("A");
102+
let b = TargetSelection::from_user("B");
103103

104104
assert_eq!(
105105
first(builder.cache.all::<dist::Docs>()),
@@ -128,8 +128,8 @@ fn dist_with_hosts() {
128128

129129
#[test]
130130
fn dist_only_cross_host() {
131-
let a = INTERNER.intern_str("A");
132-
let b = INTERNER.intern_str("B");
131+
let a = TargetSelection::from_user("A");
132+
let b = TargetSelection::from_user("B");
133133
let mut build = Build::new(configure(&["B"], &[]));
134134
build.config.docs = false;
135135
build.config.extended = true;
@@ -156,9 +156,9 @@ fn dist_with_targets_and_hosts() {
156156
let mut builder = Builder::new(&build);
157157
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
158158

159-
let a = INTERNER.intern_str("A");
160-
let b = INTERNER.intern_str("B");
161-
let c = INTERNER.intern_str("C");
159+
let a = TargetSelection::from_user("A");
160+
let b = TargetSelection::from_user("B");
161+
let c = TargetSelection::from_user("C");
162162

163163
assert_eq!(
164164
first(builder.cache.all::<dist::Docs>()),
@@ -194,9 +194,9 @@ fn dist_with_target_flag() {
194194
let mut builder = Builder::new(&build);
195195
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
196196

197-
let a = INTERNER.intern_str("A");
198-
let b = INTERNER.intern_str("B");
199-
let c = INTERNER.intern_str("C");
197+
let a = TargetSelection::from_user("A");
198+
let b = TargetSelection::from_user("B");
199+
let c = TargetSelection::from_user("C");
200200

201201
assert_eq!(
202202
first(builder.cache.all::<dist::Docs>()),
@@ -224,8 +224,8 @@ fn dist_with_same_targets_and_hosts() {
224224
let mut builder = Builder::new(&build);
225225
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
226226

227-
let a = INTERNER.intern_str("A");
228-
let b = INTERNER.intern_str("B");
227+
let a = TargetSelection::from_user("A");
228+
let b = TargetSelection::from_user("B");
229229

230230
assert_eq!(
231231
first(builder.cache.all::<dist::Docs>()),
@@ -277,9 +277,9 @@ fn build_default() {
277277
let mut builder = Builder::new(&build);
278278
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
279279

280-
let a = INTERNER.intern_str("A");
281-
let b = INTERNER.intern_str("B");
282-
let c = INTERNER.intern_str("C");
280+
let a = TargetSelection::from_user("A");
281+
let b = TargetSelection::from_user("B");
282+
let c = TargetSelection::from_user("C");
283283

284284
assert_eq!(
285285
first(builder.cache.all::<compile::Std>()),
@@ -318,9 +318,9 @@ fn build_with_target_flag() {
318318
let mut builder = Builder::new(&build);
319319
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
320320

321-
let a = INTERNER.intern_str("A");
322-
let b = INTERNER.intern_str("B");
323-
let c = INTERNER.intern_str("C");
321+
let a = TargetSelection::from_user("A");
322+
let b = TargetSelection::from_user("B");
323+
let c = TargetSelection::from_user("C");
324324

325325
assert_eq!(
326326
first(builder.cache.all::<compile::Std>()),
@@ -374,7 +374,7 @@ fn test_with_no_doc_stage0() {
374374
let build = Build::new(config);
375375
let mut builder = Builder::new(&build);
376376

377-
let host = INTERNER.intern_str("A");
377+
let host = TargetSelection::from_user("A");
378378

379379
builder
380380
.run_step_descriptions(&[StepDescription::from::<test::Crate>()], &["src/libstd".into()]);
@@ -428,7 +428,7 @@ fn doc_default() {
428428
let build = Build::new(config);
429429
let mut builder = Builder::new(&build);
430430
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]);
431-
let a = INTERNER.intern_str("A");
431+
let a = TargetSelection::from_user("A");
432432

433433
// error_index_generator uses stage 1 to share rustdoc artifacts with the
434434
// rustdoc tool.
@@ -466,7 +466,7 @@ fn test_docs() {
466466
let build = Build::new(config);
467467
let mut builder = Builder::new(&build);
468468
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]);
469-
let a = INTERNER.intern_str("A");
469+
let a = TargetSelection::from_user("A");
470470

471471
// error_index_generator uses stage 1 to share rustdoc artifacts with the
472472
// rustdoc tool.

0 commit comments

Comments
 (0)