@@ -113,6 +113,8 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
113
113
sysroot. join ( & relative_target_lib_path ( sysroot, target_triple) )
114
114
}
115
115
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.
116
118
pub fn get_or_default_sysroot ( ) -> PathBuf {
117
119
// Follow symlinks. If the resolved path is relative, make it absolute.
118
120
fn canonicalize ( path : PathBuf ) -> PathBuf {
@@ -123,15 +125,51 @@ pub fn get_or_default_sysroot() -> PathBuf {
123
125
fix_windows_verbatim_for_gcc ( & path)
124
126
}
125
127
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 ,
132
167
}
133
- Err ( e) => panic ! ( "failed to get current_exe: {}" , e) ,
134
168
}
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 ( ) )
135
173
}
136
174
137
175
// The name of the directory rustc expects libraries to be located.
0 commit comments