about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhilipp Oppermann <dev@phil-opp.com>2018-03-14 15:27:06 +0100
committerPhilipp Oppermann <dev@phil-opp.com>2018-03-26 18:57:23 +0200
commit3908b2e4438e89a4f9503a8fa3e378ecc127df45 (patch)
tree3ded54857fe37b54ed959275528fff1794d7d579
parentb4aa80dd73df9708022cc383aad8da1dcf38d1df (diff)
downloadrust-3908b2e4438e89a4f9503a8fa3e378ecc127df45.tar.gz
rust-3908b2e4438e89a4f9503a8fa3e378ecc127df45.zip
Introduce a TargetTriple enum to support absolute target paths
-rw-r--r--src/librustc/session/config.rs22
-rw-r--r--src/librustc/session/mod.rs7
-rw-r--r--src/librustc_back/target/mod.rs89
-rw-r--r--src/librustc_metadata/creader.rs12
-rw-r--r--src/librustc_metadata/locator.rs10
-rw-r--r--src/librustc_metadata/schema.rs3
-rw-r--r--src/librustc_trans/abi.rs2
-rw-r--r--src/librustc_trans/back/link.rs7
-rw-r--r--src/librustc_trans/back/write.rs4
-rw-r--r--src/librustc_trans/base.rs3
-rw-r--r--src/librustdoc/core.rs6
-rw-r--r--src/librustdoc/lib.rs9
12 files changed, 118 insertions, 56 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index d24da1ff7c8..092b84e3ffe 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -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;
@@ -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],
@@ -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(),
@@ -1903,9 +1903,15 @@ 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") {
+            TargetTriple::TargetPath(PathBuf::from(target))
+        } else {
+            TargetTriple::TargetTriple(target)
+        }
+    } else {
+        TargetTriple::from_triple(host_triple())
+    };
     let opt_level = {
         if matches.opt_present("O") {
             if cg.opt_level.is_some() {
@@ -2113,7 +2119,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,
@@ -2264,6 +2270,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);
@@ -2323,6 +2330,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);
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 556255e06ed..77cf50a8341 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -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;
 
@@ -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,
         )
@@ -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
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index f53eeb86a9c..ca73a755784 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -47,6 +47,8 @@
 use serialize::json::{Json, ToJson};
 use std::collections::BTreeMap;
 use std::default::Default;
+use std::fmt;
+use std::path::{Path, PathBuf};
 use syntax::abi::{Abi, lookup as lookup_abi};
 
 use {LinkerFlavor, PanicStrategy, RelroLevel};
@@ -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> {
@@ -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))
     }
 }
 
@@ -1014,3 +1020,36 @@ 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 target from the passed target triple string.
+    pub fn from_triple(triple: &str) -> Self {
+        TargetTriple::TargetTriple(triple.to_string())
+    }
+
+    /// 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")
+            }
+        }
+    }
+}
+
+impl fmt::Display for TargetTriple {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.triple())
+    }
+}
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index baaf57c8908..616fbc6cac5 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -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};
@@ -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![],
@@ -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() {
@@ -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,
@@ -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![],
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index c56674bd6c5..41e10b4755d 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -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;
@@ -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>,
@@ -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");
@@ -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;
         }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 98327945297..d04a4001c50 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -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};
@@ -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,
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index 44c18c371a4..9adcdf56e86 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -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)
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs
index 542cdc5baad..c4dbbff4593 100644
--- a/src/librustc_trans/back/link.rs
+++ b/src/librustc_trans/back/link.rs
@@ -31,6 +31,7 @@ use rustc::util::fs::fix_windows_verbatim_for_gcc;
 use rustc::hir::def_id::CrateNum;
 use tempdir::TempDir;
 use rustc_back::{PanicStrategy, RelroLevel};
+use rustc_back::target::TargetTriple;
 use context::get_reloc_model;
 use llvm;
 
@@ -81,7 +82,7 @@ pub fn get_linker(sess: &Session) -> (PathBuf, Command) {
         }
     };
 
-    let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple, "link.exe");
+    let msvc_tool = windows_registry::find_tool(&sess.opts.target_triple.triple(), "link.exe");
 
     let linker_path = sess.opts.cg.linker.as_ref().map(|s| &**s)
         .or(sess.target.target.options.linker.as_ref().map(|s| s.as_ref()))
@@ -812,7 +813,7 @@ fn link_natively(sess: &Session,
         }
     }
 
