Skip to content

Commit 3908b2e

Browse files
committed
Introduce a TargetTriple enum to support absolute target paths
1 parent b4aa80d commit 3908b2e

File tree

12 files changed

+118
-56
lines changed

12 files changed

+118
-56
lines changed

src/librustc/session/config.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use session::search_paths::SearchPaths;
2121

2222
use ich::StableHashingContext;
2323
use rustc_back::{LinkerFlavor, PanicStrategy, RelroLevel};
24-
use rustc_back::target::Target;
24+
use rustc_back::target::{Target, TargetTriple};
2525
use rustc_data_structures::stable_hasher::ToStableHashKey;
2626
use lint;
2727
use middle::cstore;
@@ -367,7 +367,7 @@ top_level_options!(
367367
libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
368368
maybe_sysroot: Option<PathBuf> [TRACKED],
369369

370-
target_triple: String [TRACKED],
370+
target_triple: TargetTriple [TRACKED],
371371

372372
test: bool [TRACKED],
373373
error_format: ErrorOutputType [UNTRACKED],
@@ -567,7 +567,7 @@ pub fn basic_options() -> Options {
567567
output_types: OutputTypes(BTreeMap::new()),
568568
search_paths: SearchPaths::new(),
569569
maybe_sysroot: None,
570-
target_triple: host_triple().to_string(),
570+
target_triple: TargetTriple::from_triple(host_triple()),
571571
test: false,
572572
incremental: None,
573573
debugging_opts: basic_debugging_options(),
@@ -1903,9 +1903,15 @@ pub fn build_session_options_and_crate_config(
19031903
let cg = cg;
19041904

19051905
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
1906-
let target = matches
1907-
.opt_str("target")
1908-
.unwrap_or(host_triple().to_string());
1906+
let target_triple = if let Some(target) = matches.opt_str("target") {
1907+
if target.ends_with(".json") {
1908+
TargetTriple::TargetPath(PathBuf::from(target))
1909+
} else {
1910+
TargetTriple::TargetTriple(target)
1911+
}
1912+
} else {
1913+
TargetTriple::from_triple(host_triple())
1914+
};
19091915
let opt_level = {
19101916
if matches.opt_present("O") {
19111917
if cg.opt_level.is_some() {
@@ -2113,7 +2119,7 @@ pub fn build_session_options_and_crate_config(
21132119
output_types: OutputTypes(output_types),
21142120
search_paths,
21152121
maybe_sysroot: sysroot_opt,
2116-
target_triple: target,
2122+
target_triple,
21172123
test,
21182124
incremental,
21192125
debugging_opts,
@@ -2264,6 +2270,7 @@ mod dep_tracking {
22642270
Passes, Sanitizer};
22652271
use syntax::feature_gate::UnstableFeatures;
22662272
use rustc_back::{PanicStrategy, RelroLevel};
2273+
use rustc_back::target::TargetTriple;
22672274

22682275
pub trait DepTrackingHash {
22692276
fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType);
@@ -2323,6 +2330,7 @@ mod dep_tracking {
23232330
impl_dep_tracking_hash_via_hash!(Sanitizer);
23242331
impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
23252332
impl_dep_tracking_hash_via_hash!(Edition);
2333+
impl_dep_tracking_hash_via_hash!(TargetTriple);
23262334

23272335
impl_dep_tracking_hash_for_sortable_vec_of!(String);
23282336
impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);

src/librustc/session/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use syntax::feature_gate::AttributeType;
4242
use syntax_pos::{MultiSpan, Span};
4343

4444
use rustc_back::{LinkerFlavor, PanicStrategy};
45-
use rustc_back::target::Target;
45+
use rustc_back::target::{Target, TargetTriple};
4646
use rustc_data_structures::flock;
4747
use jobserver::Client;
4848

@@ -707,7 +707,7 @@ impl Session {
707707
pub fn target_filesearch(&self, kind: PathKind) -> filesearch::FileSearch {
708708
filesearch::FileSearch::new(
709709
self.sysroot(),
710-
&self.opts.target_triple,
710+
self.opts.target_triple.triple(),
711711
&self.opts.search_paths,
712712
kind,
713713
)
@@ -1085,7 +1085,8 @@ pub fn build_session_(
10851085
span_diagnostic: errors::Handler,
10861086
codemap: Lrc<codemap::CodeMap>,
10871087
) -> Session {
1088-
let host = match Target::search(config::host_triple()) {
1088+
let host_triple = TargetTriple::from_triple(config::host_triple());
1089+
let host = match Target::search(&host_triple) {
10891090
Ok(t) => t,
10901091
Err(e) => {
10911092
span_diagnostic

src/librustc_back/target/mod.rs

+64-25
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
use serialize::json::{Json, ToJson};
4848
use std::collections::BTreeMap;
4949
use std::default::Default;
50+
use std::fmt;
51+
use std::path::{Path, PathBuf};
5052
use syntax::abi::{Abi, lookup as lookup_abi};
5153

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

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

841-
if let Ok(t) = load_specific(target) {
842-
return Ok(t)
843-
}
844-
845-
let path = Path::new(target);
846-
847-
if path.is_file() {
848-
return load_file(&path);
849-
}
842+
match target_triple {
843+
&TargetTriple::TargetTriple(ref target_triple) => {
844+
// check if triple is in list of supported targets
845+
if let Ok(t) = load_specific(target_triple) {
846+
return Ok(t)
847+
}
850848

851-
let path = {
852-
let mut target = target.to_string();
853-
target.push_str(".json");
854-
PathBuf::from(target)
855-
};
849+
// search for a file named `target_triple`.json in RUST_TARGET_PATH
850+
let path = {
851+
let mut target = target_triple.to_string();
852+
target.push_str(".json");
853+
PathBuf::from(target)
854+
};
856855

857-
let target_path = env::var_os("RUST_TARGET_PATH")
858-
.unwrap_or(OsString::new());
856+
let target_path = env::var_os("RUST_TARGET_PATH")
857+
.unwrap_or(OsString::new());
859858

860-
// FIXME 16351: add a sane default search path?
859+
// FIXME 16351: add a sane default search path?
861860

862-
for dir in env::split_paths(&target_path) {
863-
let p = dir.join(&path);
864-
if p.is_file() {
865-
return load_file(&p);
861+
for dir in env::split_paths(&target_path) {
862+
let p = dir.join(&path);
863+
if p.is_file() {
864+
return load_file(&p);
865+
}
866+
}
867+
Err(format!("Could not find specification for target {:?}", target_triple))
868+
}
869+
&TargetTriple::TargetPath(ref target_path) => {
870+
if target_path.is_file() {
871+
return load_file(&target_path);
872+
}
873+
Err(format!("Target path {:?} is not a valid file", target_path))
866874
}
867875
}
868-
869-
Err(format!("Could not find specification for target {:?}", target))
870876
}
871877
}
872878

@@ -1014,3 +1020,36 @@ fn maybe_jemalloc() -> Option<String> {
10141020
None
10151021
}
10161022
}
1023+
1024+
/// Either a target triple string or a path to a JSON file.
1025+
#[derive(PartialEq, Clone, Debug, Hash, RustcEncodable, RustcDecodable)]
1026+
pub enum TargetTriple {
1027+
TargetTriple(String),
1028+
TargetPath(PathBuf),
1029+
}
1030+
1031+
impl TargetTriple {
1032+
/// Creates a target target from the passed target triple string.
1033+
pub fn from_triple(triple: &str) -> Self {
1034+
TargetTriple::TargetTriple(triple.to_string())
1035+
}
1036+
1037+
/// Returns a string triple for this target.
1038+
///
1039+
/// If this target is a path, the file name (without extension) is returned.
1040+
pub fn triple(&self) -> &str {
1041+
match self {
1042+
&TargetTriple::TargetTriple(ref triple) => triple,
1043+
&TargetTriple::TargetPath(ref path) => {
1044+
path.file_stem().expect("target path must not be empty").to_str()
1045+
.expect("target path must be valid unicode")
1046+
}
1047+
}
1048+
}
1049+
}
1050+
1051+
impl fmt::Display for TargetTriple {
1052+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1053+
write!(f, "{}", self.triple())
1054+
}
1055+
}

src/librustc_metadata/creader.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc::middle::cstore::DepKind;
2222
use rustc::session::{Session, CrateDisambiguator};
2323
use rustc::session::config::{Sanitizer, self};
2424
use rustc_back::PanicStrategy;
25+
use rustc_back::target::TargetTriple;
2526
use rustc::session::search_paths::PathKind;
2627
use rustc::middle;
2728
use rustc::middle::cstore::{validate_crate_name, ExternCrate};
@@ -295,7 +296,7 @@ impl<'a> CrateLoader<'a> {
295296

296297
let mut proc_macro_locator = locator::Context {
297298
target: &self.sess.host,
298-
triple: config::host_triple(),
299+
triple: &TargetTriple::from_triple(config::host_triple()),
299300
filesearch: self.sess.host_filesearch(path_kind),
300301
rejected_via_hash: vec![],
301302
rejected_via_triple: vec![],
@@ -339,7 +340,7 @@ impl<'a> CrateLoader<'a> {
339340
// don't want to match a host crate against an equivalent target one
340341
// already loaded.
341342
let root = library.metadata.get_root();
342-
if locate_ctxt.triple == self.sess.opts.target_triple {
343+
if locate_ctxt.triple == &self.sess.opts.target_triple {
343344
let mut result = LoadResult::Loaded(library);
344345
self.cstore.iter_crate_data(|cnum, data| {
345346
if data.name() == root.name && root.hash == data.hash() {
@@ -426,8 +427,9 @@ impl<'a> CrateLoader<'a> {
426427
fn read_extension_crate(&mut self, span: Span, orig_name: Symbol, rename: Symbol)
427428
-> ExtensionCrate {
428429
info!("read extension crate `extern crate {} as {}`", orig_name, rename);
429-
let target_triple = &self.sess.opts.target_triple[..];
430-
let is_cross = target_triple != config::host_triple();
430+
let target_triple = &self.sess.opts.target_triple;
431+
let host_triple = TargetTriple::from_triple(config::host_triple());
432+
let is_cross = target_triple != &host_triple;
431433
let mut target_only = false;
432434
let mut locate_ctxt = locator::Context {
433435
sess: self.sess,
@@ -437,7 +439,7 @@ impl<'a> CrateLoader<'a> {
437439
hash: None,
438440
filesearch: self.sess.host_filesearch(PathKind::Crate),
439441
target: &self.sess.host,
440-
triple: config::host_triple(),
442+
triple: &host_triple,
441443
root: &None,
442444
rejected_via_hash: vec![],
443445
rejected_via_triple: vec![],

src/librustc_metadata/locator.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ use rustc::util::nodemap::FxHashMap;
233233
use errors::DiagnosticBuilder;
234234
use syntax::symbol::Symbol;
235235
use syntax_pos::Span;
236-
use rustc_back::target::Target;
236+
use rustc_back::target::{Target, TargetTriple};
237237

238238
use std::cmp;
239239
use std::fmt;
@@ -258,7 +258,7 @@ pub struct Context<'a> {
258258
pub hash: Option<&'a Svh>,
259259
// points to either self.sess.target.target or self.sess.host, must match triple
260260
pub target: &'a Target,
261-
pub triple: &'a str,
261+
pub triple: &'a TargetTriple,
262262
pub filesearch: FileSearch<'a>,
263263
pub root: &'a Option<CratePaths>,
264264
pub rejected_via_hash: Vec<CrateMismatch>,
@@ -394,7 +394,7 @@ impl<'a> Context<'a> {
394394
add);
395395

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

701-
if root.triple != self.triple {
701+
if &root.triple != self.triple {
702702
info!("Rejecting via crate triple: expected {} got {}",
703703
self.triple,
704704
root.triple);
705705
self.rejected_via_triple.push(CrateMismatch {
706706
path: libpath.to_path_buf(),
707-
got: root.triple,
707+
got: format!("{}", root.triple),
708708
});
709709
return None;
710710
}

src/librustc_metadata/schema.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc::mir;
2222
use rustc::session::CrateDisambiguator;
2323
use rustc::ty::{self, Ty, ReprOptions};
2424
use rustc_back::PanicStrategy;
25+
use rustc_back::target::TargetTriple;
2526

2627
use rustc_serialize as serialize;
2728
use syntax::{ast, attr};
@@ -186,7 +187,7 @@ pub enum LazyState {
186187
#[derive(RustcEncodable, RustcDecodable)]
187188
pub struct CrateRoot {
188189
pub name: Symbol,
189-
pub triple: String,
190+
pub triple: TargetTriple,
190191
pub hash: hir::svh::Svh,
191192
pub disambiguator: CrateDisambiguator,
192193
pub panic_strategy: PanicStrategy,

src/librustc_trans/abi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,7 @@ impl<'a, 'tcx> FnType<'tcx> {
950950
"s390x" => cabi_s390x::compute_abi_info(cx, self),
951951
"asmjs" => cabi_asmjs::compute_abi_info(cx, self),
952952
"wasm32" => {
953-
if cx.sess().opts.target_triple.contains("emscripten") {
953+
if cx.sess().opts.target_triple.triple().contains("emscripten") {
954954
cabi_asmjs::compute_abi_info(cx, self)
955955
} else {
956956
cabi_wasm32::compute_abi_info(cx, self)

src/librustc_trans/back/link.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc::util::fs::fix_windows_verbatim_for_gcc;
3131
use rustc::hir::def_id::CrateNum;
3232
use tempdir::TempDir;
3333
use rustc_back::{PanicStrategy, RelroLevel};
34+
use rustc_back::target::TargetTriple;
3435
use context::get_reloc_model;
3536
use llvm;
3637

@@ -81,7 +82,7 @@ pub fn get_linker(sess: &Session) -> (PathBuf, Command) {
8182
}
8283
};
8384

84-
let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple, "link.exe");
85+
let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe");
8586

8687
let linker_path = sess.opts.cg.linker.as_ref().map(|s| &**s)
8788
.or(sess.target.target.options.linker.as_ref().map(|s| s.as_ref()))
@@ -812,7 +813,7 @@ fn link_natively(sess: &Session,
812813
}
813814
}
814815

815-
if sess.opts.target_triple == "wasm32-unknown-unknown" {
816+
if sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown") {
816817
wasm::rewrite_imports(&out_filename, &trans.crate_info.wasm_imports);
817818
wasm::add_custom_sections(&out_filename,
818819
&trans.crate_info.wasm_custom_sections);
@@ -1090,7 +1091,7 @@ fn link_args(cmd: &mut Linker,
10901091
// addl_lib_search_paths
10911092
if sess.opts.cg.rpath {
10921093
let sysroot = sess.sysroot();
1093-
let target_triple = &sess.opts.target_triple;
1094+
let target_triple = sess.opts.target_triple.triple();
10941095
let mut get_install_prefix_lib_path = || {
10951096
let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
10961097
let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);

src/librustc_trans/back/write.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
848848
"rustc.embedded.module\0".as_ptr() as *const _,
849849
);
850850
llvm::LLVMSetInitializer(llglobal, llconst);
851-
let section = if cgcx.opts.target_triple.contains("-ios") {
851+
let section = if cgcx.opts.target_triple.triple().contains("-ios") {
852852
"__LLVM,__bitcode\0"
853853
} else {
854854
".llvmbc\0"
@@ -863,7 +863,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
863863
"rustc.embedded.cmdline\0".as_ptr() as *const _,
864864
);
865865
llvm::LLVMSetInitializer(llglobal, llconst);
866-
let section = if cgcx.opts.target_triple.contains("-ios") {
866+
let section = if cgcx.opts.target_triple.triple().contains("-ios") {
867867
"__LLVM,__cmdline\0"
868868
} else {
869869
".llvmcmd\0"

0 commit comments

Comments
 (0)