Skip to content

Commit d24a523

Browse files
committed
Use DYLD_FALLBACK_LIBRARY_PATH for dylib_path_envvar on macOS
When loading and linking a dynamic library or bundle, dlopen searches in LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, PWD, and DYLD_FALLBACK_LIBRARY_PATH. In the Mach-O format, a dynamic library has an "install path." Clients linking against the library record this path, and the dynamic linker, dyld, uses it to locate the library. dyld searches DYLD_LIBRARY_PATH *before* the install path. dyld searches DYLD_FALLBACK_LIBRARY_PATH only if it cannot find the library in the install path. Setting DYLD_LIBRARY_PATH can easily have unintended consequences. See https://users.rust-lang.org/t/subprocess-and-dynamic-library-linking-problem-interaction/7873/10 See https://trac.macports.org/ticket/57692 See https://bugzilla.mozilla.org/show_bug.cgi?id=1536486 This is the same change as was applied to cargo in rust-lang/cargo#6355 See also rust-lang/cargo#6625 and rust-lang/cargo#6625
1 parent ddd7df5 commit d24a523

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/toolchain.rs

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -380,17 +380,43 @@ impl<'a> Toolchain<'a> {
380380
}
381381

382382
pub fn set_ldpath(&self, cmd: &mut Command) {
383-
let new_path = self.path.join("lib");
383+
let mut new_path = vec![self.path.join("lib")];
384384

385385
#[cfg(not(target_os = "macos"))]
386386
mod sysenv {
387387
pub const LOADER_PATH: &str = "LD_LIBRARY_PATH";
388388
}
389389
#[cfg(target_os = "macos")]
390390
mod sysenv {
391-
pub const LOADER_PATH: &str = "DYLD_LIBRARY_PATH";
391+
// When loading and linking a dynamic library or bundle, dlopen
392+
// searches in LD_LIBRARY_PATH, DYLD_LIBRARY_PATH, PWD, and
393+
// DYLD_FALLBACK_LIBRARY_PATH.
394+
// In the Mach-O format, a dynamic library has an "install path."
395+
// Clients linking against the library record this path, and the
396+
// dynamic linker, dyld, uses it to locate the library.
397+
// dyld searches DYLD_LIBRARY_PATH *before* the install path.
398+
// dyld searches DYLD_FALLBACK_LIBRARY_PATH only if it cannot
399+
// find the library in the install path.
400+
// Setting DYLD_LIBRARY_PATH can easily have unintended
401+
// consequences.
402+
pub const LOADER_PATH: &str = "DYLD_FALLBACK_LIBRARY_PATH";
392403
}
393-
env_var::prepend_path(sysenv::LOADER_PATH, vec![new_path.clone()], cmd);
404+
if cfg!(target_os = "macos")
405+
&& env::var_os(sysenv::LOADER_PATH)
406+
.filter(|x| x.len() > 0)
407+
.is_none()
408+
{
409+
// These are the defaults when DYLD_FALLBACK_LIBRARY_PATH isn't
410+
// set or set to an empty string. Since we are explicitly setting
411+
// the value, make sure the defaults still work.
412+
if let Some(home) = env::var_os("HOME") {
413+
new_path.push(PathBuf::from(home).join("lib"));
414+
}
415+
new_path.push(PathBuf::from("/usr/local/lib"));
416+
new_path.push(PathBuf::from("/usr/lib"));
417+
}
418+
419+
env_var::prepend_path(sysenv::LOADER_PATH, new_path, cmd);
394420

395421
// Prepend CARGO_HOME/bin to the PATH variable so that we're sure to run
396422
// cargo/rustc via the proxy bins. There is no fallback case for if the

0 commit comments

Comments
 (0)