diff options
| author | bors <bors@rust-lang.org> | 2021-02-05 22:58:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-02-05 22:58:13 +0000 |
| commit | 16b805713c4cdb967263b9d59634fddea4372b65 (patch) | |
| tree | 2d14c5badf900950cd3696360518281978f70e69 | |
| parent | 23adf9fd843da7a3394c824b056f93151aaa40ad (diff) | |
| parent | 3f679fef23cd006c336e2a4f7c6707e119d22206 (diff) | |
| download | rust-16b805713c4cdb967263b9d59634fddea4372b65.tar.gz rust-16b805713c4cdb967263b9d59634fddea4372b65.zip | |
Auto merge of #79253 - rcvalle:fix-rustc-sysroot-cas, r=nagisa
Fix rustc sysroot in systems using CAS Change filesearch::get_or_default_sysroot() to check if sysroot is found using env::args().next() if rustc in argv[0] is a symlink; otherwise, or if it is not found, use env::current_exe() to imply sysroot. This makes the rustc binary able to locate Rust libraries in systems using content-addressable storage (CAS).
| -rw-r--r-- | compiler/rustc_session/src/filesearch.rs | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 3a757e5f007..47f14fa6b7a 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -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 { @@ -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. |
