Skip to content

Commit

Permalink
Use DYLD_FALLBACK_LIBRARY_PATH for dylib_path_envvar on macOS
Browse files Browse the repository at this point in the history
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
  • Loading branch information
glandium committed Apr 16, 2019
1 parent ddd7df5 commit d24a523
Showing 1 changed file with 29 additions and 3 deletions.
32 changes: 29 additions & 3 deletions src/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,17 +380,43 @@ impl<'a> Toolchain<'a> {
}

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

#[cfg(not(target_os = "macos"))]
mod sysenv {
pub const LOADER_PATH: &str = "LD_LIBRARY_PATH";
}
#[cfg(target_os = "macos")]
mod sysenv {
pub const LOADER_PATH: &str = "DYLD_LIBRARY_PATH";
// 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.
pub const LOADER_PATH: &str = "DYLD_FALLBACK_LIBRARY_PATH";
}
env_var::prepend_path(sysenv::LOADER_PATH, vec![new_path.clone()], cmd);
if cfg!(target_os = "macos")
&& env::var_os(sysenv::LOADER_PATH)
.filter(|x| x.len() > 0)
.is_none()
{
// These are the defaults when DYLD_FALLBACK_LIBRARY_PATH isn't
// set or set to an empty string. Since we are explicitly setting
// the value, make sure the defaults still work.
if let Some(home) = env::var_os("HOME") {
new_path.push(PathBuf::from(home).join("lib"));
}
new_path.push(PathBuf::from("/usr/local/lib"));
new_path.push(PathBuf::from("/usr/lib"));
}

env_var::prepend_path(sysenv::LOADER_PATH, new_path, cmd);

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

0 comments on commit d24a523

Please sign in to comment.