macos: use DYLD_FALLBACK_LIBRARY_PATH instead of DYLD_LIBRARY_PATH

`DYLD_LIBRARY_PATH` can frequently break builtin macOS software when
pointed at Spack libraries.  This is because it takes *higher* precedence
than the default library search paths, which are used by system software.

`DYLD_FALLBACK_LIBRARY_PATH`, on the other hand, takes lower precedence.
At first glance, this might seem bad, because the software installed by
Spack in an environment needs to find *its* libraries, and it should not
use the defaults.  However, Spack's isntallations are always `RPATH`'d,
so they do not have this problem.

`DYLD_FALLBACK_LIBRARY_PATH` is thus useful for things built in an
environment that need to use Spack's libraries, that don't set *their*
RPATHs correctly for whatever reason. We now prefer it to
`DYLD_LIBRARY_PATH` in modules and in environments because it helps a
little bit, and it is much less intrusive.
This commit is contained in:
Todd Gamblin 2020-04-16 10:45:01 -07:00
parent 1f5ef5c876
commit f6d26db939
5 changed files with 14 additions and 10 deletions

View file

@ -145,6 +145,7 @@ def clean_environment():
env.unset('CPATH') env.unset('CPATH')
env.unset('LD_RUN_PATH') env.unset('LD_RUN_PATH')
env.unset('DYLD_LIBRARY_PATH') env.unset('DYLD_LIBRARY_PATH')
env.unset('DYLD_FALLBACK_LIBRARY_PATH')
build_lang = spack.config.get('config:build_language') build_lang = spack.config.get('config:build_language')
if build_lang: if build_lang:

View file

@ -692,7 +692,10 @@ def main(argv=None):
# Spack clears these variables before building and installing packages, # Spack clears these variables before building and installing packages,
# but needs to know the prior state for commands like `spack load` and # but needs to know the prior state for commands like `spack load` and
# `spack env activate that modify the user environment. # `spack env activate that modify the user environment.
for var in ('LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH'): recovered_vars = (
'LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'DYLD_FALLBACK_LIBRARY_PATH'
)
for var in recovered_vars:
stored_var_name = 'SPACK_%s' % var stored_var_name = 'SPACK_%s' % var
if stored_var_name in os.environ: if stored_var_name in os.environ:
os.environ[var] = os.environ[stored_var_name] os.environ[var] = os.environ[stored_var_name]

View file

@ -40,7 +40,7 @@ def prefix_inspections(platform):
if platform == 'darwin': if platform == 'darwin':
for subdir in ('lib', 'lib64'): for subdir in ('lib', 'lib64'):
inspections[subdir].append('DYLD_LIBRARY_PATH') inspections[subdir].append('DYLD_FALLBACK_LIBRARY_PATH')
return inspections return inspections

View file

@ -29,13 +29,16 @@
######################################################################## ########################################################################
# Store LD_LIBRARY_PATH variables from spack shell function # Store LD_LIBRARY_PATH variables from spack shell function
# This is necessary because MacOS System Integrity Protection clears # This is necessary because MacOS System Integrity Protection clears
# (DY?)LD_LIBRARY_PATH variables on process start. # variables that affect dyld on process start.
if ( ${?LD_LIBRARY_PATH} ) then if ( ${?LD_LIBRARY_PATH} ) then
setenv SPACK_LD_LIBRARY_PATH $LD_LIBRARY_PATH setenv SPACK_LD_LIBRARY_PATH $LD_LIBRARY_PATH
endif endif
if ( ${?DYLD_LIBRARY_PATH} ) then if ( ${?DYLD_LIBRARY_PATH} ) then
setenv SPACK_DYLD_LIBRARY_PATH $DYLD_LIBRARY_PATH setenv SPACK_DYLD_LIBRARY_PATH $DYLD_LIBRARY_PATH
endif endif
if ( ${?DYLD_FALLBACK_LIBRARY_PATH} ) then
setenv SPACK_DYLD_FALLBACK_LIBRARY_PATH $DYLD_FALLBACK_LIBRARY_PATH
endif
# accumulate initial flags for main spack command # accumulate initial flags for main spack command
set _sp_flags = "" set _sp_flags = ""

View file

@ -42,13 +42,10 @@
spack() { spack() {
# Store LD_LIBRARY_PATH variables from spack shell function # Store LD_LIBRARY_PATH variables from spack shell function
# This is necessary because MacOS System Integrity Protection clears # This is necessary because MacOS System Integrity Protection clears
# (DY?)LD_LIBRARY_PATH variables on process start. # variables that affect dyld on process start.
if [ -n "${LD_LIBRARY_PATH-}" ]; then for var in LD_LIBRARY_PATH DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH; do
export SPACK_LD_LIBRARY_PATH=$LD_LIBRARY_PATH eval "if [ -n \"\${${var}-}\" ]; then export SPACK_$var=\${${var}}; fi"
fi done
if [ -n "${DYLD_LIBRARY_PATH-}" ]; then
export SPACK_DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH
fi
# Zsh does not do word splitting by default, this enables it for this # Zsh does not do word splitting by default, this enables it for this
# function only # function only