-    if sess.opts.target_triple == "wasm32-unknown-unknown" {
+    if sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown") {
         wasm::rewrite_imports(&out_filename, &trans.crate_info.wasm_imports);
         wasm::add_custom_sections(&out_filename,
                                   &trans.crate_info.wasm_custom_sections);
@@ -1090,7 +1091,7 @@ fn link_args(cmd: &mut Linker,
     // addl_lib_search_paths
     if sess.opts.cg.rpath {
         let sysroot = sess.sysroot();
-        let target_triple = &sess.opts.target_triple;
+        let target_triple = sess.opts.target_triple.triple();
         let mut get_install_prefix_lib_path = || {
             let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
             let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 3e7422557e9..adf5e4a8a71 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -848,7 +848,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
         "rustc.embedded.module\0".as_ptr() as *const _,
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
-    let section = if cgcx.opts.target_triple.contains("-ios") {
+    let section = if cgcx.opts.target_triple.triple().contains("-ios") {
         "__LLVM,__bitcode\0"
     } else {
         ".llvmbc\0"
@@ -863,7 +863,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
         "rustc.embedded.cmdline\0".as_ptr() as *const _,
     );
     llvm::LLVMSetInitializer(llglobal, llconst);
-    let section = if cgcx.opts.target_triple.contains("-ios") {
+    let section = if cgcx.opts.target_triple.triple().contains("-ios") {
         "__LLVM,__cmdline\0"
     } else {
         ".llvmcmd\0"
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index 56eece9f31e..0ce26f2295e 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -73,6 +73,7 @@ use type_of::LayoutLlvmExt;
 use rustc::util::nodemap::{FxHashMap, FxHashSet, DefIdSet};
 use CrateInfo;
 use rustc_data_structures::sync::Lrc;
+use rustc_back::target::TargetTriple;
 
 use std::any::Any;
 use std::collections::BTreeMap;
@@ -1079,7 +1080,7 @@ impl CrateInfo {
         let load_wasm_items = tcx.sess.crate_types.borrow()
             .iter()
             .any(|c| *c != config::CrateTypeRlib) &&
-            tcx.sess.opts.target_triple == "wasm32-unknown-unknown";
+            tcx.sess.opts.target_triple == TargetTriple::from_triple("wasm32-unknown-unknown");
 
         if load_wasm_items {
             info!("attempting to load all wasm sections");
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 1e0fafc8d9d..0bf3a8f368d 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -22,6 +22,7 @@ use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_resolve as resolve;
 use rustc_metadata::creader::CrateLoader;
 use rustc_metadata::cstore::CStore;
+use rustc_back::target::TargetTriple;
 
 use syntax::ast::NodeId;
 use syntax::codemap;
@@ -116,7 +117,7 @@ pub fn run_core(search_paths: SearchPaths,
                 cfgs: Vec<String>,
                 externs: config::Externs,
                 input: Input,
-                triple: Option<String>,
+                triple: Option<TargetTriple>,
                 maybe_sysroot: Option<PathBuf>,
                 allow_warnings: bool,
                 crate_name: Option<String>,
@@ -131,6 +132,7 @@ pub fn run_core(search_paths: SearchPaths,
 
     let warning_lint = lint::builtin::WARNINGS.name_lower();
 
+    let host_triple = TargetTriple::from_triple(config::host_triple());
     let sessopts = config::Options {
         maybe_sysroot,
         search_paths,
@@ -138,7 +140,7 @@ pub fn run_core(search_paths: SearchPaths,
         lint_opts: if !allow_warnings { vec![(warning_lint, lint::Allow)] } else { vec![] },
         lint_cap: Some(lint::Allow),
         externs,
-        target_triple: triple.unwrap_or(config::host_triple().to_string()),
+        target_triple: triple.unwrap_or(host_triple),
         // Ensure that rustdoc works even if rustc is feature-staged
         unstable_features: UnstableFeatures::Allow,
         actually_rustdoc: true,
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index bec25a98227..0339a58d582 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -64,6 +64,7 @@ use std::sync::mpsc::channel;
 use externalfiles::ExternalHtml;
 use rustc::session::search_paths::SearchPaths;
 use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options, Externs};
+use rustc_back::target::TargetTriple;
 
 #[macro_use]
 pub mod externalfiles;
@@ -542,7 +543,13 @@ where R: 'static + Send, F: 'static + Send + FnOnce(Output) -> R {
         paths.add_path(s, ErrorOutputType::default());
     }
     let cfgs = matches.opt_strs("cfg");
-    let triple = matches.opt_str("target");
+    let triple = matches.opt_str("target").map(|target| {
+        if target.ends_with(".json") {
+            TargetTriple::TargetPath(PathBuf::from(target))
+        } else {
+            TargetTriple::TargetTriple(target)
+        }
+    });
     let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
     let crate_name = matches.opt_str("crate-name");
     let crate_version = matches.opt_str("crate-version");