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

Adjust target search algorithm for rustlib path #85152

Merged
merged 1 commit into from
May 10, 2021
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
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ fn add_rpath_args(
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(&sess.sysroot, target_triple);
let tlib = rustc_target::target_rustlib_path(&sess.sysroot, target_triple).join("lib");
let mut path = PathBuf::from(install_prefix);
path.push(&tlib);

Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,7 @@ pub fn get_codegen_sysroot(
.iter()
.chain(sysroot_candidates.iter())
.map(|sysroot| {
let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
sysroot.join(libdir).with_file_name("codegen-backends")
filesearch::make_target_lib_path(&sysroot, &target).with_file_name("codegen-backends")
})
.find(|f| {
info!("codegen backend candidate: {}", f.display());
Expand Down
68 changes: 15 additions & 53 deletions compiler/rustc_session/src/filesearch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
pub use self::FileMatch::*;

use std::borrow::Cow;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -91,26 +90,21 @@ impl<'a> FileSearch<'a> {

// Returns a list of directories where target-specific tool binaries are located.
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
let mut p = PathBuf::from(self.sysroot);
p.push(find_libdir(self.sysroot).as_ref());
p.push(RUST_LIB_DIR);
p.push(&self.triple);
p.push("bin");
let rustlib_path = rustc_target::target_rustlib_path(self.sysroot, &self.triple);
let p = std::array::IntoIter::new([
Path::new(&self.sysroot),
Path::new(&rustlib_path),
Path::new("bin"),
])
.collect::<PathBuf>();
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
}
}

pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
let mut p = PathBuf::from(find_libdir(sysroot).as_ref());
assert!(p.is_relative());
p.push(RUST_LIB_DIR);
p.push(target_triple);
p.push("lib");
p
}

pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
let rustlib_path = rustc_target::target_rustlib_path(sysroot, target_triple);
std::array::IntoIter::new([sysroot, Path::new(&rustlib_path), Path::new("lib")])
.collect::<PathBuf>()
}

// This function checks if sysroot is found using env::args().next(), and if it
Expand Down Expand Up @@ -157,11 +151,13 @@ pub fn get_or_default_sysroot() -> PathBuf {
return None;
}

// Pop off `bin/rustc`, obtaining the suspected sysroot.
p.pop();
p.pop();
let mut libdir = PathBuf::from(&p);
libdir.push(find_libdir(&p).as_ref());
if libdir.exists() { Some(p) } else { None }
// Look for the target rustlib directory in the suspected sysroot.
let mut rustlib_path = rustc_target::target_rustlib_path(&p, "dummy");
rustlib_path.pop(); // pop off the dummy target.
if rustlib_path.exists() { Some(p) } else { None }
}
None => None,
}
Expand All @@ -171,37 +167,3 @@ pub fn get_or_default_sysroot() -> PathBuf {
// use env::current_exe() to imply sysroot.
from_env_args_next().unwrap_or_else(from_current_exe)
}

// The name of the directory rustc expects libraries to be located.
fn find_libdir(sysroot: &Path) -> Cow<'static, str> {
// FIXME: This is a quick hack to make the rustc binary able to locate
// Rust libraries in Linux environments where libraries might be installed
// to lib64/lib32. This would be more foolproof by basing the sysroot off
// of the directory where `librustc_driver` is located, rather than
// where the rustc binary is.
// If --libdir is set during configuration to the value other than
// "lib" (i.e., non-default), this value is used (see issue #16552).

#[cfg(target_pointer_width = "64")]
const PRIMARY_LIB_DIR: &str = "lib64";

#[cfg(target_pointer_width = "32")]
const PRIMARY_LIB_DIR: &str = "lib32";

const SECONDARY_LIB_DIR: &str = "lib";

match option_env!("CFG_LIBDIR_RELATIVE") {
None | Some("lib") => {
if sysroot.join(PRIMARY_LIB_DIR).join(RUST_LIB_DIR).exists() {
PRIMARY_LIB_DIR.into()
} else {
SECONDARY_LIB_DIR.into()
}
}
Some(libdir) => libdir.into(),
}
}

// The name of rustc's own place to organize libraries.
// Used to be "rustc", now the default is "rustlib"
const RUST_LIB_DIR: &str = "rustlib";
51 changes: 51 additions & 0 deletions compiler/rustc_target/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#![feature(associated_type_bounds)]
#![feature(exhaustive_patterns)]

use std::path::{Path, PathBuf};

#[macro_use]
extern crate rustc_macros;

Expand All @@ -29,3 +31,52 @@ pub mod spec;
/// This is a hack to allow using the `HashStable_Generic` derive macro
/// instead of implementing everything in `rustc_middle`.
pub trait HashStableContext {}

/// The name of rustc's own place to organize libraries.
///
/// Used to be `rustc`, now the default is `rustlib`.
const RUST_LIB_DIR: &str = "rustlib";

/// Returns a `rustlib` path for this particular target, relative to the provided sysroot.
///
/// For example: `target_sysroot_path("/usr", "x86_64-unknown-linux-gnu")` =>
/// `"lib*/rustlib/x86_64-unknown-linux-gnu"`.
pub fn target_rustlib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
let libdir = find_libdir(sysroot);
std::array::IntoIter::new([
Path::new(libdir.as_ref()),
Path::new(RUST_LIB_DIR),
Path::new(target_triple),
])
.collect::<PathBuf>()
}

/// The name of the directory rustc expects libraries to be located.
fn find_libdir(sysroot: &Path) -> std::borrow::Cow<'static, str> {
// FIXME: This is a quick hack to make the rustc binary able to locate
// Rust libraries in Linux environments where libraries might be installed
// to lib64/lib32. This would be more foolproof by basing the sysroot off
// of the directory where `librustc_driver` is located, rather than
// where the rustc binary is.
// If --libdir is set during configuration to the value other than
// "lib" (i.e., non-default), this value is used (see issue #16552).

#[cfg(target_pointer_width = "64")]
const PRIMARY_LIB_DIR: &str = "lib64";

#[cfg(target_pointer_width = "32")]
const PRIMARY_LIB_DIR: &str = "lib32";

const SECONDARY_LIB_DIR: &str = "lib";

match option_env!("CFG_LIBDIR_RELATIVE") {
None | Some("lib") => {
if sysroot.join(PRIMARY_LIB_DIR).join(RUST_LIB_DIR).exists() {
PRIMARY_LIB_DIR.into()
} else {
SECONDARY_LIB_DIR.into()
}
}
Some(libdir) => libdir.into(),
}
}
25 changes: 15 additions & 10 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1897,15 +1897,15 @@ impl Target {
Ok(base)
}

/// Search RUST_TARGET_PATH for a JSON file specifying the given target
/// 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.
/// Search for a JSON file specifying the given target triple.
///
/// The error string could come from any of the APIs called, including
/// filesystem access and JSON decoding.
/// If none is found in `$RUST_TARGET_PATH`, 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, sysroot: &PathBuf) -> Result<Target, String> {
use rustc_serialize::json;
use std::env;
Expand Down Expand Up @@ -1942,8 +1942,13 @@ impl Target {

// 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");
let rustlib_path = crate::target_rustlib_path(&sysroot, &target_triple);
let p = std::array::IntoIter::new([
Path::new(sysroot),
Path::new(&rustlib_path),
Path::new("target.json"),
])
.collect::<PathBuf>();
if p.is_file() {
return load_file(&p);
}
Expand Down