Rollup merge of #85152 - nagisa:target-search-rustlib, r=Mark-Simulacrum
Adjust target search algorithm for rustlib path With this the concerns expressed in #83800 should be addressed. r? `@Mark-Simulacrum`
This commit is contained in:
commit
6ec1de7d4f
5 changed files with 83 additions and 66 deletions
|
@ -1576,7 +1576,7 @@ fn add_rpath_args(
|
||||||
let target_triple = sess.opts.target_triple.triple();
|
let target_triple = sess.opts.target_triple.triple();
|
||||||
let mut get_install_prefix_lib_path = || {
|
let mut get_install_prefix_lib_path = || {
|
||||||
let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
|
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);
|
let mut path = PathBuf::from(install_prefix);
|
||||||
path.push(&tlib);
|
path.push(&tlib);
|
||||||
|
|
||||||
|
|
|
@ -423,8 +423,7 @@ pub fn get_codegen_sysroot(
|
||||||
.iter()
|
.iter()
|
||||||
.chain(sysroot_candidates.iter())
|
.chain(sysroot_candidates.iter())
|
||||||
.map(|sysroot| {
|
.map(|sysroot| {
|
||||||
let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
|
filesearch::make_target_lib_path(&sysroot, &target).with_file_name("codegen-backends")
|
||||||
sysroot.join(libdir).with_file_name("codegen-backends")
|
|
||||||
})
|
})
|
||||||
.find(|f| {
|
.find(|f| {
|
||||||
info!("codegen backend candidate: {}", f.display());
|
info!("codegen backend candidate: {}", f.display());
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
pub use self::FileMatch::*;
|
pub use self::FileMatch::*;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -91,26 +90,21 @@ impl<'a> FileSearch<'a> {
|
||||||
|
|
||||||
// Returns a list of directories where target-specific tool binaries are located.
|
// Returns a list of directories where target-specific tool binaries are located.
|
||||||
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
|
pub fn get_tools_search_paths(&self, self_contained: bool) -> Vec<PathBuf> {
|
||||||
let mut p = PathBuf::from(self.sysroot);
|
let rustlib_path = rustc_target::target_rustlib_path(self.sysroot, &self.triple);
|
||||||
p.push(find_libdir(self.sysroot).as_ref());
|
let p = std::array::IntoIter::new([
|
||||||
p.push(RUST_LIB_DIR);
|
Path::new(&self.sysroot),
|
||||||
p.push(&self.triple);
|
Path::new(&rustlib_path),
|
||||||
p.push("bin");
|
Path::new("bin"),
|
||||||
|
])
|
||||||
|
.collect::<PathBuf>();
|
||||||
if self_contained { vec![p.clone(), p.join("self-contained")] } else { vec![p] }
|
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 {
|
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
|
// This function checks if sysroot is found using env::args().next(), and if it
|
||||||
|
@ -157,11 +151,13 @@ pub fn get_or_default_sysroot() -> PathBuf {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pop off `bin/rustc`, obtaining the suspected sysroot.
|
||||||
p.pop();
|
p.pop();
|
||||||
p.pop();
|
p.pop();
|
||||||
let mut libdir = PathBuf::from(&p);
|
// Look for the target rustlib directory in the suspected sysroot.
|
||||||
libdir.push(find_libdir(&p).as_ref());
|
let mut rustlib_path = rustc_target::target_rustlib_path(&p, "dummy");
|
||||||
if libdir.exists() { Some(p) } else { None }
|
rustlib_path.pop(); // pop off the dummy target.
|
||||||
|
if rustlib_path.exists() { Some(p) } else { None }
|
||||||
}
|
}
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
|
@ -171,37 +167,3 @@ pub fn get_or_default_sysroot() -> PathBuf {
|
||||||
// use env::current_exe() to imply sysroot.
|
// use env::current_exe() to imply sysroot.
|
||||||
from_env_args_next().unwrap_or_else(from_current_exe)
|
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";
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#![feature(associated_type_bounds)]
|
#![feature(associated_type_bounds)]
|
||||||
#![feature(exhaustive_patterns)]
|
#![feature(exhaustive_patterns)]
|
||||||
|
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rustc_macros;
|
extern crate rustc_macros;
|
||||||
|
|
||||||
|
@ -29,3 +31,52 @@ pub mod spec;
|
||||||
/// This is a hack to allow using the `HashStable_Generic` derive macro
|
/// This is a hack to allow using the `HashStable_Generic` derive macro
|
||||||
/// instead of implementing everything in `rustc_middle`.
|
/// instead of implementing everything in `rustc_middle`.
|
||||||
pub trait HashStableContext {}
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1897,15 +1897,15 @@ impl Target {
|
||||||
Ok(base)
|
Ok(base)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search RUST_TARGET_PATH for a JSON file specifying the given target
|
/// Search for a JSON file specifying the given target triple.
|
||||||
/// 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
|
/// If none is found in `$RUST_TARGET_PATH`, look for a file called `target.json` inside the
|
||||||
/// filesystem access and JSON decoding.
|
/// 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> {
|
pub fn search(target_triple: &TargetTriple, sysroot: &PathBuf) -> Result<Target, String> {
|
||||||
use rustc_serialize::json;
|
use rustc_serialize::json;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -1942,8 +1942,13 @@ impl Target {
|
||||||
|
|
||||||
// Additionally look in the sysroot under `lib/rustlib/<triple>/target.json`
|
// Additionally look in the sysroot under `lib/rustlib/<triple>/target.json`
|
||||||
// as a fallback.
|
// as a fallback.
|
||||||
let p =
|
let rustlib_path = crate::target_rustlib_path(&sysroot, &target_triple);
|
||||||
sysroot.join("lib").join("rustlib").join(&target_triple).join("target.json");
|
let p = std::array::IntoIter::new([
|
||||||
|
Path::new(sysroot),
|
||||||
|
Path::new(&rustlib_path),
|
||||||
|
Path::new("target.json"),
|
||||||
|
])
|
||||||
|
.collect::<PathBuf>();
|
||||||
if p.is_file() {
|
if p.is_file() {
|
||||||
return load_file(&p);
|
return load_file(&p);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue