Skip to content

Commit

Permalink
Teach bootstrap about target files vs target triples
Browse files Browse the repository at this point in the history
`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.
  • Loading branch information
shepmaster committed Jul 12, 2020
1 parent 9d09331 commit 8abbbe2
Show file tree
Hide file tree
Showing 17 changed files with 391 additions and 317 deletions.
59 changes: 29 additions & 30 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use build_helper::{output, t};
use crate::cache::{Cache, Interned, INTERNER};
use crate::check;
use crate::compile;
use crate::config::TargetSelection;
use crate::dist;
use crate::doc;
use crate::flags::Subcommand;
Expand Down Expand Up @@ -86,8 +87,8 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {

pub struct RunConfig<'a> {
pub builder: &'a Builder<'a>,
pub host: Interned<String>,
pub target: Interned<String>,
pub host: TargetSelection,
pub target: TargetSelection,
pub path: PathBuf,
}

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

Expand All @@ -594,8 +595,8 @@ impl<'a> Builder<'a> {
pub fn compiler_for(
&self,
stage: u32,
host: Interned<String>,
target: Interned<String>,
host: TargetSelection,
target: TargetSelection,
) -> Compiler {
if self.build.force_use_stage1(Compiler { stage, host }, target) {
self.compiler(1, self.config.build)
Expand All @@ -610,15 +611,11 @@ impl<'a> Builder<'a> {

/// Returns the libdir where the standard library and other artifacts are
/// found for a compiler's sysroot.
pub fn sysroot_libdir(
&self,
compiler: Compiler,
target: Interned<String>,
) -> Interned<PathBuf> {
pub fn sysroot_libdir(&self, compiler: Compiler, target: TargetSelection) -> Interned<PathBuf> {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
struct Libdir {
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
}
impl Step for Libdir {
type Output = Interned<PathBuf>;
Expand All @@ -633,7 +630,7 @@ impl<'a> Builder<'a> {
.sysroot(self.compiler)
.join(lib)
.join("rustlib")
.join(self.target)
.join(self.target.triple)
.join("lib");
let _ = fs::remove_dir_all(&sysroot);
t!(fs::create_dir_all(&sysroot));
Expand All @@ -656,7 +653,7 @@ impl<'a> Builder<'a> {
Some(relative_libdir) if compiler.stage >= 1 => {
self.sysroot(compiler).join(relative_libdir)
}
_ => self.sysroot(compiler).join(libdir(&compiler.host)),
_ => self.sysroot(compiler).join(libdir(compiler.host)),
}
}
}
Expand All @@ -668,11 +665,11 @@ impl<'a> Builder<'a> {
/// Windows.
pub fn libdir_relative(&self, compiler: Compiler) -> &Path {
if compiler.is_snapshot(self) {
libdir(&self.config.build).as_ref()
libdir(self.config.build).as_ref()
} else {
match self.config.libdir_relative() {
Some(relative_libdir) if compiler.stage >= 1 => relative_libdir,
_ => libdir(&compiler.host).as_ref(),
_ => libdir(compiler.host).as_ref(),
}
}
}
Expand Down Expand Up @@ -707,7 +704,7 @@ impl<'a> Builder<'a> {
if compiler.is_snapshot(self) {
self.initial_rustc.clone()
} else {
self.sysroot(compiler).join("bin").join(exe("rustc", &compiler.host))
self.sysroot(compiler).join("bin").join(exe("rustc", compiler.host))
}
}

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

if cmd != "install" {
cargo.arg("--target").arg(target);
cargo.arg("--target").arg(target.rustc_target_arg());
} else {
assert_eq!(target, compiler.host);
}
Expand All @@ -820,7 +817,7 @@ impl<'a> Builder<'a> {
compiler.stage
};

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

if let Some(target_linker) = self.linker(target, can_use_lld) {
let target = crate::envify(&target);
let target = crate::envify(&target.triple);
cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
}
if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
Expand Down Expand Up @@ -1182,21 +1179,23 @@ impl<'a> Builder<'a> {
}
};
let cc = ccacheify(&self.cc(target));
cargo.env(format!("CC_{}", target), &cc);
cargo.env(format!("CC_{}", target.triple), &cc);

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

if let Some(ar) = self.ar(target) {
let ranlib = format!("{} s", ar.display());
cargo.env(format!("AR_{}", target), ar).env(format!("RANLIB_{}", target), ranlib);
cargo
.env(format!("AR_{}", target.triple), ar)
.env(format!("RANLIB_{}", target.triple), ranlib);
}

if let Ok(cxx) = self.cxx(target) {
let cxx = ccacheify(&cxx);
cargo
.env(format!("CXX_{}", target), &cxx)
.env(format!("CXXFLAGS_{}", target), cflags);
.env(format!("CXX_{}", target.triple), &cxx)
.env(format!("CXXFLAGS_{}", target.triple), cflags);
}
}

Expand Down Expand Up @@ -1230,7 +1229,7 @@ impl<'a> Builder<'a> {
// Environment variables *required* throughout the build
//
// FIXME: should update code to not require this env var
cargo.env("CFG_COMPILER_HOST_TRIPLE", target);
cargo.env("CFG_COMPILER_HOST_TRIPLE", target.triple);

// Set this for all builds to make sure doc builds also get it.
cargo.env("CFG_RELEASE_CHANNEL", &self.config.channel);
Expand Down Expand Up @@ -1386,15 +1385,15 @@ mod tests;
struct Rustflags(String);

impl Rustflags {
fn new(target: &str) -> Rustflags {
fn new(target: TargetSelection) -> Rustflags {
let mut ret = Rustflags(String::new());

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

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

ret
Expand Down
56 changes: 28 additions & 28 deletions src/bootstrap/builder/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::*;
use crate::config::Config;
use crate::config::{Config, TargetSelection};
use std::thread;

use pretty_assertions::assert_eq;
Expand All @@ -17,16 +17,16 @@ fn configure(host: &[&str], target: &[&str]) -> Config {
.join(&thread::current().name().unwrap_or("unknown").replace(":", "-"));
t!(fs::create_dir_all(&dir));
config.out = dir;
config.build = INTERNER.intern_str("A");
config.build = TargetSelection::from_user("A");
config.hosts = vec![config.build]
.into_iter()
.chain(host.iter().map(|s| INTERNER.intern_str(s)))
.chain(host.iter().map(|s| TargetSelection::from_user(s)))
.collect::<Vec<_>>();
config.targets = config
.hosts
.clone()
.into_iter()
.chain(target.iter().map(|s| INTERNER.intern_str(s)))
.chain(target.iter().map(|s| TargetSelection::from_user(s)))
.collect::<Vec<_>>();
config
}
Expand All @@ -41,7 +41,7 @@ fn dist_baseline() {
let mut builder = Builder::new(&build);
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);

let a = INTERNER.intern_str("A");
let a = TargetSelection::from_user("A");

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

let a = INTERNER.intern_str("A");
let b = INTERNER.intern_str("B");
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");

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

let a = INTERNER.intern_str("A");
let b = INTERNER.intern_str("B");
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");

assert_eq!(
first(builder.cache.all::<dist::Docs>()),
Expand Down Expand Up @@ -128,8 +128,8 @@ fn dist_with_hosts() {

#[test]
fn dist_only_cross_host() {
let a = INTERNER.intern_str("A");
let b = INTERNER.intern_str("B");
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");
let mut build = Build::new(configure(&["B"], &[]));
build.config.docs = false;
build.config.extended = true;
Expand All @@ -156,9 +156,9 @@ fn dist_with_targets_and_hosts() {
let mut builder = Builder::new(&build);
builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);

let a = INTERNER.intern_str("A");
let b = INTERNER.intern_str("B");
let c = INTERNER.intern_str("C");
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");
let c = TargetSelection::from_user("C");

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

let a = INTERNER.intern_str("A");
let b = INTERNER.intern_str("B");
let c = INTERNER.intern_str("C");
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");
let c = TargetSelection::from_user("C");

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

let a = INTERNER.intern_str("A");
let b = INTERNER.intern_str("B");
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");

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

let a = INTERNER.intern_str("A");
let b = INTERNER.intern_str("B");
let c = INTERNER.intern_str("C");
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");
let c = TargetSelection::from_user("C");

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

let a = INTERNER.intern_str("A");
let b = INTERNER.intern_str("B");
let c = INTERNER.intern_str("C");
let a = TargetSelection::from_user("A");
let b = TargetSelection::from_user("B");
let c = TargetSelection::from_user("C");

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

let host = INTERNER.intern_str("A");
let host = TargetSelection::from_user("A");

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

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

// error_index_generator uses stage 1 to share rustdoc artifacts with the
// rustdoc tool.
Expand Down
Loading

0 comments on commit 8abbbe2

Please sign in to comment.