diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 52a6e4ff924f4..1c9bd153f8de1 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -892,8 +892,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 { - 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, + 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 cc2583be94474..e3ea3a11c4d40 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 2af46693449dc..490239ee6155c 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1892,13 +1892,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 { + pub fn search(target_triple: &TargetTriple, sysroot: &PathBuf) -> Result { use rustc_serialize::json; use std::env; use std::fs; @@ -1925,14 +1927,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//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) => {