about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_session/src/config.rs9
-rw-r--r--compiler/rustc_session/src/session.rs13
-rw-r--r--compiler/rustc_target/src/spec/mod.rs17
3 files changed, 27 insertions, 12 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 6956b815f19..44007974a15 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -893,8 +893,13 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
     user_cfg
 }
 
-pub(super) fn build_target_config(opts: &Options, target_override: Option<Target>) -> Target {
-    let target_result = target_override.map_or_else(|| Target::search(&opts.target_triple), Ok);
+pub(super) fn build_target_config(
+    opts: &Options,
+    target_override: Option<Target>,
+    sysroot: &PathBuf,
+) -> Target {
+    let target_result =
+        target_override.map_or_else(|| Target::search(&opts.target_triple, sysroot), Ok);
     let target = target_result.unwrap_or_else(|e| {
         early_error(
             opts.error_format,
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index acb2a1ae7ef..66b0f5c11be 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -1276,9 +1276,14 @@ pub fn build_session(
         DiagnosticOutput::Raw(write) => Some(write),
     };
 
-    let target_cfg = config::build_target_config(&sopts, target_override);
+    let sysroot = match &sopts.maybe_sysroot {
+        Some(sysroot) => sysroot.clone(),
+        None => filesearch::get_or_default_sysroot(),
+    };
+
+    let target_cfg = config::build_target_config(&sopts, target_override, &sysroot);
     let host_triple = TargetTriple::from_triple(config::host_triple());
-    let host = Target::search(&host_triple).unwrap_or_else(|e| {
+    let host = Target::search(&host_triple, &sysroot).unwrap_or_else(|e| {
         early_error(sopts.error_format, &format!("Error loading host specification: {}", e))
     });
 
@@ -1325,10 +1330,6 @@ pub fn build_session(
 
     let mut parse_sess = ParseSess::with_span_handler(span_diagnostic, source_map);
     parse_sess.assume_incomplete_release = sopts.debugging_opts.assume_incomplete_release;
-    let sysroot = match &sopts.maybe_sysroot {
-        Some(sysroot) => sysroot.clone(),
-        None => filesearch::get_or_default_sysroot(),
-    };
 
     let host_triple = config::host_triple();
     let target_triple = sopts.target_triple.triple();
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index dfc97447ce0..27ca6a23a96 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1898,13 +1898,15 @@ impl Target {
     }
 
     /// Search RUST_TARGET_PATH for a JSON file specifying the given target
-    /// triple. Note that it could also just be a bare filename already, so also
+    /// triple. If none is found, look for a file called `target.json` inside
+    /// the sysroot under the target-triple's `rustlib` directory.
+    /// Note that it could also just be a bare filename already, so also
     /// check for that. If one of the hardcoded targets we know about, just
     /// return it directly.
     ///
     /// The error string could come from any of the APIs called, including
     /// filesystem access and JSON decoding.
-    pub fn search(target_triple: &TargetTriple) -> Result<Target, String> {
+    pub fn search(target_triple: &TargetTriple, sysroot: &PathBuf) -> Result<Target, String> {
         use rustc_serialize::json;
         use std::env;
         use std::fs;
@@ -1931,14 +1933,21 @@ impl Target {
 
                 let target_path = env::var_os("RUST_TARGET_PATH").unwrap_or_default();
 
-                // 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);
                     }
                 }
+
+                // Additionally look in the sysroot under `lib/rustlib/<triple>/target.json`
+                // as a fallback.
+                let p =
+                    sysroot.join("lib").join("rustlib").join(&target_triple).join("target.json");
+                if p.is_file() {
+                    return load_file(&p);
+                }
+
                 Err(format!("Could not find specification for target {:?}", target_triple))
             }
             TargetTriple::TargetPath(ref target_path) => {