Skip to content
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

Introduce a TargetTriple enum to support absolute target paths #49019

Merged
merged 3 commits into from
Mar 28, 2018
Merged
Show file tree
Hide file tree
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
30 changes: 22 additions & 8 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use session::search_paths::SearchPaths;

use ich::StableHashingContext;
use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel};
use rustc_back::target::Target;
use rustc_back::target::{Target, TargetTriple};
use rustc_data_structures::stable_hasher::ToStableHashKey;
use lint;
use middle::cstore;
Expand All @@ -47,7 +47,7 @@ use std::hash::Hasher;
use std::collections::hash_map::DefaultHasher;
use std::collections::HashSet;
use std::iter::FromIterator;
use std::path::PathBuf;
use std::path::{Path, PathBuf};

pub struct Config {
pub target: Target,
Expand Down Expand Up @@ -367,7 +367,7 @@ top_level_options!(
libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
maybe_sysroot: Option<PathBuf> [TRACKED],

target_triple: String [TRACKED],
target_triple: TargetTriple [TRACKED],

test: bool [TRACKED],
error_format: ErrorOutputType [UNTRACKED],
Expand Down Expand Up @@ -567,7 +567,7 @@ pub fn basic_options() -> Options {
output_types: OutputTypes(BTreeMap::new()),
search_paths: SearchPaths::new(),
maybe_sysroot: None,
target_triple: host_triple().to_string(),
target_triple: TargetTriple::from_triple(host_triple()),
test: false,
incremental: None,
debugging_opts: basic_debugging_options(),
Expand Down Expand Up @@ -1903,9 +1903,21 @@ pub fn build_session_options_and_crate_config(
let cg = cg;

let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
let target = matches
.opt_str("target")
.unwrap_or(host_triple().to_string());
let target_triple = if let Some(target) = matches.opt_str("target") {
if target.ends_with(".json") {
let path = Path::new(&target);
match TargetTriple::from_path(&path) {
Ok(triple) => triple,
Err(_) => {
early_error(error_format, &format!("target file {:?} does not exist", path))
}
}
} else {
TargetTriple::TargetTriple(target)
}
} else {
TargetTriple::from_triple(host_triple())
};
let opt_level = {
if matches.opt_present("O") {
if cg.opt_level.is_some() {
Expand Down Expand Up @@ -2113,7 +2125,7 @@ pub fn build_session_options_and_crate_config(
output_types: OutputTypes(output_types),
search_paths,
maybe_sysroot: sysroot_opt,
target_triple: target,
target_triple,
test,
incremental,
debugging_opts,
Expand Down Expand Up @@ -2264,6 +2276,7 @@ mod dep_tracking {
Passes, Sanitizer};
use syntax::feature_gate::UnstableFeatures;
use rustc_back::{PanicStrategy, RelroLevel};
use rustc_back::target::TargetTriple;

pub trait DepTrackingHash {
fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType);
Expand Down Expand Up @@ -2323,6 +2336,7 @@ mod dep_tracking {
impl_dep_tracking_hash_via_hash!(Sanitizer);
impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
impl_dep_tracking_hash_via_hash!(Edition);
impl_dep_tracking_hash_via_hash!(TargetTriple);

impl_dep_tracking_hash_for_sortable_vec_of!(String);
impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
Expand Down
7 changes: 4 additions & 3 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use syntax::feature_gate::AttributeType;
use syntax_pos::{MultiSpan, Span};

use rustc_back::{LinkerFlavor, PanicStrategy};
use rustc_back::target::Target;
use rustc_back::target::{Target, TargetTriple};
use rustc_data_structures::flock;
use jobserver::Client;

Expand Down Expand Up @@ -707,7 +707,7 @@ impl Session {
pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch {
filesearch::FileSearch::new(
self.sysroot(),
&self.opts.target_triple,
self.opts.target_triple.triple(),
&self.opts.search_paths,
kind,
)
Expand Down Expand Up @@ -1085,7 +1085,8 @@ pub fn build_session_(
span_diagnostic: errors::Handler,
codemap: Lrc<codemap::CodeMap>,
) -> Session {
let host = match Target::search(config::host_triple()) {
let host_triple = TargetTriple::from_triple(config::host_triple());
let host = match Target::search(&host_triple) {
Ok(t) => t,
Err(e) => {
span_diagnostic
Expand Down
114 changes: 89 additions & 25 deletions src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
use serialize::json::{Json, ToJson};
use std::collections::BTreeMap;
use std::default::Default;
use std::{fmt, io};
use std::path::{Path, PathBuf};
use syntax::abi::{Abi, lookup as lookup_abi};

use {LinkerFlavor, PanicStrategy, RelroLevel};
Expand Down Expand Up @@ -824,11 +826,10 @@ impl Target {
///
/// The error string could come from any of the APIs called, including
/// filesystem access and JSON decoding.
pub fn search(target: &str) -> Result<Target, String> {
pub fn search(target_triple: &TargetTriple) -> Result<Target, String> {
use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{Path, PathBuf};
use serialize::json;

fn load_file(path: &Path) -> Result<Target, String> {
Expand All @@ -838,35 +839,40 @@ impl Target {
Target::from_json(obj)
}

if let Ok(t) = load_specific(target) {
return Ok(t)
}

let path = Path::new(target);

if path.is_file() {
return load_file(&path);
}
match target_triple {
&TargetTriple::TargetTriple(ref target_triple) => {
// check if triple is in list of supported targets
if let Ok(t) = load_specific(target_triple) {
return Ok(t)
}

let path = {
let mut target = target.to_string();
target.push_str(".json");
PathBuf::from(target)
};
// search for a file named `target_triple`.json in RUST_TARGET_PATH
let path = {
let mut target = target_triple.to_string();
target.push_str(".json");
PathBuf::from(target)
};

let target_path = env::var_os("RUST_TARGET_PATH")
.unwrap_or(OsString::new());
let target_path = env::var_os("RUST_TARGET_PATH")
.unwrap_or(OsString::new());

// FIXME 16351: add a sane default search path?
// FIXME 16351: add a sane default search path?

for dir in env::split_paths(&target_path) {
let p = dir.join(&path);
if p.is_file() {
return load_file(&p);
for dir in env::split_paths(&target_path) {
let p = dir.join(&path);
if p.is_file() {
return load_file(&p);
}
}
Err(format!("Could not find specification for target {:?}", target_triple))
}
&TargetTriple::TargetPath(ref target_path) => {
if target_path.is_file() {
return load_file(&target_path);
}
Err(format!("Target path {:?} is not a valid file", target_path))
}
}

Err(format!("Could not find specification for target {:?}", target))
}
}

Expand Down Expand Up @@ -1014,3 +1020,61 @@ fn maybe_jemalloc() -> Option<String> {
None
}
}

/// Either a target triple string or a path to a JSON file.
#[derive(PartialEq, Clone, Debug, Hash, RustcEncodable, RustcDecodable)]
pub enum TargetTriple {
TargetTriple(String),
TargetPath(PathBuf),
}

impl TargetTriple {
/// Creates a target triple from the passed target triple string.
pub fn from_triple(triple: &str) -> Self {
TargetTriple::TargetTriple(triple.to_string())
}

/// Creates a target triple from the passed target path.
pub fn from_path(path: &Path) -> Result<Self, io::Error> {
let canonicalized_path = path.canonicalize()?;
Ok(TargetTriple::TargetPath(canonicalized_path))
}

/// Returns a string triple for this target.
///
/// If this target is a path, the file name (without extension) is returned.
pub fn triple(&self) -> &str {
match self {
&TargetTriple::TargetTriple(ref triple) => triple,
&TargetTriple::TargetPath(ref path) => {
path.file_stem().expect("target path must not be empty").to_str()
.expect("target path must be valid unicode")
}
}
}

/// Returns an extended string triple for this target.
///
/// If this target is a path, a hash of the path is appended to the triple returned
/// by `triple()`.
pub fn debug_triple(&self) -> String {
use std::hash::{Hash, Hasher};
use std::collections::hash_map::DefaultHasher;

let triple = self.triple();
if let &TargetTriple::TargetPath(ref path) = self {
let mut hasher = DefaultHasher::new();
path.hash(&mut hasher);
let hash = hasher.finish();
format!("{}-{}", triple, hash)
} else {
triple.to_owned()
}
}
}

impl fmt::Display for TargetTriple {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.debug_triple())
}
}
12 changes: 7 additions & 5 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use rustc::middle::cstore::DepKind;
use rustc::session::{Session, CrateDisambiguator};
use rustc::session::config::{Sanitizer, self};
use rustc_back::PanicStrategy;
use rustc_back::target::TargetTriple;
use rustc::session::search_paths::PathKind;
use rustc::middle;
use rustc::middle::cstore::{validate_crate_name, ExternCrate};
Expand Down Expand Up @@ -295,7 +296,7 @@ impl<'a> CrateLoader<'a> {

let mut proc_macro_locator = locator::Context {
target: &self.sess.host,
triple: config::host_triple(),
triple: &TargetTriple::from_triple(config::host_triple()),
filesearch: self.sess.host_filesearch(path_kind),
rejected_via_hash: vec![],
rejected_via_triple: vec![],
Expand Down Expand Up @@ -339,7 +340,7 @@ impl<'a> CrateLoader<'a> {
// don't want to match a host crate against an equivalent target one
// already loaded.
let root = library.metadata.get_root();
if locate_ctxt.triple == self.sess.opts.target_triple {
if locate_ctxt.triple == &self.sess.opts.target_triple {
let mut result = LoadResult::Loaded(library);
self.cstore.iter_crate_data(|cnum, data| {
if data.name() == root.name && root.hash == data.hash() {
Expand Down Expand Up @@ -426,8 +427,9 @@ impl<'a> CrateLoader<'a> {
fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol)
-> ExtensionCrate {
info!("read extension crate `extern crate {} as {}`", orig_name, rename);
let target_triple = &self.sess.opts.target_triple[..];
let is_cross = target_triple != config::host_triple();
let target_triple = &self.sess.opts.target_triple;
let host_triple = TargetTriple::from_triple(config::host_triple());
let is_cross = target_triple != &host_triple;
let mut target_only = false;
let mut locate_ctxt = locator::Context {
sess: self.sess,
Expand All @@ -437,7 +439,7 @@ impl<'a> CrateLoader<'a> {
hash: None,
filesearch: self.sess.host_filesearch(PathKind::Crate),
target: &self.sess.host,
triple: config::host_triple(),
triple: &host_triple,
root: &None,
rejected_via_hash: vec![],
rejected_via_triple: vec![],
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_metadata/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ use rustc::util::nodemap::FxHashMap;
use errors::DiagnosticBuilder;
use syntax::symbol::Symbol;
use syntax_pos::Span;
use rustc_back::target::Target;
use rustc_back::target::{Target, TargetTriple};

use std::cmp;
use std::fmt;
Expand All @@ -258,7 +258,7 @@ pub struct Context<'a> {
pub hash: Option<&'a Svh>,
// points to either self.sess.target.target or self.sess.host, must match triple
pub target: &'a Target,
pub triple: &'a str,
pub triple: &'a TargetTriple,
pub filesearch: FileSearch<'a>,
pub root: &'a Option<CratePaths>,
pub rejected_via_hash: Vec<CrateMismatch>,
Expand Down Expand Up @@ -394,7 +394,7 @@ impl<'a> Context<'a> {
add);

if (self.ident == "std" || self.ident == "core")
&& self.triple != config::host_triple() {
&& self.triple != &TargetTriple::from_triple(config::host_triple()) {
err.note(&format!("the `{}` target may not be installed", self.triple));
}
err.span_label(self.span, "can't find crate");
Expand Down Expand Up @@ -698,13 +698,13 @@ impl<'a> Context<'a> {
}
}

if root.triple != self.triple {
if &root.triple != self.triple {
info!("Rejecting via crate triple: expected {} got {}",
self.triple,
root.triple);
self.rejected_via_triple.push(CrateMismatch {
path: libpath.to_path_buf(),
got: root.triple,
got: format!("{}", root.triple),
});
return None;
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_metadata/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use rustc::mir;
use rustc::session::CrateDisambiguator;
use rustc::ty::{self, Ty, ReprOptions};
use rustc_back::PanicStrategy;
use rustc_back::target::TargetTriple;

use rustc_serialize as serialize;
use syntax::{ast, attr};
Expand Down Expand Up @@ -186,7 +187,7 @@ pub enum LazyState {
#[derive(RustcEncodable, RustcDecodable)]
pub struct CrateRoot {
pub name: Symbol,
pub triple: String,
pub triple: TargetTriple,
pub hash: hir::svh::Svh,
pub disambiguator: CrateDisambiguator,
pub panic_strategy: PanicStrategy,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trans/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ impl<'a, 'tcx> FnType<'tcx> {
"s390x" => cabi_s390x::compute_abi_info(cx, self),
"asmjs" => cabi_asmjs::compute_abi_info(cx, self),
"wasm32" => {
if cx.sess().opts.target_triple.contains("emscripten") {
if cx.sess().opts.target_triple.triple().contains("emscripten") {
cabi_asmjs::compute_abi_info(cx, self)
} else {
cabi_wasm32::compute_abi_info(cx, self)
Expand Down
Loading