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

Fix rustc sysroot in systems using CAS #79253

Merged
merged 1 commit into from
Feb 6, 2021
Merged
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
52 changes: 45 additions & 7 deletions compiler/rustc_session/src/filesearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
}

// This function checks if sysroot is found using env::args().next(), and if it
// is not found, uses env::current_exe() to imply sysroot.
pub fn get_or_default_sysroot() -> PathBuf {
// Follow symlinks. If the resolved path is relative, make it absolute.
fn canonicalize(path: PathBuf) -> PathBuf {
Expand All @@ -123,15 +125,51 @@ pub fn get_or_default_sysroot() -> PathBuf {
fix_windows_verbatim_for_gcc(&path)
}

match env::current_exe() {
Ok(exe) => {
let mut p = canonicalize(exe);
p.pop();
p.pop();
p
// Use env::current_exe() to get the path of the executable following
// symlinks/canonicalizing components.
fn from_current_exe() -> PathBuf {
match env::current_exe() {
Ok(exe) => {
let mut p = canonicalize(exe);
p.pop();
p.pop();
p
}
Err(e) => panic!("failed to get current_exe: {}", e),
}
}

// Use env::args().next() to get the path of the executable without
// following symlinks/canonicalizing any component. This makes the rustc
// binary able to locate Rust libraries in systems using content-addressable
// storage (CAS).
fn from_env_args_next() -> Option<PathBuf> {
match env::args_os().next() {
Some(first_arg) => {
let mut p = PathBuf::from(first_arg);

// Check if sysroot is found using env::args().next() only if the rustc in argv[0]
// is a symlink (see #79253). We might want to change/remove it to conform with
// https://www.gnu.org/prep/standards/standards.html#Finding-Program-Files in the
// future.
if fs::read_link(&p).is_err() {
// Path is not a symbolic link or does not exist.
return None;
}

p.pop();
p.pop();
let mut libdir = PathBuf::from(&p);
libdir.push(find_libdir(&p).as_ref());
if libdir.exists() { Some(p) } else { None }
}
None => None,
}
Err(e) => panic!("failed to get current_exe: {}", e),
}

// Check if sysroot is found using env::args().next(), and if is not found,
// use env::current_exe() to imply sysroot.
from_env_args_next().unwrap_or(from_current_exe())
}

// The name of the directory rustc expects libraries to be located.
Expand Down