Skip to content

Commit 16b8057

Browse files
committed
Auto merge of rust-lang#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).
2 parents 23adf9f + 3f679fe commit 16b8057

File tree

1 file changed

+45
-7
lines changed

1 file changed

+45
-7
lines changed

Diff for: compiler/rustc_session/src/filesearch.rs

+45-7
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
113113
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
114114
}
115115

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

126-
match env::current_exe() {
127-
Ok(exe) => {
128-
let mut p = canonicalize(exe);
129-
p.pop();
130-
p.pop();
131-
p
128+
// Use env::current_exe() to get the path of the executable following
129+
// symlinks/canonicalizing components.
130+
fn from_current_exe() -> PathBuf {
131+
match env::current_exe() {
132+
Ok(exe) => {
133+
let mut p = canonicalize(exe);
134+
p.pop();
135+
p.pop();
136+
p
137+
}
138+
Err(e) => panic!("failed to get current_exe: {}", e),
139+
}
140+
}
141+
142+
// Use env::args().next() to get the path of the executable without
143+
// following symlinks/canonicalizing any component. This makes the rustc
144+
// binary able to locate Rust libraries in systems using content-addressable
145+
// storage (CAS).
146+
fn from_env_args_next() -> Option<PathBuf> {
147+
match env::args_os().next() {
148+
Some(first_arg) => {
149+
let mut p = PathBuf::from(first_arg);
150+
151+
// Check if sysroot is found using env::args().next() only if the rustc in argv[0]
152+
// is a symlink (see #79253). We might want to change/remove it to conform with
153+
// https://www.gnu.org/prep/standards/standards.html#Finding-Program-Files in the
154+
// future.
155+
if fs::read_link(&p).is_err() {
156+
// Path is not a symbolic link or does not exist.
157+
return None;
158+
}
159+
160+
p.pop();
161+
p.pop();
162+
let mut libdir = PathBuf::from(&p);
163+
libdir.push(find_libdir(&p).as_ref());
164+
if libdir.exists() { Some(p) } else { None }
165+
}
166+
None => None,
132167
}
133-
Err(e) => panic!("failed to get current_exe: {}", e),
134168
}
169+
170+
// Check if sysroot is found using env::args().next(), and if is not found,
171+
// use env::current_exe() to imply sysroot.
172+
from_env_args_next().unwrap_or(from_current_exe())
135173
}
136174

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

0 commit comments

Comments
 (0)