@@ -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.
116118pub 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