Skip to content
Snippets Groups Projects
Commit cd9691de authored by becker33's avatar becker33 Committed by Todd Gamblin
Browse files

cc: package search paths come before dependency paths (#4692)

Spack currently prepends include paths, library paths, and rpaths to the compile line.  This causes problems when a header or library in the package has the same name as one exported by one of its dependencies.  The *dependency's* header will be preferred over the package's, which is not what most builds expect.  This also breaks some of our production codes.

This restores the original cc behavior (from *very* early Spack) of parsing compiler arguments out by type (`-L`, `-I`, `-Wl,-rpath`) and reconstituting the full command at the end.

`<includes> <other_args> <library dirs> <rpaths>`

This differs from the original behavior in one significant way, though: it *appends* the library arguments so that dependency libraries do not shadow those in the build. 

This is safe because semantics aren't affected by *interleaving* `-I`, `-L`, and `-Wl,-rpath` arguments with others, only with each other (so the order fo two `-L` args affects the search path, but we search for all libraries on the command line using the same search path).

We preserve the following:
1. Any system directory in the paths will be listed last.
2. The root package's include/library/RPATH flags come before flags of the same type for any dependency.
3. Order will be preserved within flags passed by the build (except system paths, which are moved to be last)
4. Flags for dependencies will appear between the root flags and the system flags, and the flags for any dependency will come before those for *its* dependencies (this is for completeness -- we already guarantee this in `build_environment.py`)
parent 38062a8a
Branches
Tags
No related merge requests found
...@@ -52,6 +52,7 @@ parameters=( ...@@ -52,6 +52,7 @@ parameters=(
SPACK_F77_RPATH_ARG SPACK_F77_RPATH_ARG
SPACK_FC_RPATH_ARG SPACK_FC_RPATH_ARG
SPACK_SHORT_SPEC SPACK_SHORT_SPEC
SPACK_SYSTEM_DIRS
) )
# The compiler input variables are checked for sanity later: # The compiler input variables are checked for sanity later:
...@@ -228,7 +229,92 @@ fi ...@@ -228,7 +229,92 @@ fi
# Save original command for debug logging # Save original command for debug logging
input_command="$@" input_command="$@"
args=("$@") args=()
#
# Parse the command line args, trying hard to keep
# non-rpath linker arguments in the proper order w.r.t. other command
# line arguments. This is important for things like groups.
#
# -l arguments are treated as 'other_args' to ensure that they stay in
# any groups they are a part of. Dependency library -l statements are
# categorized as 'libs'
#
# The various categories will be recombined with compiler flags into
# args variable later.
#
includes=()
libdirs=()
libs=()
rpaths=()
other_args=()
while [ -n "$1" ]; do
case "$1" in
-I*)
arg="${1#-I}"
if [ -z "$arg" ]; then shift; arg="$1"; fi
includes+=("$arg")
;;
-L*)
arg="${1#-L}"
if [ -z "$arg" ]; then shift; arg="$1"; fi
libdirs+=("$arg")
;;
-l*)
arg="${1#-l}"
if [ -z "$arg" ]; then shift; arg="$1"; fi
other_args+=("-l$arg")
;;
-Wl,*)
arg="${1#-Wl,}"
if [ -z "$arg" ]; then shift; arg="$1"; fi
if [[ "$arg" = -rpath=* ]]; then
rpaths+=("${arg#-rpath=}")
elif [[ "$arg" = -rpath,* ]]; then
rpaths+=("${arg#-rpath,}")
elif [[ "$arg" = -rpath ]]; then
shift; arg="$1"
if [[ "$arg" != -Wl,* ]]; then
die "-Wl,-rpath was not followed by -Wl,*"
fi
rpaths+=("${arg#-Wl,}")
else
other_args+=("-Wl,$arg")
fi
;;
-Xlinker,*)
arg="${1#-Xlinker,}"
if [ -z "$arg" ]; then shift; arg="$1"; fi
if [[ "$arg" = -rpath=* ]]; then
rpaths+=("${arg#-rpath=}")
elif [[ "$arg" = -rpath ]]; then
shift; arg="$1"
if [[ "$arg" != -Xlinker,* ]]; then
die "-Xlinker,-rpath was not followed by -Xlinker,*"
fi
rpaths+=("${arg#-Xlinker,}")
else
other_args+=("-Xlinker,$arg")
fi
;;
-Xlinker)
if [[ "$2" == "-rpath" ]]; then
if [[ "$3" != "-Xlinker" ]]; then
die "-Xlinker,-rpath was not followed by -Xlinker,*"
fi
shift 3;
rpaths+=("$1")
else
other_args+=("$1")
fi
;;
*)
other_args+=("$1")
;;
esac
shift
done
# Prepend cppflags, cflags, cxxflags, fcflags, fflags, and ldflags # Prepend cppflags, cflags, cxxflags, fcflags, fflags, and ldflags
...@@ -266,92 +352,93 @@ case "$mode" in cc|ccld) ...@@ -266,92 +352,93 @@ case "$mode" in cc|ccld)
;; ;;
esac esac
# Include all -L's and prefix/whatever dirs in rpath
$add_rpaths && rpaths+=("$SPACK_PREFIX/lib")
$add_rpaths && rpaths+=("$SPACK_PREFIX/lib64")
# Read spack dependencies from the path environment variable # Read spack dependencies from the path environment variable
IFS=':' read -ra deps <<< "$SPACK_DEPENDENCIES" IFS=':' read -ra deps <<< "$SPACK_DEPENDENCIES"
for dep in "${deps[@]}"; do for dep in "${deps[@]}"; do
# Prepend include directories # Append include directories
if [[ -d $dep/include ]]; then if [[ -d $dep/include ]]; then
if [[ $mode == cpp || $mode == cc || $mode == as || $mode == ccld ]]; then if [[ $mode == cpp || $mode == cc || $mode == as || $mode == ccld ]]; then
args=("-I$dep/include" "${args[@]}") includes=("${includes[@]}" "$dep/include")
fi fi
fi fi
# Prepend lib and RPATH directories # Append lib and RPATH directories
if [[ -d $dep/lib ]]; then if [[ -d $dep/lib ]]; then
if [[ $mode == ccld ]]; then if [[ $SPACK_RPATH_DEPS == *$dep* ]]; then
if [[ $SPACK_RPATH_DEPS == *$dep* ]]; then $add_rpaths && rpaths=("${rpaths[@]}" "$dep/lib")
$add_rpaths && args=("$rpath$dep/lib" "${args[@]}") fi
fi if [[ $SPACK_LINK_DEPS == *$dep* ]]; then
if [[ $SPACK_LINK_DEPS == *$dep* ]]; then libdirs=("${libdirs[@]}" "$dep/lib")
args=("-L$dep/lib" "${args[@]}")
fi
elif [[ $mode == ld ]]; then
if [[ $SPACK_RPATH_DEPS == *$dep* ]]; then
$add_rpaths && args=("-rpath" "$dep/lib" "${args[@]}")
fi
if [[ $SPACK_LINK_DEPS == *$dep* ]]; then
args=("-L$dep/lib" "${args[@]}")
fi
fi fi
fi fi
# Prepend lib64 and RPATH directories # Append lib64 and RPATH directories
if [[ -d $dep/lib64 ]]; then if [[ -d $dep/lib64 ]]; then
if [[ $mode == ccld ]]; then if [[ $SPACK_RPATH_DEPS == *$dep* ]]; then
if [[ $SPACK_RPATH_DEPS == *$dep* ]]; then $add_rpaths && rpaths+=("$dep/lib64")
$add_rpaths && args=("$rpath$dep/lib64" "${args[@]}") fi
fi if [[ $SPACK_LINK_DEPS == *$dep* ]]; then
if [[ $SPACK_LINK_DEPS == *$dep* ]]; then libdirs+=("$dep/lib64")
args=("-L$dep/lib64" "${args[@]}")
fi
elif [[ $mode == ld ]]; then
if [[ $SPACK_RPATH_DEPS == *$dep* ]]; then
$add_rpaths && args=("-rpath" "$dep/lib64" "${args[@]}")
fi
if [[ $SPACK_LINK_DEPS == *$dep* ]]; then
args=("-L$dep/lib64" "${args[@]}")
fi
fi fi
fi fi
done done
# Include all -L's and prefix/whatever dirs in rpath
if [[ $mode == ccld ]]; then
$add_rpaths && args=("$rpath$SPACK_PREFIX/lib64" "${args[@]}")
$add_rpaths && args=("$rpath$SPACK_PREFIX/lib" "${args[@]}")
elif [[ $mode == ld ]]; then
$add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib64" "${args[@]}")
$add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib" "${args[@]}")
fi
# Set extra RPATHs # Set extra RPATHs
IFS=':' read -ra extra_rpaths <<< "$SPACK_COMPILER_EXTRA_RPATHS" IFS=':' read -ra extra_rpaths <<< "$SPACK_COMPILER_EXTRA_RPATHS"
for extra_rpath in "${extra_rpaths[@]}"; do for extra_rpath in "${extra_rpaths[@]}"; do
if [[ $mode == ccld ]]; then $add_rpaths && rpaths+=("$extra_rpath")
$add_rpaths && args=("$rpath$extra_rpath" "${args[@]}") libdirs+=("$extra_rpath")
args=("-L$extra_rpath" "${args[@]}")
elif [[ $mode == ld ]]; then
$add_rpaths && args=("-rpath" "$extra_rpath" "${args[@]}")
args=("-L$extra_rpath" "${args[@]}")
fi
done done
# Add SPACK_LDLIBS to args # Add SPACK_LDLIBS to args
case "$mode" in case "$mode" in
ld|ccld) ld|ccld)
args=("${args[@]}" ${SPACK_LDLIBS[@]}) ;; for lib in ${SPACK_LDLIBS[@]}; do
libs+=("${lib#-l}")
done
esac esac
#ccache only supports C languages, so filtering out Fortran # Filter system locations to the end of each sublist of args
if [[ ( ${lang_flags} = "C" || ${lang_flags} = "CXX" ) && ${SPACK_CCACHE_BINARY} ]]; then # (includes, library dirs, rpaths)
full_command=("${SPACK_CCACHE_BINARY}" "$command" "${args[@]}") for sd in ${SPACK_SYSTEM_DIRS[@]}; do
# #3761#issuecomment-294352232 stripped_includes=`echo $includes | sed "s#\b$sd/\? \b##g"`
# workaround for stage being a temp folder stripped_libdirs=`echo $libdirs | sed "s#\b$sd/\? \b##g"`
export CCACHE_NOHASHDIR=yes stripped_rpaths=`echo $rpaths | sed "s#\b$sd/\? \b##g"`
else if [[ "$includes" != "$stripped_includes" ]]; then
full_command=("$command" "${args[@]}") $includes="$stripped_includes $sd"
fi
if [[ "$libdirs" != "$stripped_libdirs" ]]; then
$libdirs="$stripped_libdirs $sd"
fi
if [[ "$rpaths" != "$stripped_rpaths" ]]; then
$rpaths="$stripped_rpaths $sd"
fi
done
# Put the arguments together into one list
# Includes come first, then other args, library dirs, and rpaths
# rpaths get appropriate flag for ld vs ccld mode
for dir in "${includes[@]}"; do args+=("-I$dir"); done
args+=("${other_args[@]}")
for dir in "${libdirs[@]}"; do args+=("-L$dir"); done
for lib in "${libs[@]}"; do args+=("-l$lib"); done
if [ "$mode" = ccld ]; then
for dir in "${rpaths[@]}"; do
args+=("$rpath$dir")
done
elif [ "$mode" = ld ]; then
for dir in "${rpaths[@]}"; do
args+=("-rpath" "$dir")
done
fi fi
full_command=("$command")
full_command+=("${args[@]}")
# In test command mode, write out full command for Spack tests. # In test command mode, write out full command for Spack tests.
if [[ $SPACK_TEST_COMMAND == dump-args ]]; then if [[ $SPACK_TEST_COMMAND == dump-args ]]; then
echo "${full_command[@]}" echo "${full_command[@]}"
...@@ -370,4 +457,4 @@ if [[ $SPACK_DEBUG == TRUE ]]; then ...@@ -370,4 +457,4 @@ if [[ $SPACK_DEBUG == TRUE ]]; then
echo "[$mode] ${full_command[@]}" >> "$output_log" echo "[$mode] ${full_command[@]}" >> "$output_log"
fi fi
exec "${full_command[@]}" exec "${full_command[@]}"
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
from spack.environment import EnvironmentModifications, validate from spack.environment import EnvironmentModifications, validate
from spack.environment import preserve_environment from spack.environment import preserve_environment
from spack.util.environment import env_flag, filter_system_paths, get_path from spack.util.environment import env_flag, filter_system_paths, get_path
from spack.util.environment import system_dirs
from spack.util.executable import Executable from spack.util.executable import Executable
from spack.util.module_cmd import load_module, get_path_from_module from spack.util.module_cmd import load_module, get_path_from_module
from spack.util.log_parse import parse_log_events, make_log_context from spack.util.log_parse import parse_log_events, make_log_context
...@@ -99,6 +100,7 @@ ...@@ -99,6 +100,7 @@
SPACK_DEBUG_LOG_ID = 'SPACK_DEBUG_LOG_ID' SPACK_DEBUG_LOG_ID = 'SPACK_DEBUG_LOG_ID'
SPACK_DEBUG_LOG_DIR = 'SPACK_DEBUG_LOG_DIR' SPACK_DEBUG_LOG_DIR = 'SPACK_DEBUG_LOG_DIR'
SPACK_CCACHE_BINARY = 'SPACK_CCACHE_BINARY' SPACK_CCACHE_BINARY = 'SPACK_CCACHE_BINARY'
SPACK_SYSTEM_DIRS = 'SPACK_SYSTEM_DIRS'
# Platform-specific library suffix. # Platform-specific library suffix.
...@@ -202,6 +204,8 @@ def set_compiler_environment_variables(pkg, env): ...@@ -202,6 +204,8 @@ def set_compiler_environment_variables(pkg, env):
env.set('SPACK_COMPILER_SPEC', str(pkg.spec.compiler)) env.set('SPACK_COMPILER_SPEC', str(pkg.spec.compiler))
env.set('SPACK_SYSTEM_DIRS', ' '.join(system_dirs))
compiler.setup_custom_environment(pkg, env) compiler.setup_custom_environment(pkg, env)
return env return env
......
...@@ -58,6 +58,8 @@ def build_environment(): ...@@ -58,6 +58,8 @@ def build_environment():
os.environ['SPACK_F77_RPATH_ARG'] = "-Wl,-rpath," os.environ['SPACK_F77_RPATH_ARG'] = "-Wl,-rpath,"
os.environ['SPACK_FC_RPATH_ARG'] = "-Wl,-rpath," os.environ['SPACK_FC_RPATH_ARG'] = "-Wl,-rpath,"
os.environ['SPACK_SYSTEM_DIRS'] = '/usr/include /usr/lib'
if 'SPACK_DEPENDENCIES' in os.environ: if 'SPACK_DEPENDENCIES' in os.environ:
del os.environ['SPACK_DEPENDENCIES'] del os.environ['SPACK_DEPENDENCIES']
...@@ -67,7 +69,8 @@ def build_environment(): ...@@ -67,7 +69,8 @@ def build_environment():
'SPACK_ENV_PATH', 'SPACK_DEBUG_LOG_DIR', 'SPACK_ENV_PATH', 'SPACK_DEBUG_LOG_DIR',
'SPACK_COMPILER_SPEC', 'SPACK_SHORT_SPEC', 'SPACK_COMPILER_SPEC', 'SPACK_SHORT_SPEC',
'SPACK_CC_RPATH_ARG', 'SPACK_CXX_RPATH_ARG', 'SPACK_CC_RPATH_ARG', 'SPACK_CXX_RPATH_ARG',
'SPACK_F77_RPATH_ARG', 'SPACK_FC_RPATH_ARG'): 'SPACK_F77_RPATH_ARG', 'SPACK_FC_RPATH_ARG',
'SPACK_SYSTEM_DIRS'):
del os.environ[name] del os.environ[name]
...@@ -96,8 +99,8 @@ def test_static_to_shared_library(build_environment): ...@@ -96,8 +99,8 @@ def test_static_to_shared_library(build_environment):
shared_lib = '{0}.{1}'.format( shared_lib = '{0}.{1}'.format(
os.path.splitext(static_lib)[0], dso_suffix) os.path.splitext(static_lib)[0], dso_suffix)
assert output == expected[arch].format( assert set(output.split()) == set(expected[arch].format(
static_lib, shared_lib, os.path.basename(shared_lib)) static_lib, shared_lib, os.path.basename(shared_lib)).split())
@pytest.mark.regression('8345') @pytest.mark.regression('8345')
......
...@@ -166,50 +166,71 @@ def test_flags(self): ...@@ -166,50 +166,71 @@ def test_flags(self):
# Test ldflags added properly in ld mode # Test ldflags added properly in ld mode
self.check_ld('dump-args', test_command, self.check_ld('dump-args', test_command,
"ld " + 'ld -L foo ' +
'-rpath ' + self.prefix + '/lib ' + '-I/test/include -I/other/include arg1 ' +
'-rpath ' + self.prefix + '/lib64 ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-L foo ' + '-Wl,--end-group ' +
' '.join(test_command) + ' ' + '-llib3 -llib4 arg5 arg6 ' +
'-lfoo') '-L/test/lib -L/other/lib ' +
'-lfoo ' +
'-rpath /first/rpath -rpath /second/rpath ' +
'-rpath /third/rpath -rpath /fourth/rpath ' +
'-rpath /spack-test-prefix/lib ' +
'-rpath /spack-test-prefix/lib64')
# Test cppflags added properly in cpp mode # Test cppflags added properly in cpp mode
self.check_cpp('dump-args', test_command, self.check_cpp('dump-args', test_command,
"cpp " + "cpp " +
'-g -O1 ' + '-g -O1 ' +
' '.join(test_command)) '-I/test/include -I/other/include arg1 ' +
'-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Wl,--end-group ' +
'-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib')
# Test ldflags, cppflags, and language specific flags are added in # Test ldflags, cppflags, and language specific flags are added in
# proper order # proper order
self.check_cc('dump-args', test_command, self.check_cc('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-g -O1 -Wall -L foo ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-I/test/include -I/other/include arg1 ' +
'-g -O1 ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Wall ' + '-Wl,--end-group ' +
'-L foo ' + '-llib3 -llib4 arg5 arg6 ' +
' '.join(test_command) + ' ' + '-L/test/lib -L/other/lib ' +
'-lfoo') '-lfoo ' +
'-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
'-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64')
self.check_cxx('dump-args', test_command, self.check_cxx('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-g -O1 -Werror -L foo ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-I/test/include -I/other/include arg1 ' +
'-g -O1 ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Werror ' + '-Wl,--end-group ' +
'-L foo ' + '-llib3 -llib4 arg5 arg6 ' +
' '.join(test_command) + ' ' + '-L/test/lib -L/other/lib ' +
'-lfoo') '-lfoo ' +
'-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
'-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64')
self.check_fc('dump-args', test_command, self.check_fc('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-w -g -O1 -L foo ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-I/test/include -I/other/include arg1 ' +
'-w ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-g -O1 ' + '-Wl,--end-group ' +
'-L foo ' + '-llib3 -llib4 arg5 arg6 ' +
' '.join(test_command) + ' ' + '-L/test/lib -L/other/lib ' +
'-lfoo') '-lfoo ' +
'-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
'-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64')
del os.environ['SPACK_CFLAGS'] del os.environ['SPACK_CFLAGS']
del os.environ['SPACK_CXXFLAGS'] del os.environ['SPACK_CXXFLAGS']
...@@ -222,9 +243,15 @@ def test_dep_rpath(self): ...@@ -222,9 +243,15 @@ def test_dep_rpath(self):
"""Ensure RPATHs for root package are added.""" """Ensure RPATHs for root package are added."""
self.check_cc('dump-args', test_command, self.check_cc('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-I/test/include -I/other/include arg1 ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
' '.join(test_command)) '-Wl,--end-group ' +
'-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
'-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64')
def test_dep_include(self): def test_dep_include(self):
"""Ensure a single dependency include directory is added.""" """Ensure a single dependency include directory is added."""
...@@ -233,10 +260,16 @@ def test_dep_include(self): ...@@ -233,10 +260,16 @@ def test_dep_include(self):
os.environ['SPACK_LINK_DEPS'] = os.environ['SPACK_DEPENDENCIES'] os.environ['SPACK_LINK_DEPS'] = os.environ['SPACK_DEPENDENCIES']
self.check_cc('dump-args', test_command, self.check_cc('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-I/test/include -I/other/include ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-I' + self.dep4 + '/include arg1 ' +
'-I' + self.dep4 + '/include ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
' '.join(test_command)) '-Wl,--end-group ' +
'-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
'-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64')
def test_dep_lib(self): def test_dep_lib(self):
"""Ensure a single dependency RPATH is added.""" """Ensure a single dependency RPATH is added."""
...@@ -245,11 +278,17 @@ def test_dep_lib(self): ...@@ -245,11 +278,17 @@ def test_dep_lib(self):
os.environ['SPACK_LINK_DEPS'] = os.environ['SPACK_DEPENDENCIES'] os.environ['SPACK_LINK_DEPS'] = os.environ['SPACK_DEPENDENCIES']
self.check_cc('dump-args', test_command, self.check_cc('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-I/test/include -I/other/include arg1 ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Wl,--end-group ' +
'-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-L' + self.dep2 + '/lib64 ' + '-L' + self.dep2 + '/lib64 ' +
'-Wl,-rpath,' + self.dep2 + '/lib64 ' + '-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
' '.join(test_command)) '-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64 ' +
'-Wl,-rpath,' + self.dep2 + '/lib64')
def test_dep_lib_no_rpath(self): def test_dep_lib_no_rpath(self):
"""Ensure a single dependency link flag is added with no dep RPATH.""" """Ensure a single dependency link flag is added with no dep RPATH."""
...@@ -257,10 +296,16 @@ def test_dep_lib_no_rpath(self): ...@@ -257,10 +296,16 @@ def test_dep_lib_no_rpath(self):
os.environ['SPACK_LINK_DEPS'] = os.environ['SPACK_DEPENDENCIES'] os.environ['SPACK_LINK_DEPS'] = os.environ['SPACK_DEPENDENCIES']
self.check_cc('dump-args', test_command, self.check_cc('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-I/test/include -I/other/include arg1 ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Wl,--end-group ' +
'-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-L' + self.dep2 + '/lib64 ' + '-L' + self.dep2 + '/lib64 ' +
' '.join(test_command)) '-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
'-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64')
def test_dep_lib_no_lib(self): def test_dep_lib_no_lib(self):
"""Ensure a single dependency RPATH is added with no -L.""" """Ensure a single dependency RPATH is added with no -L."""
...@@ -268,10 +313,16 @@ def test_dep_lib_no_lib(self): ...@@ -268,10 +313,16 @@ def test_dep_lib_no_lib(self):
os.environ['SPACK_RPATH_DEPS'] = os.environ['SPACK_DEPENDENCIES'] os.environ['SPACK_RPATH_DEPS'] = os.environ['SPACK_DEPENDENCIES']
self.check_cc('dump-args', test_command, self.check_cc('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-I/test/include -I/other/include arg1 ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Wl,-rpath,' + self.dep2 + '/lib64 ' + '-Wl,--end-group ' +
' '.join(test_command)) '-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
'-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64 ' +
'-Wl,-rpath,' + self.dep2 + '/lib64')
def test_all_deps(self): def test_all_deps(self):
"""Ensure includes and RPATHs for all deps are added. """ """Ensure includes and RPATHs for all deps are added. """
...@@ -285,23 +336,25 @@ def test_all_deps(self): ...@@ -285,23 +336,25 @@ def test_all_deps(self):
# to. We could loosen that if it becomes necessary # to. We could loosen that if it becomes necessary
self.check_cc('dump-args', test_command, self.check_cc('dump-args', test_command,
self.realcc + ' ' + self.realcc + ' ' +
'-Wl,-rpath,' + self.prefix + '/lib ' + '-I/test/include -I/other/include ' +
'-Wl,-rpath,' + self.prefix + '/lib64 ' + '-I' + self.dep1 + '/include ' +
'-I' + self.dep4 + '/include ' +
'-L' + self.dep3 + '/lib64 ' +
'-Wl,-rpath,' + self.dep3 + '/lib64 ' +
'-I' + self.dep3 + '/include ' + '-I' + self.dep3 + '/include ' +
'-I' + self.dep4 + '/include ' +
'-L' + self.dep2 + '/lib64 ' + 'arg1 ' +
'-Wl,-rpath,' + self.dep2 + '/lib64 ' + '-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Wl,--end-group ' +
'-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-L' + self.dep1 + '/lib ' + '-L' + self.dep1 + '/lib ' +
'-L' + self.dep2 + '/lib64 ' +
'-L' + self.dep3 + '/lib64 ' +
'-Wl,-rpath,/first/rpath -Wl,-rpath,/second/rpath ' +
'-Wl,-rpath,/third/rpath -Wl,-rpath,/fourth/rpath ' +
'-Wl,-rpath,/spack-test-prefix/lib ' +
'-Wl,-rpath,/spack-test-prefix/lib64 ' +
'-Wl,-rpath,' + self.dep1 + '/lib ' + '-Wl,-rpath,' + self.dep1 + '/lib ' +
'-I' + self.dep1 + '/include ' + '-Wl,-rpath,' + self.dep2 + '/lib64 ' +
'-Wl,-rpath,' + self.dep3 + '/lib64')
' '.join(test_command))
def test_ld_deps(self): def test_ld_deps(self):
"""Ensure no (extra) -I args or -Wl, are passed in ld mode.""" """Ensure no (extra) -I args or -Wl, are passed in ld mode."""
...@@ -312,19 +365,22 @@ def test_ld_deps(self): ...@@ -312,19 +365,22 @@ def test_ld_deps(self):
self.check_ld('dump-args', test_command, self.check_ld('dump-args', test_command,
'ld ' + 'ld ' +
'-rpath ' + self.prefix + '/lib ' + '-I/test/include -I/other/include ' +
'-rpath ' + self.prefix + '/lib64 ' + 'arg1 ' +
'-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-L' + self.dep3 + '/lib64 ' + '-Wl,--end-group ' +
'-rpath ' + self.dep3 + '/lib64 ' + '-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-L' + self.dep2 + '/lib64 ' +
'-rpath ' + self.dep2 + '/lib64 ' +
'-L' + self.dep1 + '/lib ' + '-L' + self.dep1 + '/lib ' +
'-L' + self.dep2 + '/lib64 ' +
'-L' + self.dep3 + '/lib64 ' +
'-rpath /first/rpath -rpath /second/rpath ' +
'-rpath /third/rpath -rpath /fourth/rpath ' +
'-rpath /spack-test-prefix/lib ' +
'-rpath /spack-test-prefix/lib64 ' +
'-rpath ' + self.dep1 + '/lib ' + '-rpath ' + self.dep1 + '/lib ' +
'-rpath ' + self.dep2 + '/lib64 ' +
' '.join(test_command)) '-rpath ' + self.dep3 + '/lib64')
def test_ld_deps_no_rpath(self): def test_ld_deps_no_rpath(self):
"""Ensure SPACK_RPATH_DEPS controls RPATHs for ld.""" """Ensure SPACK_RPATH_DEPS controls RPATHs for ld."""
...@@ -334,14 +390,19 @@ def test_ld_deps_no_rpath(self): ...@@ -334,14 +390,19 @@ def test_ld_deps_no_rpath(self):
self.check_ld('dump-args', test_command, self.check_ld('dump-args', test_command,
'ld ' + 'ld ' +
'-rpath ' + self.prefix + '/lib ' + '-I/test/include -I/other/include ' +
'-rpath ' + self.prefix + '/lib64 ' + 'arg1 ' +
'-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-L' + self.dep3 + '/lib64 ' + '-Wl,--end-group ' +
'-L' + self.dep2 + '/lib64 ' + '-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-L' + self.dep1 + '/lib ' + '-L' + self.dep1 + '/lib ' +
'-L' + self.dep2 + '/lib64 ' +
' '.join(test_command)) '-L' + self.dep3 + '/lib64 ' +
'-rpath /first/rpath -rpath /second/rpath ' +
'-rpath /third/rpath -rpath /fourth/rpath ' +
'-rpath /spack-test-prefix/lib ' +
'-rpath /spack-test-prefix/lib64')
def test_ld_deps_no_link(self): def test_ld_deps_no_link(self):
"""Ensure SPACK_LINK_DEPS controls -L for ld.""" """Ensure SPACK_LINK_DEPS controls -L for ld."""
...@@ -351,14 +412,19 @@ def test_ld_deps_no_link(self): ...@@ -351,14 +412,19 @@ def test_ld_deps_no_link(self):
self.check_ld('dump-args', test_command, self.check_ld('dump-args', test_command,
'ld ' + 'ld ' +
'-rpath ' + self.prefix + '/lib ' + '-I/test/include -I/other/include ' +
'-rpath ' + self.prefix + '/lib64 ' + 'arg1 ' +
'-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-rpath ' + self.dep3 + '/lib64 ' + '-Wl,--end-group ' +
'-rpath ' + self.dep2 + '/lib64 ' + '-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-rpath /first/rpath -rpath /second/rpath ' +
'-rpath /third/rpath -rpath /fourth/rpath ' +
'-rpath /spack-test-prefix/lib ' +
'-rpath /spack-test-prefix/lib64 ' +
'-rpath ' + self.dep1 + '/lib ' + '-rpath ' + self.dep1 + '/lib ' +
'-rpath ' + self.dep2 + '/lib64 ' +
' '.join(test_command)) '-rpath ' + self.dep3 + '/lib64')
def test_ld_deps_reentrant(self): def test_ld_deps_reentrant(self):
"""Make sure ld -r is handled correctly on OS's where it doesn't """Make sure ld -r is handled correctly on OS's where it doesn't
...@@ -371,18 +437,30 @@ def test_ld_deps_reentrant(self): ...@@ -371,18 +437,30 @@ def test_ld_deps_reentrant(self):
reentrant_test_command = ['-r'] + test_command reentrant_test_command = ['-r'] + test_command
self.check_ld('dump-args', reentrant_test_command, self.check_ld('dump-args', reentrant_test_command,
'ld ' + 'ld ' +
'-rpath ' + self.prefix + '/lib ' + '-I/test/include -I/other/include ' +
'-rpath ' + self.prefix + '/lib64 ' + '-r arg1 ' +
'-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Wl,--end-group ' +
'-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-L' + self.dep1 + '/lib ' + '-L' + self.dep1 + '/lib ' +
'-rpath ' + self.dep1 + '/lib ' + '-rpath /first/rpath -rpath /second/rpath ' +
'-rpath /third/rpath -rpath /fourth/rpath ' +
'-r ' + '-rpath /spack-test-prefix/lib ' +
' '.join(test_command)) '-rpath /spack-test-prefix/lib64 ' +
'-rpath ' + self.dep1 + '/lib')
# rpaths from the underlying command will still appear
# Spack will not add its own rpaths.
os.environ['SPACK_SHORT_SPEC'] = "foo@1.2=darwin-x86_64" os.environ['SPACK_SHORT_SPEC'] = "foo@1.2=darwin-x86_64"
self.check_ld('dump-args', reentrant_test_command, self.check_ld('dump-args', reentrant_test_command,
'ld ' + 'ld ' +
'-I/test/include -I/other/include ' +
'-r arg1 ' +
'-Wl,--start-group arg2 arg3 -llib1 -llib2 arg4 ' +
'-Wl,--end-group ' +
'-llib3 -llib4 arg5 arg6 ' +
'-L/test/lib -L/other/lib ' +
'-L' + self.dep1 + '/lib ' + '-L' + self.dep1 + '/lib ' +
'-r ' + '-rpath /first/rpath -rpath /second/rpath ' +
' '.join(test_command)) '-rpath /third/rpath -rpath /fourth/rpath')
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment