Skip to content

Teach bootstrap about target files vs target triples #74251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 18, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 30 additions & 31 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -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,
}

@@ -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 } })
}

@@ -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)
@@ -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>;
@@ -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));
@@ -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)),
}
}
}
@@ -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(),
}
}
}
@@ -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))
}
}

@@ -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() {
@@ -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);
@@ -773,7 +770,7 @@ impl<'a> Builder<'a> {
let my_out = match mode {
// This is the intended out directory for compiler documentation.
Mode::Rustc | Mode::ToolRustc | Mode::Codegen => self.compiler_doc_out(target),
Mode::Std => out_dir.join(target).join("doc"),
Mode::Std => out_dir.join(target.triple).join("doc"),
_ => panic!("doc mode {:?} not expected", mode),
};
let rustdoc = self.rustdoc(compiler);
@@ -795,7 +792,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);
}
@@ -821,7 +818,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());
@@ -994,7 +991,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
@@ -1022,7 +1019,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 {
@@ -1193,21 +1190,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);
}
}

@@ -1241,7 +1240,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);
@@ -1397,15 +1396,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
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;
@@ -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
}
@@ -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 },]);
@@ -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>()),
@@ -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>()),
@@ -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;
@@ -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>()),
@@ -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>()),
@@ -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>()),
@@ -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>()),
@@ -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>()),
@@ -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()]);
@@ -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.
@@ -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.
34 changes: 17 additions & 17 deletions src/bootstrap/cc_detect.rs
Original file line number Diff line number Diff line change
@@ -28,16 +28,15 @@ use std::{env, iter};

use build_helper::output;

use crate::cache::Interned;
use crate::config::Target;
use crate::config::{Target, TargetSelection};
use crate::{Build, GitRepo};

// The `cc` crate doesn't provide a way to obtain a path to the detected archiver,
// so use some simplified logic here. First we respect the environment variable `AR`, then
// try to infer the archiver path from the C compiler path.
// In the future this logic should be replaced by calling into the `cc` crate.
fn cc2ar(cc: &Path, target: &str) -> Option<PathBuf> {
if let Some(ar) = env::var_os(format!("AR_{}", target.replace("-", "_"))) {
fn cc2ar(cc: &Path, target: TargetSelection) -> Option<PathBuf> {
if let Some(ar) = env::var_os(format!("AR_{}", target.triple.replace("-", "_"))) {
Some(PathBuf::from(ar))
} else if let Some(ar) = env::var_os("AR") {
Some(PathBuf::from(ar))
@@ -79,8 +78,8 @@ pub fn find(build: &mut Build) {
.opt_level(2)
.warnings(false)
.debug(false)
.target(&target)
.host(&build.build);
.target(&target.triple)
.host(&build.build.triple);
match build.crt_static(target) {
Some(a) => {
cfg.static_crt(a);
@@ -106,10 +105,10 @@ pub fn find(build: &mut Build) {
let ar = if let ar @ Some(..) = config.and_then(|c| c.ar.clone()) {
ar
} else {
cc2ar(compiler.path(), &target)
cc2ar(compiler.path(), target)
};

build.cc.insert(target, compiler);
build.cc.insert(target, compiler.clone());
let cflags = build.cflags(target, GitRepo::Rustc);

// If we use llvm-libunwind, we will need a C++ compiler as well for all targets
@@ -120,8 +119,8 @@ pub fn find(build: &mut Build) {
.warnings(false)
.debug(false)
.cpp(true)
.target(&target)
.host(&build.build);
.target(&target.triple)
.host(&build.build.triple);

let cxx_configured = if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
cfg.compiler(cxx);
@@ -138,14 +137,14 @@ pub fn find(build: &mut Build) {
build.cxx.insert(target, compiler);
}

build.verbose(&format!("CC_{} = {:?}", &target, build.cc(target)));
build.verbose(&format!("CFLAGS_{} = {:?}", &target, cflags));
build.verbose(&format!("CC_{} = {:?}", &target.triple, build.cc(target)));
build.verbose(&format!("CFLAGS_{} = {:?}", &target.triple, cflags));
if let Ok(cxx) = build.cxx(target) {
build.verbose(&format!("CXX_{} = {:?}", &target, cxx));
build.verbose(&format!("CXXFLAGS_{} = {:?}", &target, cflags));
build.verbose(&format!("CXX_{} = {:?}", &target.triple, cxx));
build.verbose(&format!("CXXFLAGS_{} = {:?}", &target.triple, cflags));
}
if let Some(ar) = ar {
build.verbose(&format!("AR_{} = {:?}", &target, ar));
build.verbose(&format!("AR_{} = {:?}", &target.triple, ar));
build.ar.insert(target, ar);
}
}
@@ -154,17 +153,18 @@ pub fn find(build: &mut Build) {
fn set_compiler(
cfg: &mut cc::Build,
compiler: Language,
target: Interned<String>,
target: TargetSelection,
config: Option<&Target>,
build: &Build,
) {
match &*target {
match &*target.triple {
// When compiling for android we may have the NDK configured in the
// config.toml in which case we look there. Otherwise the default
// compiler already takes into account the triple in question.
t if t.contains("android") => {
if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) {
let target = target
.triple
.replace("armv7neon", "arm")
.replace("armv7", "arm")
.replace("thumbv7neon", "arm")
18 changes: 9 additions & 9 deletions src/bootstrap/check.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
use crate::cache::Interned;
use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, std_cargo};
use crate::config::TargetSelection;
use crate::tool::{prepare_tool_cargo, SourceType};
use crate::{Compiler, Mode};
use std::path::PathBuf;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Std {
pub target: Interned<String>,
pub target: TargetSelection,
}

fn args(kind: Kind) -> Vec<String> {
@@ -71,7 +71,7 @@ impl Step for Std {

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Rustc {
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Rustc {
@@ -127,7 +127,7 @@ macro_rules! tool_check_step {
($name:ident, $path:expr, $source_type:expr) => {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct $name {
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for $name {
@@ -163,8 +163,8 @@ macro_rules! tool_check_step {
println!(
"Checking {} artifacts ({} -> {})",
stringify!($name).to_lowercase(),
&compiler.host,
target
&compiler.host.triple,
target.triple
);
run_cargo(
builder,
@@ -184,7 +184,7 @@ macro_rules! tool_check_step {
fn stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
) -> PathBuf {
builder
.cargo_out(compiler, Mode::ToolRustc, target)
@@ -204,12 +204,12 @@ tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree);

/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: Interned<String>) -> PathBuf {
fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
}

/// Cargo's output path for librustc in a given stage, compiled by a particular
/// compiler for the specified target.
fn librustc_stamp(builder: &Builder<'_>, compiler: Compiler, target: Interned<String>) -> PathBuf {
fn librustc_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc-check.stamp")
}
2 changes: 1 addition & 1 deletion src/bootstrap/clean.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ pub fn clean(build: &Build, all: bool) {
rm_rf(&build.out.join("dist"));

for host in &build.hosts {
let entries = match build.out.join(host).read_dir() {
let entries = match build.out.join(host.triple).read_dir() {
Ok(iter) => iter,
Err(_) => continue,
};
45 changes: 21 additions & 24 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ use serde::Deserialize;
use crate::builder::Cargo;
use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
use crate::cache::{Interned, INTERNER};
use crate::config::TargetSelection;
use crate::dist;
use crate::native;
use crate::tool::SourceType;
@@ -30,7 +31,7 @@ use crate::{Compiler, DependencyType, GitRepo, Mode};

#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Std {
pub target: Interned<String>,
pub target: TargetSelection,
pub compiler: Compiler,
}

@@ -129,7 +130,7 @@ fn copy_and_stamp(
fn copy_third_party_objects(
builder: &Builder<'_>,
compiler: &Compiler,
target: Interned<String>,
target: TargetSelection,
) -> Vec<(PathBuf, DependencyType)> {
let mut target_deps = vec![];

@@ -157,7 +158,7 @@ fn copy_third_party_objects(
fn copy_self_contained_objects(
builder: &Builder<'_>,
compiler: &Compiler,
target: Interned<String>,
target: TargetSelection,
) -> Vec<(PathBuf, DependencyType)> {
let libdir_self_contained = builder.sysroot_libdir(*compiler, target).join("self-contained");
t!(fs::create_dir_all(&libdir_self_contained));
@@ -206,7 +207,7 @@ fn copy_self_contained_objects(

/// Configure cargo to compile the standard library, adding appropriate env vars
/// and such.
pub fn std_cargo(builder: &Builder<'_>, target: Interned<String>, stage: u32, cargo: &mut Cargo) {
pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, cargo: &mut Cargo) {
if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
}
@@ -301,7 +302,7 @@ pub fn std_cargo(builder: &Builder<'_>, target: Interned<String>, stage: u32, ca
struct StdLink {
pub compiler: Compiler,
pub target_compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for StdLink {
@@ -337,7 +338,7 @@ impl Step for StdLink {
fn copy_sanitizers(
builder: &Builder<'_>,
compiler: &Compiler,
target: Interned<String>,
target: TargetSelection,
) -> Vec<PathBuf> {
let runtimes: Vec<native::SanitizerRuntime> = builder.ensure(native::Sanitizers { target });

@@ -372,7 +373,7 @@ fn copy_sanitizers(
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct StartupObjects {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for StartupObjects {
@@ -419,7 +420,7 @@ impl Step for StartupObjects {
.arg("--cfg")
.arg("bootstrap")
.arg("--target")
.arg(target)
.arg(target.rustc_target_arg())
.arg("--emit=obj")
.arg("-o")
.arg(dst_file)
@@ -438,7 +439,7 @@ impl Step for StartupObjects {

#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Rustc {
pub target: Interned<String>,
pub target: TargetSelection,
pub compiler: Compiler,
}

@@ -518,7 +519,7 @@ impl Step for Rustc {
}
}

pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: Interned<String>) {
pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
cargo
.arg("--features")
.arg(builder.rustc_features())
@@ -527,7 +528,7 @@ pub fn rustc_cargo(builder: &Builder<'_>, cargo: &mut Cargo, target: Interned<St
rustc_cargo_env(builder, cargo, target);
}

pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interned<String>) {
pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
// Set some configuration variables picked up by build scripts and
// the compiler alike
cargo
@@ -608,7 +609,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interne
struct RustcLink {
pub compiler: Compiler,
pub target_compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for RustcLink {
@@ -638,11 +639,7 @@ impl Step for RustcLink {

/// Cargo's output path for the standard library in a given stage, compiled
/// by a particular compiler for the specified target.
pub fn libstd_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: Interned<String>,
) -> PathBuf {
pub fn libstd_stamp(builder: &Builder<'_>, compiler: Compiler, target: TargetSelection) -> PathBuf {
builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
}

@@ -651,15 +648,15 @@ pub fn libstd_stamp(
pub fn librustc_stamp(
builder: &Builder<'_>,
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
) -> PathBuf {
builder.cargo_out(compiler, Mode::Rustc, target).join(".librustc.stamp")
}

pub fn compiler_file(
builder: &Builder<'_>,
compiler: &Path,
target: Interned<String>,
target: TargetSelection,
file: &str,
) -> PathBuf {
let mut cmd = Command::new(compiler);
@@ -690,9 +687,9 @@ impl Step for Sysroot {
fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> {
let compiler = self.compiler;
let sysroot = if compiler.stage == 0 {
builder.out.join(&compiler.host).join("stage0-sysroot")
builder.out.join(&compiler.host.triple).join("stage0-sysroot")
} else {
builder.out.join(&compiler.host).join(format!("stage{}", compiler.stage))
builder.out.join(&compiler.host.triple).join(format!("stage{}", compiler.stage))
};
let _ = fs::remove_dir_all(&sysroot);
t!(fs::create_dir_all(&sysroot));
@@ -806,8 +803,8 @@ impl Step for Assemble {

let libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
if let Some(lld_install) = lld_install {
let src_exe = exe("lld", &target_compiler.host);
let dst_exe = exe("rust-lld", &target_compiler.host);
let src_exe = exe("lld", target_compiler.host);
let dst_exe = exe("rust-lld", target_compiler.host);
// we prepend this bin directory to the user PATH when linking Rust binaries. To
// avoid shadowing the system LLD we rename the LLD we provide to `rust-lld`.
let dst = libdir.parent().unwrap().join("bin");
@@ -822,7 +819,7 @@ impl Step for Assemble {

// Link the compiler binary itself into place
let out_dir = builder.cargo_out(build_compiler, Mode::Rustc, host);
let rustc = out_dir.join(exe("rustc_binary", &*host));
let rustc = out_dir.join(exe("rustc_binary", host));
let bindir = sysroot.join("bin");
t!(fs::create_dir_all(&bindir));
let compiler = builder.rustc(target_compiler);
84 changes: 74 additions & 10 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ use std::cmp;
use std::collections::{HashMap, HashSet};
use std::env;
use std::ffi::OsString;
use std::fmt;
use std::fs;
use std::path::{Path, PathBuf};
use std::process;
@@ -39,7 +40,7 @@ pub struct Config {
pub docs: bool,
pub locked_deps: bool,
pub vendor: bool,
pub target_config: HashMap<Interned<String>, Target>,
pub target_config: HashMap<TargetSelection, Target>,
pub full_bootstrap: bool,
pub extended: bool,
pub tools: Option<HashSet<String>>,
@@ -112,9 +113,9 @@ pub struct Config {
pub rust_thin_lto_import_instr_limit: Option<u32>,
pub rust_remap_debuginfo: bool,

pub build: Interned<String>,
pub hosts: Vec<Interned<String>>,
pub targets: Vec<Interned<String>>,
pub build: TargetSelection,
pub hosts: Vec<TargetSelection>,
pub targets: Vec<TargetSelection>,
pub local_rebuild: bool,
pub jemalloc: bool,
pub control_flow_guard: bool,
@@ -158,6 +159,67 @@ pub struct Config {
pub out: PathBuf,
}

#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TargetSelection {
pub triple: Interned<String>,
file: Option<Interned<String>>,
}

impl TargetSelection {
pub fn from_user(selection: &str) -> Self {
let path = Path::new(selection);

let (triple, file) = if path.exists() {
let triple = path
.file_stem()
.expect("Target specification file has no file stem")
.to_str()
.expect("Target specification file stem is not UTF-8");

(triple, Some(selection))
} else {
(selection, None)
};

let triple = INTERNER.intern_str(triple);
let file = file.map(|f| INTERNER.intern_str(f));

Self { triple, file }
}

pub fn rustc_target_arg(&self) -> &str {
self.file.as_ref().unwrap_or(&self.triple)
}

pub fn contains(&self, needle: &str) -> bool {
self.triple.contains(needle)
}

pub fn starts_with(&self, needle: &str) -> bool {
self.triple.starts_with(needle)
}

pub fn ends_with(&self, needle: &str) -> bool {
self.triple.ends_with(needle)
}
}

impl fmt::Display for TargetSelection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.triple)?;
if let Some(file) = self.file {
write!(f, "({})", file)?;
}
Ok(())
}
}

impl PartialEq<&str> for TargetSelection {
fn eq(&self, other: &&str) -> bool {
self.triple == *other
}
}

/// Per-target configuration stored in the global configuration structure.
#[derive(Default)]
pub struct Target {
@@ -403,7 +465,7 @@ impl Config {
config.missing_tools = false;

// set by bootstrap.py
config.build = INTERNER.intern_str(&env::var("BUILD").expect("'BUILD' to be set"));
config.build = TargetSelection::from_user(&env::var("BUILD").expect("'BUILD' to be set"));
config.src = Config::path_from_python("SRC");
config.out = Config::path_from_python("BUILD_DIR");

@@ -464,14 +526,16 @@ impl Config {
let build = toml.build.clone().unwrap_or_default();
// set by bootstrap.py
config.hosts.push(config.build.clone());
for host in build.host.iter() {
let host = INTERNER.intern_str(host);
for host in build.host.iter().map(|h| TargetSelection::from_user(h)) {
if !config.hosts.contains(&host) {
config.hosts.push(host);
}
}
for target in
config.hosts.iter().cloned().chain(build.target.iter().map(|s| INTERNER.intern_str(s)))
for target in config
.hosts
.iter()
.copied()
.chain(build.target.iter().map(|h| TargetSelection::from_user(h)))
{
if !config.targets.contains(&target) {
config.targets.push(target);
@@ -637,7 +701,7 @@ impl Config {
target.wasi_root = cfg.wasi_root.clone().map(PathBuf::from);
target.qemu_rootfs = cfg.qemu_rootfs.clone().map(PathBuf::from);

config.target_config.insert(INTERNER.intern_string(triple.clone()), target);
config.target_config.insert(TargetSelection::from_user(triple), target);
}
}

79 changes: 40 additions & 39 deletions src/bootstrap/dist.rs
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::cache::{Interned, INTERNER};
use crate::channel;
use crate::compile;
use crate::config::TargetSelection;
use crate::tool::{self, Tool};
use crate::util::{exe, is_dylib, timeit};
use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS};
@@ -68,7 +69,7 @@ fn missing_tool(tool_name: &str, skip: bool) {

#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Docs {
pub host: Interned<String>,
pub host: TargetSelection,
}

impl Step for Docs {
@@ -131,7 +132,7 @@ impl Step for Docs {

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustcDocs {
pub host: Interned<String>,
pub host: TargetSelection,
}

impl Step for RustcDocs {
@@ -210,11 +211,11 @@ fn find_files(files: &[&str], path: &[PathBuf]) -> Vec<PathBuf> {
fn make_win_dist(
rust_root: &Path,
plat_root: &Path,
target_triple: Interned<String>,
target: TargetSelection,
builder: &Builder<'_>,
) {
//Ask gcc where it keeps its stuff
let mut cmd = Command::new(builder.cc(target_triple));
let mut cmd = Command::new(builder.cc(target));
cmd.arg("-print-search-dirs");
let gcc_out = output(&mut cmd);

@@ -234,16 +235,16 @@ fn make_win_dist(
}
}

let compiler = if target_triple == "i686-pc-windows-gnu" {
let compiler = if target == "i686-pc-windows-gnu" {
"i686-w64-mingw32-gcc.exe"
} else if target_triple == "x86_64-pc-windows-gnu" {
} else if target == "x86_64-pc-windows-gnu" {
"x86_64-w64-mingw32-gcc.exe"
} else {
"gcc.exe"
};
let target_tools = [compiler, "ld.exe", "dlltool.exe", "libwinpthread-1.dll"];
let mut rustc_dlls = vec!["libwinpthread-1.dll"];
if target_triple.starts_with("i686-") {
if target.starts_with("i686-") {
rustc_dlls.push("libgcc_s_dw2-1.dll");
} else {
rustc_dlls.push("libgcc_s_seh-1.dll");
@@ -311,7 +312,7 @@ fn make_win_dist(
let target_bin_dir = plat_root
.join("lib")
.join("rustlib")
.join(target_triple)
.join(target.triple)
.join("bin")
.join("self-contained");
fs::create_dir_all(&target_bin_dir).expect("creating target_bin_dir failed");
@@ -331,7 +332,7 @@ fn make_win_dist(
let target_lib_dir = plat_root
.join("lib")
.join("rustlib")
.join(target_triple)
.join(target.triple)
.join("lib")
.join("self-contained");
fs::create_dir_all(&target_lib_dir).expect("creating target_lib_dir failed");
@@ -342,7 +343,7 @@ fn make_win_dist(

#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Mingw {
pub host: Interned<String>,
pub host: TargetSelection,
}

impl Step for Mingw {
@@ -530,11 +531,11 @@ impl Step for Rustc {

// Copy over lld if it's there
if builder.config.lld_enabled {
let exe = exe("rust-lld", &compiler.host);
let exe = exe("rust-lld", compiler.host);
let src =
builder.sysroot_libdir(compiler, host).parent().unwrap().join("bin").join(&exe);
// for the rationale about this rename check `compile::copy_lld_to_sysroot`
let dst = image.join("lib/rustlib").join(&*host).join("bin").join(&exe);
let dst = image.join("lib/rustlib").join(&*host.triple).join("bin").join(&exe);
t!(fs::create_dir_all(&dst.parent().unwrap()));
builder.copy(&src, &dst);
}
@@ -592,7 +593,7 @@ impl Step for Rustc {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct DebuggerScripts {
pub sysroot: Interned<PathBuf>,
pub host: Interned<String>,
pub host: TargetSelection,
}

impl Step for DebuggerScripts {
@@ -662,8 +663,8 @@ fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
}

/// Copy stamped files into an image's `target/lib` directory.
fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &Path) {
let dst = image.join("lib/rustlib").join(target).join("lib");
fn copy_target_libs(builder: &Builder<'_>, target: TargetSelection, image: &Path, stamp: &Path) {
let dst = image.join("lib/rustlib").join(target.triple).join("lib");
let self_contained_dst = dst.join("self-contained");
t!(fs::create_dir_all(&dst));
t!(fs::create_dir_all(&self_contained_dst));
@@ -679,7 +680,7 @@ fn copy_target_libs(builder: &Builder<'_>, target: &str, image: &Path, stamp: &P
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Std {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Std {
@@ -718,7 +719,7 @@ impl Step for Std {

let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
copy_target_libs(builder, &target, &image, &stamp);
copy_target_libs(builder, target, &image, &stamp);

let mut cmd = rust_installer(builder);
cmd.arg("generate")
@@ -747,7 +748,7 @@ impl Step for Std {
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustcDev {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for RustcDev {
@@ -787,7 +788,7 @@ impl Step for RustcDev {

let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
let stamp = compile::librustc_stamp(builder, compiler_to_use, target);
copy_target_libs(builder, &target, &image, &stamp);
copy_target_libs(builder, target, &image, &stamp);

let mut cmd = rust_installer(builder);
cmd.arg("generate")
@@ -818,7 +819,7 @@ impl Step for RustcDev {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Analysis {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Analysis {
@@ -861,12 +862,12 @@ impl Step for Analysis {

let src = builder
.stage_out(compiler, Mode::Std)
.join(target)
.join(target.triple)
.join(builder.cargo_dir())
.join("deps");

let image_src = src.join("save-analysis");
let dst = image.join("lib/rustlib").join(target).join("analysis");
let dst = image.join("lib/rustlib").join(target.triple).join("analysis");
t!(fs::create_dir_all(&dst));
builder.info(&format!("image_src: {:?}, dst: {:?}", image_src, dst));
builder.cp_r(&image_src, &dst);
@@ -1163,7 +1164,7 @@ pub fn sanitize_sh(path: &Path) -> String {
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Cargo {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Cargo {
@@ -1255,7 +1256,7 @@ impl Step for Cargo {
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Rls {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Rls {
@@ -1345,7 +1346,7 @@ impl Step for Rls {
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustAnalyzer {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for RustAnalyzer {
@@ -1432,7 +1433,7 @@ impl Step for RustAnalyzer {
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Clippy {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Clippy {
@@ -1523,7 +1524,7 @@ impl Step for Clippy {
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Miri {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Miri {
@@ -1620,7 +1621,7 @@ impl Step for Miri {
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Rustfmt {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Rustfmt {
@@ -1714,8 +1715,8 @@ impl Step for Rustfmt {
#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Extended {
stage: u32,
host: Interned<String>,
target: Interned<String>,
host: TargetSelection,
target: TargetSelection,
}

impl Step for Extended {
@@ -2255,7 +2256,7 @@ impl Step for Extended {
}
}

fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: Interned<String>) {
fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
let mut parts = channel::CFG_RELEASE_NUM.split('.');
cmd.env("CFG_RELEASE_INFO", builder.rust_version())
.env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM)
@@ -2266,7 +2267,7 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: Interned<String>) {
.env("CFG_VER_BUILD", "0") // just needed to build
.env("CFG_PACKAGE_VERS", builder.rust_package_vers())
.env("CFG_PACKAGE_NAME", pkgname(builder, "rust"))
.env("CFG_BUILD", target)
.env("CFG_BUILD", target.triple)
.env("CFG_CHANNEL", &builder.config.channel);

if target.contains("windows-gnu") {
@@ -2348,7 +2349,7 @@ impl Step for HashSign {
///
/// Note: This function does not yet support Windows, but we also don't support
/// linking LLVM tools dynamically on Windows yet.
fn maybe_install_llvm(builder: &Builder<'_>, target: Interned<String>, dst_libdir: &Path) {
fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) {
let src_libdir = builder.llvm_out(target).join("lib");

if target.contains("apple-darwin") {
@@ -2373,21 +2374,21 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: Interned<String>, dst_libdi
}

/// Maybe add libLLVM.so to the target lib-dir for linking.
pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: Interned<String>, sysroot: &Path) {
let dst_libdir = sysroot.join("lib/rustlib").join(&*target).join("lib");
pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) {
let dst_libdir = sysroot.join("lib/rustlib").join(&*target.triple).join("lib");
maybe_install_llvm(builder, target, &dst_libdir);
}

/// Maybe add libLLVM.so to the runtime lib-dir for rustc itself.
pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: Interned<String>, sysroot: &Path) {
pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) {
let dst_libdir =
sysroot.join(builder.sysroot_libdir_relative(Compiler { stage: 1, host: target }));
maybe_install_llvm(builder, target, &dst_libdir);
}

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct LlvmTools {
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for LlvmTools {
@@ -2425,10 +2426,10 @@ impl Step for LlvmTools {

// Prepare the image directory
let src_bindir = builder.llvm_out(target).join("bin");
let dst_bindir = image.join("lib/rustlib").join(&*target).join("bin");
let dst_bindir = image.join("lib/rustlib").join(&*target.triple).join("bin");
t!(fs::create_dir_all(&dst_bindir));
for tool in LLVM_TOOLS {
let exe = src_bindir.join(exe(tool, &target));
let exe = src_bindir.join(exe(tool, target));
builder.install(&exe, &dst_bindir, 0o755);
}

30 changes: 15 additions & 15 deletions src/bootstrap/doc.rs
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@ use build_helper::{t, up_to_date};
use crate::builder::{Builder, Compiler, RunConfig, ShouldRun, Step};
use crate::cache::{Interned, INTERNER};
use crate::compile;
use crate::config::Config;
use crate::config::{Config, TargetSelection};
use crate::tool::{self, prepare_tool_cargo, SourceType, Tool};
use crate::util::symlink_dir;

@@ -27,7 +27,7 @@ macro_rules! book {
$(
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct $name {
target: Interned<String>,
target: TargetSelection,
}

impl Step for $name {
@@ -101,7 +101,7 @@ fn is_explicit_request(builder: &Builder<'_>, path: &str) -> bool {

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct UnstableBook {
target: Interned<String>,
target: TargetSelection,
}

impl Step for UnstableBook {
@@ -129,7 +129,7 @@ impl Step for UnstableBook {

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
struct RustbookSrc {
target: Interned<String>,
target: TargetSelection,
name: Interned<String>,
src: Interned<PathBuf>,
}
@@ -169,7 +169,7 @@ impl Step for RustbookSrc {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct TheBook {
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
}

impl Step for TheBook {
@@ -241,7 +241,7 @@ impl Step for TheBook {
fn invoke_rustdoc(
builder: &Builder<'_>,
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
markdown: &str,
) {
let out = builder.doc_out(target);
@@ -277,7 +277,7 @@ fn invoke_rustdoc(
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Standalone {
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
}

impl Step for Standalone {
@@ -386,7 +386,7 @@ impl Step for Standalone {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Std {
pub stage: u32,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Std {
@@ -415,7 +415,7 @@ impl Step for Std {
let compiler = builder.compiler(stage, builder.config.build);

builder.ensure(compile::Std { compiler, target });
let out_dir = builder.stage_out(compiler, Mode::Std).join(target).join("doc");
let out_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join("doc");

t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css")));

@@ -475,7 +475,7 @@ impl Step for Std {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Rustc {
stage: u32,
target: Interned<String>,
target: TargetSelection,
}

impl Step for Rustc {
@@ -522,7 +522,7 @@ impl Step for Rustc {
// needed because rustdoc is built in a different directory from
// rustc. rustdoc needs to be able to see everything, for example when
// merging the search index, or generating local (relative) links.
let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target).join("doc");
let out_dir = builder.stage_out(compiler, Mode::Rustc).join(target.triple).join("doc");
t!(symlink_dir_force(&builder.config, &out, &out_dir));

// Build cargo command.
@@ -559,7 +559,7 @@ impl Step for Rustc {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Rustdoc {
stage: u32,
target: Interned<String>,
target: TargetSelection,
}

impl Step for Rustdoc {
@@ -604,7 +604,7 @@ impl Step for Rustdoc {
builder.ensure(tool::Rustdoc { compiler });

// Symlink compiler docs to the output directory of rustdoc documentation.
let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target).join("doc");
let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc");
t!(fs::create_dir_all(&out_dir));
t!(symlink_dir_force(&builder.config, &out, &out_dir));

@@ -632,7 +632,7 @@ impl Step for Rustdoc {
#[derive(Ord, PartialOrd, Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct ErrorIndex {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for ErrorIndex {
@@ -672,7 +672,7 @@ impl Step for ErrorIndex {

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct UnstableBookGen {
target: Interned<String>,
target: TargetSelection,
}

impl Step for UnstableBookGen {
11 changes: 5 additions & 6 deletions src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
@@ -10,8 +10,7 @@ use std::process;
use getopts::Options;

use crate::builder::Builder;
use crate::cache::{Interned, INTERNER};
use crate::config::Config;
use crate::config::{Config, TargetSelection};
use crate::{Build, DocTests};

/// Deserialized version of all flags for this compile.
@@ -21,8 +20,8 @@ pub struct Flags {
pub stage: Option<u32>,
pub keep_stage: Vec<u32>,

pub host: Vec<Interned<String>>,
pub target: Vec<Interned<String>>,
pub host: Vec<TargetSelection>,
pub target: Vec<TargetSelection>,
pub config: Option<PathBuf>,
pub jobs: Option<u32>,
pub cmd: Subcommand,
@@ -532,11 +531,11 @@ Arguments:
.collect(),
host: split(&matches.opt_strs("host"))
.into_iter()
.map(|x| INTERNER.intern_string(x))
.map(|x| TargetSelection::from_user(&x))
.collect::<Vec<_>>(),
target: split(&matches.opt_strs("target"))
.into_iter()
.map(|x| INTERNER.intern_string(x))
.map(|x| TargetSelection::from_user(&x))
.collect::<Vec<_>>(),
config: cfg_file,
jobs: matches.opt_str("jobs").map(|j| j.parse().expect("`jobs` should be a number")),
29 changes: 15 additions & 14 deletions src/bootstrap/install.rs
Original file line number Diff line number Diff line change
@@ -14,46 +14,47 @@ use crate::dist::{self, pkgname, sanitize_sh, tmpdir};
use crate::Compiler;

use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::cache::Interned;
use crate::config::Config;
use crate::config::{Config, TargetSelection};

pub fn install_docs(builder: &Builder<'_>, stage: u32, host: Interned<String>) {
pub fn install_docs(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "docs", "rust-docs", stage, Some(host));
}

pub fn install_std(builder: &Builder<'_>, stage: u32, target: Interned<String>) {
pub fn install_std(builder: &Builder<'_>, stage: u32, target: TargetSelection) {
install_sh(builder, "std", "rust-std", stage, Some(target));
}

pub fn install_cargo(builder: &Builder<'_>, stage: u32, host: Interned<String>) {
pub fn install_cargo(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "cargo", "cargo", stage, Some(host));
}

pub fn install_rls(builder: &Builder<'_>, stage: u32, host: Interned<String>) {
pub fn install_rls(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "rls", "rls", stage, Some(host));
}
pub fn install_rust_analyzer(builder: &Builder<'_>, stage: u32, host: Interned<String>) {

pub fn install_rust_analyzer(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "rust-analyzer", "rust-analyzer", stage, Some(host));
}
pub fn install_clippy(builder: &Builder<'_>, stage: u32, host: Interned<String>) {

pub fn install_clippy(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "clippy", "clippy", stage, Some(host));
}
pub fn install_miri(builder: &Builder<'_>, stage: u32, host: Interned<String>) {
pub fn install_miri(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "miri", "miri", stage, Some(host));
}

pub fn install_rustfmt(builder: &Builder<'_>, stage: u32, host: Interned<String>) {
pub fn install_rustfmt(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "rustfmt", "rustfmt", stage, Some(host));
}

pub fn install_analysis(builder: &Builder<'_>, stage: u32, host: Interned<String>) {
pub fn install_analysis(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "analysis", "rust-analysis", stage, Some(host));
}

pub fn install_src(builder: &Builder<'_>, stage: u32) {
install_sh(builder, "src", "rust-src", stage, None);
}
pub fn install_rustc(builder: &Builder<'_>, stage: u32, host: Interned<String>) {
pub fn install_rustc(builder: &Builder<'_>, stage: u32, host: TargetSelection) {
install_sh(builder, "rustc", "rustc", stage, Some(host));
}

@@ -62,7 +63,7 @@ fn install_sh(
package: &str,
name: &str,
stage: u32,
host: Option<Interned<String>>,
host: Option<TargetSelection>,
) {
builder.info(&format!("Install {} stage{} ({:?})", package, stage, host));

@@ -150,7 +151,7 @@ macro_rules! install {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct $name {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl $name {
106 changes: 55 additions & 51 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
@@ -123,6 +123,7 @@ use std::os::windows::fs::symlink_file;
use build_helper::{mtime, output, run, run_suppressed, t, try_run, try_run_suppressed};
use filetime::FileTime;

use crate::config::TargetSelection;
use crate::util::{exe, libdir, CiEnv};

mod builder;
@@ -187,7 +188,7 @@ const LLVM_TOOLS: &[&str] = &[
#[derive(Eq, PartialOrd, Ord, PartialEq, Clone, Copy, Hash, Debug)]
pub struct Compiler {
stage: u32,
host: Interned<String>,
host: TargetSelection,
}

#[derive(PartialEq, Eq, Copy, Clone, Debug)]
@@ -236,9 +237,9 @@ pub struct Build {
verbosity: usize,

// Targets for which to build
build: Interned<String>,
hosts: Vec<Interned<String>>,
targets: Vec<Interned<String>>,
build: TargetSelection,
hosts: Vec<TargetSelection>,
targets: Vec<TargetSelection>,

// Stage 0 (downloaded) compiler, lld and cargo or their local rust equivalents
initial_rustc: PathBuf,
@@ -248,18 +249,18 @@ pub struct Build {

// Runtime state filled in later on
// C/C++ compilers and archiver for all targets
cc: HashMap<Interned<String>, cc::Tool>,
cxx: HashMap<Interned<String>, cc::Tool>,
ar: HashMap<Interned<String>, PathBuf>,
ranlib: HashMap<Interned<String>, PathBuf>,
cc: HashMap<TargetSelection, cc::Tool>,
cxx: HashMap<TargetSelection, cc::Tool>,
ar: HashMap<TargetSelection, PathBuf>,
ranlib: HashMap<TargetSelection, PathBuf>,
// Miscellaneous
crates: HashMap<Interned<String>, Crate>,
is_sudo: bool,
ci_env: CiEnv,
delayed_failures: RefCell<Vec<String>>,
prerelease_version: Cell<Option<u32>>,
tool_artifacts:
RefCell<HashMap<Interned<String>, HashMap<String, (&'static str, PathBuf, Vec<String>)>>>,
RefCell<HashMap<TargetSelection, HashMap<String, (&'static str, PathBuf, Vec<String>)>>>,
}

#[derive(Debug)]
@@ -365,7 +366,7 @@ impl Build {
output(
Command::new(&config.initial_rustc)
.arg("--target")
.arg(config.build)
.arg(config.build.rustc_target_arg())
.arg("--print")
.arg("target-libdir"),
)
@@ -453,7 +454,7 @@ impl Build {
}

pub fn build_triple(&self) -> &[Interned<String>] {
unsafe { slice::from_raw_parts(&self.build, 1) }
slice::from_ref(&self.build.triple)
}

/// Executes the entire build, as configured by the flags and configuration.
@@ -558,7 +559,10 @@ impl Build {
}

fn tools_dir(&self, compiler: Compiler) -> PathBuf {
let out = self.out.join(&*compiler.host).join(format!("stage{}-tools-bin", compiler.stage));
let out = self
.out
.join(&*compiler.host.triple)
.join(format!("stage{}-tools-bin", compiler.stage));
t!(fs::create_dir_all(&out));
out
}
@@ -575,69 +579,69 @@ impl Build {
Mode::ToolBootstrap => "-bootstrap-tools",
Mode::ToolStd | Mode::ToolRustc => "-tools",
};
self.out.join(&*compiler.host).join(format!("stage{}{}", compiler.stage, suffix))
self.out.join(&*compiler.host.triple).join(format!("stage{}{}", compiler.stage, suffix))
}

/// Returns the root output directory for all Cargo output in a given stage,
/// running a particular compiler, whether or not we're building the
/// standard library, and targeting the specified architecture.
fn cargo_out(&self, compiler: Compiler, mode: Mode, target: Interned<String>) -> PathBuf {
self.stage_out(compiler, mode).join(&*target).join(self.cargo_dir())
fn cargo_out(&self, compiler: Compiler, mode: Mode, target: TargetSelection) -> PathBuf {
self.stage_out(compiler, mode).join(&*target.triple).join(self.cargo_dir())
}

/// Root output directory for LLVM compiled for `target`
///
/// Note that if LLVM is configured externally then the directory returned
/// will likely be empty.
fn llvm_out(&self, target: Interned<String>) -> PathBuf {
self.out.join(&*target).join("llvm")
fn llvm_out(&self, target: TargetSelection) -> PathBuf {
self.out.join(&*target.triple).join("llvm")
}

fn lld_out(&self, target: Interned<String>) -> PathBuf {
self.out.join(&*target).join("lld")
fn lld_out(&self, target: TargetSelection) -> PathBuf {
self.out.join(&*target.triple).join("lld")
}

/// Output directory for all documentation for a target
fn doc_out(&self, target: Interned<String>) -> PathBuf {
self.out.join(&*target).join("doc")
fn doc_out(&self, target: TargetSelection) -> PathBuf {
self.out.join(&*target.triple).join("doc")
}

/// Output directory for all documentation for a target
fn compiler_doc_out(&self, target: Interned<String>) -> PathBuf {
self.out.join(&*target).join("compiler-doc")
fn compiler_doc_out(&self, target: TargetSelection) -> PathBuf {
self.out.join(&*target.triple).join("compiler-doc")
}

/// Output directory for some generated md crate documentation for a target (temporary)
fn md_doc_out(&self, target: Interned<String>) -> Interned<PathBuf> {
INTERNER.intern_path(self.out.join(&*target).join("md-doc"))
fn md_doc_out(&self, target: TargetSelection) -> Interned<PathBuf> {
INTERNER.intern_path(self.out.join(&*target.triple).join("md-doc"))
}

/// Returns `true` if no custom `llvm-config` is set for the specified target.
///
/// If no custom `llvm-config` was specified then Rust's llvm will be used.
fn is_rust_llvm(&self, target: Interned<String>) -> bool {
fn is_rust_llvm(&self, target: TargetSelection) -> bool {
match self.config.target_config.get(&target) {
Some(ref c) => c.llvm_config.is_none(),
None => true,
}
}

/// Returns the path to `FileCheck` binary for the specified target
fn llvm_filecheck(&self, target: Interned<String>) -> PathBuf {
fn llvm_filecheck(&self, target: TargetSelection) -> PathBuf {
let target_config = self.config.target_config.get(&target);
if let Some(s) = target_config.and_then(|c| c.llvm_filecheck.as_ref()) {
s.to_path_buf()
} else if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) {
let llvm_bindir = output(Command::new(s).arg("--bindir"));
let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", &*target));
let filecheck = Path::new(llvm_bindir.trim()).join(exe("FileCheck", target));
if filecheck.exists() {
filecheck
} else {
// On Fedora the system LLVM installs FileCheck in the
// llvm subdirectory of the libdir.
let llvm_libdir = output(Command::new(s).arg("--libdir"));
let lib_filecheck =
Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", &*target));
Path::new(llvm_libdir.trim()).join("llvm").join(exe("FileCheck", target));
if lib_filecheck.exists() {
lib_filecheck
} else {
@@ -662,18 +666,18 @@ impl Build {
} else {
base
};
base.join("bin").join(exe("FileCheck", &*target))
base.join("bin").join(exe("FileCheck", target))
}
}

/// Directory for libraries built from C/C++ code and shared between stages.
fn native_dir(&self, target: Interned<String>) -> PathBuf {
self.out.join(&*target).join("native")
fn native_dir(&self, target: TargetSelection) -> PathBuf {
self.out.join(&*target.triple).join("native")
}

/// Root output directory for rust_test_helpers library compiled for
/// `target`
fn test_helpers_out(&self, target: Interned<String>) -> PathBuf {
fn test_helpers_out(&self, target: TargetSelection) -> PathBuf {
self.native_dir(target).join("rust-test-helpers")
}

@@ -686,7 +690,7 @@ impl Build {

/// Returns the libdir of the snapshot compiler.
fn rustc_snapshot_libdir(&self) -> PathBuf {
self.rustc_snapshot_sysroot().join(libdir(&self.config.build))
self.rustc_snapshot_sysroot().join(libdir(self.config.build))
}

/// Returns the sysroot of the snapshot compiler.
@@ -784,13 +788,13 @@ impl Build {
}

/// Returns the path to the C compiler for the target specified.
fn cc(&self, target: Interned<String>) -> &Path {
fn cc(&self, target: TargetSelection) -> &Path {
self.cc[&target].path()
}

/// Returns a list of flags to pass to the C compiler for the target
/// specified.
fn cflags(&self, target: Interned<String>, which: GitRepo) -> Vec<String> {
fn cflags(&self, target: TargetSelection, which: GitRepo) -> Vec<String> {
// Filter out -O and /O (the optimization flags) that we picked up from
// cc-rs because the build scripts will determine that for themselves.
let mut base = self.cc[&target]
@@ -811,7 +815,7 @@ impl Build {
// Work around an apparently bad MinGW / GCC optimization,
// See: http://lists.llvm.org/pipermail/cfe-dev/2016-December/051980.html
// See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78936
if &*target == "i686-pc-windows-gnu" {
if &*target.triple == "i686-pc-windows-gnu" {
base.push("-fno-omit-frame-pointer".into());
}

@@ -829,17 +833,17 @@ impl Build {
}

/// Returns the path to the `ar` archive utility for the target specified.
fn ar(&self, target: Interned<String>) -> Option<&Path> {
fn ar(&self, target: TargetSelection) -> Option<&Path> {
self.ar.get(&target).map(|p| &**p)
}

/// Returns the path to the `ranlib` utility for the target specified.
fn ranlib(&self, target: Interned<String>) -> Option<&Path> {
fn ranlib(&self, target: TargetSelection) -> Option<&Path> {
self.ranlib.get(&target).map(|p| &**p)
}

/// Returns the path to the C++ compiler for the target specified.
fn cxx(&self, target: Interned<String>) -> Result<&Path, String> {
fn cxx(&self, target: TargetSelection) -> Result<&Path, String> {
match self.cxx.get(&target) {
Some(p) => Ok(p.path()),
None => {
@@ -849,12 +853,12 @@ impl Build {
}

/// Returns the path to the linker for the given target if it needs to be overridden.
fn linker(&self, target: Interned<String>, can_use_lld: bool) -> Option<&Path> {
fn linker(&self, target: TargetSelection, can_use_lld: bool) -> Option<&Path> {
if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref())
{
Some(linker)
} else if target != self.config.build
&& util::use_host_linker(&target)
&& util::use_host_linker(target)
&& !target.contains("msvc")
{
Some(self.cc(target))
@@ -866,7 +870,7 @@ impl Build {
}

/// Returns if this target should statically link the C runtime, if specified
fn crt_static(&self, target: Interned<String>) -> Option<bool> {
fn crt_static(&self, target: TargetSelection) -> Option<bool> {
if target.contains("pc-windows-msvc") {
Some(true)
} else {
@@ -875,7 +879,7 @@ impl Build {
}

/// Returns the "musl root" for this `target`, if defined
fn musl_root(&self, target: Interned<String>) -> Option<&Path> {
fn musl_root(&self, target: TargetSelection) -> Option<&Path> {
self.config
.target_config
.get(&target)
@@ -885,7 +889,7 @@ impl Build {
}

/// Returns the "musl libdir" for this `target`.
fn musl_libdir(&self, target: Interned<String>) -> Option<PathBuf> {
fn musl_libdir(&self, target: TargetSelection) -> Option<PathBuf> {
let t = self.config.target_config.get(&target)?;
if let libdir @ Some(_) = &t.musl_libdir {
return libdir.clone();
@@ -894,18 +898,18 @@ impl Build {
}

/// Returns the sysroot for the wasi target, if defined
fn wasi_root(&self, target: Interned<String>) -> Option<&Path> {
fn wasi_root(&self, target: TargetSelection) -> Option<&Path> {
self.config.target_config.get(&target).and_then(|t| t.wasi_root.as_ref()).map(|p| &**p)
}

/// Returns `true` if this is a no-std `target`, if defined
fn no_std(&self, target: Interned<String>) -> Option<bool> {
fn no_std(&self, target: TargetSelection) -> Option<bool> {
self.config.target_config.get(&target).map(|t| t.no_std)
}

/// Returns `true` if the target will be tested using the `remote-test-client`
/// and `remote-test-server` binaries.
fn remote_tested(&self, target: Interned<String>) -> bool {
fn remote_tested(&self, target: TargetSelection) -> bool {
self.qemu_rootfs(target).is_some()
|| target.contains("android")
|| env::var_os("TEST_DEVICE_ADDR").is_some()
@@ -916,7 +920,7 @@ impl Build {
///
/// If `Some` is returned then that means that tests for this target are
/// emulated with QEMU and binaries will need to be shipped to the emulator.
fn qemu_rootfs(&self, target: Interned<String>) -> Option<&Path> {
fn qemu_rootfs(&self, target: TargetSelection) -> Option<&Path> {
self.config.target_config.get(&target).and_then(|t| t.qemu_rootfs.as_ref()).map(|p| &**p)
}

@@ -948,7 +952,7 @@ impl Build {
///
/// When all of these conditions are met the build will lift artifacts from
/// the previous stage forward.
fn force_use_stage1(&self, compiler: Compiler, target: Interned<String>) -> bool {
fn force_use_stage1(&self, compiler: Compiler, target: TargetSelection) -> bool {
!self.config.full_bootstrap
&& compiler.stage >= 2
&& (self.hosts.iter().any(|h| *h == target) || target == self.build)
@@ -1058,7 +1062,7 @@ impl Build {
self.rust_version()
}

fn llvm_link_tools_dynamically(&self, target: Interned<String>) -> bool {
fn llvm_link_tools_dynamically(&self, target: TargetSelection) -> bool {
target.contains("linux-gnu") || target.contains("apple-darwin")
}

39 changes: 20 additions & 19 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
@@ -19,8 +19,8 @@ use std::process::Command;
use build_helper::{output, t};

use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::cache::Interned;
use crate::channel;
use crate::config::TargetSelection;
use crate::util::{self, exe};
use crate::GitRepo;
use build_helper::up_to_date;
@@ -41,7 +41,7 @@ pub struct Meta {
// if not).
pub fn prebuilt_llvm_config(
builder: &Builder<'_>,
target: Interned<String>,
target: TargetSelection,
) -> Result<PathBuf, Meta> {
// If we're using a custom LLVM bail out here, but we can only use a
// custom LLVM for the build triple.
@@ -54,13 +54,14 @@ pub fn prebuilt_llvm_config(

let root = "src/llvm-project/llvm";
let out_dir = builder.llvm_out(target);

let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
if !builder.config.build.contains("msvc") || builder.config.ninja {
llvm_config_ret_dir.push("build");
}
llvm_config_ret_dir.push("bin");

let build_llvm_config = llvm_config_ret_dir.join(exe("llvm-config", &*builder.config.build));
let build_llvm_config = llvm_config_ret_dir.join(exe("llvm-config", builder.config.build));

let stamp = out_dir.join("llvm-finished-building");
let stamp = HashStamp::new(stamp, builder.in_tree_llvm_info.sha());
@@ -93,7 +94,7 @@ pub fn prebuilt_llvm_config(

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Llvm {
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Llvm {
@@ -115,9 +116,9 @@ impl Step for Llvm {
let target_native = if self.target.starts_with("riscv") {
// RISC-V target triples in Rust is not named the same as C compiler target triples.
// This converts Rust RISC-V target triples to C compiler triples.
let idx = target.find('-').unwrap();
let idx = target.triple.find('-').unwrap();

format!("riscv{}{}", &target[5..7], &target[idx..])
format!("riscv{}{}", &target.triple[5..7], &target.triple[idx..])
} else {
target.to_string()
};
@@ -359,7 +360,7 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {

fn configure_cmake(
builder: &Builder<'_>,
target: Interned<String>,
target: TargetSelection,
cfg: &mut cmake::Config,
use_compiler_launcher: bool,
) {
@@ -375,7 +376,7 @@ fn configure_cmake(
if builder.config.ninja {
cfg.generator("Ninja");
}
cfg.target(&target).host(&builder.config.build);
cfg.target(&target.triple).host(&builder.config.build.triple);

let sanitize_cc = |cc: &Path| {
if target.contains("msvc") {
@@ -405,7 +406,7 @@ fn configure_cmake(
cfg.define("CMAKE_C_COMPILER", sanitize_cc(&wrap_cc))
.define("CMAKE_CXX_COMPILER", sanitize_cc(&wrap_cc));
cfg.env("SCCACHE_PATH", builder.config.ccache.as_ref().unwrap())
.env("SCCACHE_TARGET", target)
.env("SCCACHE_TARGET", target.triple)
.env("SCCACHE_CC", &cc)
.env("SCCACHE_CXX", &cxx);

@@ -505,7 +506,7 @@ fn configure_cmake(

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Lld {
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Lld {
@@ -578,8 +579,8 @@ impl Step for Lld {
// brittle and will break over time. If anyone knows better how to
// cross-compile LLD it would be much appreciated to fix this!
if target != builder.config.build {
cfg.env("LLVM_CONFIG_SHIM_REPLACE", &builder.config.build)
.env("LLVM_CONFIG_SHIM_REPLACE_WITH", &target)
cfg.env("LLVM_CONFIG_SHIM_REPLACE", &builder.config.build.triple)
.env("LLVM_CONFIG_SHIM_REPLACE_WITH", &target.triple)
.define(
"LLVM_TABLEGEN_EXE",
llvm_config.with_file_name("llvm-tblgen").with_extension(EXE_EXTENSION),
@@ -599,7 +600,7 @@ impl Step for Lld {

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct TestHelpers {
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for TestHelpers {
@@ -646,8 +647,8 @@ impl Step for TestHelpers {

cfg.cargo_metadata(false)
.out_dir(&dst)
.target(&target)
.host(&builder.config.build)
.target(&target.triple)
.host(&builder.config.build.triple)
.opt_level(0)
.warnings(false)
.debug(false)
@@ -658,7 +659,7 @@ impl Step for TestHelpers {

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Sanitizers {
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Sanitizers {
@@ -709,7 +710,7 @@ impl Step for Sanitizers {

let mut cfg = cmake::Config::new(&compiler_rt_dir);
cfg.profile("Release");
cfg.define("CMAKE_C_COMPILER_TARGET", self.target);
cfg.define("CMAKE_C_COMPILER_TARGET", self.target.triple);
cfg.define("COMPILER_RT_BUILD_BUILTINS", "OFF");
cfg.define("COMPILER_RT_BUILD_CRT", "OFF");
cfg.define("COMPILER_RT_BUILD_LIBFUZZER", "OFF");
@@ -752,7 +753,7 @@ pub struct SanitizerRuntime {
/// Returns sanitizers available on a given target.
fn supported_sanitizers(
out_dir: &Path,
target: Interned<String>,
target: TargetSelection,
channel: &str,
) -> Vec<SanitizerRuntime> {
let darwin_libs = |os: &str, components: &[&str]| -> Vec<SanitizerRuntime> {
@@ -778,7 +779,7 @@ fn supported_sanitizers(
.collect()
};

match &*target {
match &*target.triple {
"aarch64-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]),
"aarch64-unknown-linux-gnu" => {
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan"])
6 changes: 5 additions & 1 deletion src/bootstrap/sanity.rs
Original file line number Diff line number Diff line change
@@ -183,7 +183,11 @@ pub fn check(build: &mut Build) {
panic!("the iOS target is only supported on macOS");
}

build.config.target_config.entry(target.clone()).or_insert(Target::from_triple(target));
build
.config
.target_config
.entry(target.clone())
.or_insert(Target::from_triple(&target.triple));

if target.contains("-none-") || target.contains("nvptx") {
if build.no_std(*target) == Some(false) {
69 changes: 37 additions & 32 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ use build_helper::{self, output, t};
use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
use crate::cache::{Interned, INTERNER};
use crate::compile;
use crate::config::TargetSelection;
use crate::dist;
use crate::flags::Subcommand;
use crate::native;
@@ -93,7 +94,7 @@ fn try_run_quiet(builder: &Builder<'_>, cmd: &mut Command) -> bool {

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Linkcheck {
host: Interned<String>,
host: TargetSelection,
}

impl Step for Linkcheck {
@@ -115,7 +116,7 @@ impl Step for Linkcheck {
let _time = util::timeit(&builder);
try_run(
builder,
builder.tool_cmd(Tool::Linkchecker).arg(builder.out.join(host).join("doc")),
builder.tool_cmd(Tool::Linkchecker).arg(builder.out.join(host.triple).join("doc")),
);
}

@@ -132,7 +133,7 @@ impl Step for Linkcheck {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Cargotest {
stage: u32,
host: Interned<String>,
host: TargetSelection,
}

impl Step for Cargotest {
@@ -177,7 +178,7 @@ impl Step for Cargotest {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Cargo {
stage: u32,
host: Interned<String>,
host: TargetSelection,
}

impl Step for Cargo {
@@ -230,7 +231,7 @@ impl Step for Cargo {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Rls {
stage: u32,
host: Interned<String>,
host: TargetSelection,
}

impl Step for Rls {
@@ -281,7 +282,7 @@ impl Step for Rls {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Rustfmt {
stage: u32,
host: Interned<String>,
host: TargetSelection,
}

impl Step for Rustfmt {
@@ -338,7 +339,7 @@ impl Step for Rustfmt {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Miri {
stage: u32,
host: Interned<String>,
host: TargetSelection,
}

impl Step for Miri {
@@ -464,7 +465,7 @@ impl Step for Miri {

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CompiletestTest {
host: Interned<String>,
host: TargetSelection,
}

impl Step for CompiletestTest {
@@ -501,7 +502,7 @@ impl Step for CompiletestTest {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Clippy {
stage: u32,
host: Interned<String>,
host: TargetSelection,
}

impl Step for Clippy {
@@ -542,8 +543,10 @@ impl Step for Clippy {
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
let host_libs = builder.stage_out(compiler, Mode::ToolRustc).join(builder.cargo_dir());
let target_libs =
builder.stage_out(compiler, Mode::ToolRustc).join(&self.host).join(builder.cargo_dir());
let target_libs = builder
.stage_out(compiler, Mode::ToolRustc)
.join(&self.host.triple)
.join(builder.cargo_dir());
cargo.env("HOST_LIBS", host_libs);
cargo.env("TARGET_LIBS", target_libs);
// clippy tests need to find the driver
@@ -607,7 +610,7 @@ impl Step for RustdocTheme {

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustdocJSStd {
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for RustdocJSStd {
@@ -646,8 +649,8 @@ impl Step for RustdocJSStd {

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustdocJSNotStd {
pub host: Interned<String>,
pub target: Interned<String>,
pub host: TargetSelection,
pub target: TargetSelection,
pub compiler: Compiler,
}

@@ -683,8 +686,8 @@ impl Step for RustdocJSNotStd {

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RustdocUi {
pub host: Interned<String>,
pub target: Interned<String>,
pub host: TargetSelection,
pub target: TargetSelection,
pub compiler: Compiler,
}

@@ -785,8 +788,8 @@ impl Step for ExpandYamlAnchors {
}
}

fn testdir(builder: &Builder<'_>, host: Interned<String>) -> PathBuf {
builder.out.join(host).join("test")
fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf {
builder.out.join(host.triple).join("test")
}

macro_rules! default_test {
@@ -855,7 +858,7 @@ macro_rules! test_definitions {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct $name {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for $name {
@@ -943,7 +946,7 @@ default_test!(Assembly { path: "src/test/assembly", mode: "assembly", suite: "as
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
struct Compiletest {
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
mode: &'static str,
suite: &'static str,
path: &'static str,
@@ -1023,8 +1026,8 @@ impl Step for Compiletest {
cmd.arg("--build-base").arg(testdir(builder, compiler.host).join(suite));
cmd.arg("--stage-id").arg(format!("stage{}-{}", compiler.stage, target));
cmd.arg("--mode").arg(mode);
cmd.arg("--target").arg(target);
cmd.arg("--host").arg(&*compiler.host);
cmd.arg("--target").arg(target.rustc_target_arg());
cmd.arg("--host").arg(&*compiler.host.triple);
cmd.arg("--llvm-filecheck").arg(builder.llvm_filecheck(builder.config.build));

if builder.config.cmd.bless() {
@@ -1543,7 +1546,7 @@ impl Step for RustcGuide {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CrateLibrustc {
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
test_kind: TestKind,
krate: Interned<String>,
}
@@ -1589,7 +1592,7 @@ impl Step for CrateLibrustc {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CrateNotDefault {
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
test_kind: TestKind,
krate: &'static str,
}
@@ -1638,7 +1641,7 @@ impl Step for CrateNotDefault {
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Crate {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
pub mode: Mode,
pub test_kind: TestKind,
pub krate: Interned<String>,
@@ -1750,17 +1753,17 @@ impl Step for Crate {

if target.contains("emscripten") {
cargo.env(
format!("CARGO_TARGET_{}_RUNNER", envify(&target)),
format!("CARGO_TARGET_{}_RUNNER", envify(&target.triple)),
builder.config.nodejs.as_ref().expect("nodejs not configured"),
);
} else if target.starts_with("wasm32") {
let node = builder.config.nodejs.as_ref().expect("nodejs not configured");
let runner =
format!("{} {}/src/etc/wasm32-shim.js", node.display(), builder.src.display());
cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)), &runner);
cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target.triple)), &runner);
} else if builder.remote_tested(target) {
cargo.env(
format!("CARGO_TARGET_{}_RUNNER", envify(&target)),
format!("CARGO_TARGET_{}_RUNNER", envify(&target.triple)),
format!("{} run 0", builder.tool_exe(Tool::RemoteTestClient).display()),
);
}
@@ -1776,7 +1779,7 @@ impl Step for Crate {

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct CrateRustdoc {
host: Interned<String>,
host: TargetSelection,
test_kind: TestKind,
}

@@ -1883,7 +1886,7 @@ impl Step for CrateRustdoc {
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct RemoteCopyLibs {
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
}

impl Step for RemoteCopyLibs {
@@ -1911,7 +1914,7 @@ impl Step for RemoteCopyLibs {
// Spawn the emulator and wait for it to come online
let tool = builder.tool_exe(Tool::RemoteTestClient);
let mut cmd = Command::new(&tool);
cmd.arg("spawn-emulator").arg(target).arg(&server).arg(builder.out.join("tmp"));
cmd.arg("spawn-emulator").arg(target.triple).arg(&server).arg(builder.out.join("tmp"));
if let Some(rootfs) = builder.qemu_rootfs(target) {
cmd.arg(rootfs);
}
@@ -1966,7 +1969,9 @@ impl Step for Distcheck {
.current_dir(&dir),
);
builder.run(
Command::new(build_helper::make(&builder.config.build)).arg("check").current_dir(&dir),
Command::new(build_helper::make(&builder.config.build.triple))
.arg("check")
.current_dir(&dir),
);

// Now make sure that rust-src has all of libstd's dependencies
26 changes: 13 additions & 13 deletions src/bootstrap/tool.rs
Original file line number Diff line number Diff line change
@@ -7,10 +7,10 @@ use std::process::{exit, Command};
use build_helper::t;

use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step};
use crate::cache::Interned;
use crate::channel;
use crate::channel::GitInfo;
use crate::compile;
use crate::config::TargetSelection;
use crate::toolstate::ToolState;
use crate::util::{add_dylib_path, exe};
use crate::Compiler;
@@ -25,7 +25,7 @@ pub enum SourceType {
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
struct ToolBuild {
compiler: Compiler,
target: Interned<String>,
target: TargetSelection,
tool: &'static str,
path: &'static str,
mode: Mode,
@@ -111,7 +111,7 @@ impl Step for ToolBuild {
.and_then(|p| p.file_name())
.and_then(|p| p.to_str())
.unwrap();
if maybe_target != &*target {
if maybe_target != &*target.triple {
continue;
}
}
@@ -208,8 +208,8 @@ impl Step for ToolBuild {
}
} else {
let cargo_out =
builder.cargo_out(compiler, self.mode, target).join(exe(tool, &compiler.host));
let bin = builder.tools_dir(compiler).join(exe(tool, &compiler.host));
builder.cargo_out(compiler, self.mode, target).join(exe(tool, compiler.host));
let bin = builder.tools_dir(compiler).join(exe(tool, compiler.host));
builder.copy(&cargo_out, &bin);
Some(bin)
}
@@ -220,7 +220,7 @@ pub fn prepare_tool_cargo(
builder: &Builder<'_>,
compiler: Compiler,
mode: Mode,
target: Interned<String>,
target: TargetSelection,
command: &'static str,
path: &'static str,
source_type: SourceType,
@@ -303,7 +303,7 @@ macro_rules! bootstrap_tool {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct $name {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for $name {
@@ -416,7 +416,7 @@ impl Step for ErrorIndex {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct RemoteTestServer {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for RemoteTestServer {
@@ -476,7 +476,7 @@ impl Step for Rustdoc {
if !target_compiler.is_snapshot(builder) {
panic!("rustdoc in stage 0 must be snapshot rustdoc");
}
return builder.initial_rustc.with_file_name(exe("rustdoc", &target_compiler.host));
return builder.initial_rustc.with_file_name(exe("rustdoc", target_compiler.host));
}
let target = target_compiler.host;
// Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise
@@ -514,14 +514,14 @@ impl Step for Rustdoc {
// rustdoc a different name.
let tool_rustdoc = builder
.cargo_out(build_compiler, Mode::ToolRustc, target)
.join(exe("rustdoc_tool_binary", &target_compiler.host));
.join(exe("rustdoc_tool_binary", target_compiler.host));

// don't create a stage0-sysroot/bin directory.
if target_compiler.stage > 0 {
let sysroot = builder.sysroot(target_compiler);
let bindir = sysroot.join("bin");
t!(fs::create_dir_all(&bindir));
let bin_rustdoc = bindir.join(exe("rustdoc", &*target_compiler.host));
let bin_rustdoc = bindir.join(exe("rustdoc", target_compiler.host));
let _ = fs::remove_file(&bin_rustdoc);
builder.copy(&tool_rustdoc, &bin_rustdoc);
bin_rustdoc
@@ -534,7 +534,7 @@ impl Step for Rustdoc {
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Cargo {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
}

impl Step for Cargo {
@@ -583,7 +583,7 @@ macro_rules! tool_extended {
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct $name {
pub compiler: Compiler,
pub target: Interned<String>,
pub target: TargetSelection,
pub extra_features: Vec<String>,
}

11 changes: 5 additions & 6 deletions src/bootstrap/util.rs
Original file line number Diff line number Diff line change
@@ -14,17 +14,16 @@ use std::time::Instant;
use build_helper::t;

use crate::builder::Builder;
use crate::cache::Interned;
use crate::config::Config;
use crate::config::{Config, TargetSelection};

/// Returns the `name` as the filename of a static library for `target`.
pub fn staticlib(name: &str, target: &str) -> String {
pub fn staticlib(name: &str, target: TargetSelection) -> String {
if target.contains("windows") { format!("{}.lib", name) } else { format!("lib{}.a", name) }
}

/// Given an executable called `name`, return the filename for the
/// executable for a particular target.
pub fn exe(name: &str, target: &str) -> String {
pub fn exe(name: &str, target: TargetSelection) -> String {
if target.contains("windows") { format!("{}.exe", name) } else { name.to_string() }
}

@@ -35,7 +34,7 @@ pub fn is_dylib(name: &str) -> bool {

/// Returns the corresponding relative library directory that the compiler's
/// dylibs will be found in.
pub fn libdir(target: &str) -> &'static str {
pub fn libdir(target: TargetSelection) -> &'static str {
if target.contains("windows") { "bin" } else { "lib" }
}

@@ -294,7 +293,7 @@ pub fn forcing_clang_based_tests() -> bool {
}
}

pub fn use_host_linker(target: &Interned<String>) -> bool {
pub fn use_host_linker(target: TargetSelection) -> bool {
// FIXME: this information should be gotten by checking the linker flavor
// of the rustc target
!(target.contains("emscripten")