Allow compilers to specify their own rpath linking flags

This commit is contained in:
Adam J. Stewart 2016-05-05 10:50:07 -05:00
parent cbae98670b
commit 4473311bdb
5 changed files with 69 additions and 18 deletions

39
lib/spack/env/cc vendored
View File

@ -38,15 +38,20 @@
# -Wl,-rpath arguments for dependency /lib directories. # -Wl,-rpath arguments for dependency /lib directories.
# #
# This is the list of environment variables that need to be set before # This is an array of environment variables that need to be set before
# the script runs. They are set by routines in spack.build_environment # the script runs. They are set by routines in spack.build_environment
# as part of spack.package.Package.do_install(). # as part of spack.package.Package.do_install().
parameters=" parameters=(
SPACK_PREFIX SPACK_PREFIX
SPACK_ENV_PATH SPACK_ENV_PATH
SPACK_DEBUG_LOG_DIR SPACK_DEBUG_LOG_DIR
SPACK_COMPILER_SPEC SPACK_COMPILER_SPEC
SPACK_SHORT_SPEC" SPACK_CC_RPATH_ARG
SPACK_CXX_RPATH_ARG
SPACK_F77_RPATH_ARG
SPACK_FC_RPATH_ARG
SPACK_SHORT_SPEC
)
# The compiler input variables are checked for sanity later: # The compiler input variables are checked for sanity later:
# SPACK_CC, SPACK_CXX, SPACK_F77, SPACK_FC # SPACK_CC, SPACK_CXX, SPACK_F77, SPACK_FC
@ -64,7 +69,7 @@ function die {
exit 1 exit 1
} }
for param in $parameters; do for param in ${parameters[@]}; do
if [[ -z ${!param} ]]; then if [[ -z ${!param} ]]; then
die "Spack compiler must be run from Spack! Input '$param' is missing." die "Spack compiler must be run from Spack! Input '$param' is missing."
fi fi
@ -85,6 +90,7 @@ done
# ccld compile & link # ccld compile & link
command=$(basename "$0") command=$(basename "$0")
comp="CC"
case "$command" in case "$command" in
cpp) cpp)
mode=cpp mode=cpp
@ -92,18 +98,22 @@ case "$command" in
cc|c89|c99|gcc|clang|icc|pgcc|xlc) cc|c89|c99|gcc|clang|icc|pgcc|xlc)
command="$SPACK_CC" command="$SPACK_CC"
language="C" language="C"
comp="CC"
;; ;;
c++|CC|g++|clang++|icpc|pgc++|xlc++) c++|CC|g++|clang++|icpc|pgc++|xlc++)
command="$SPACK_CXX" command="$SPACK_CXX"
language="C++" language="C++"
comp="CXX"
;; ;;
f90|fc|f95|gfortran|ifort|pgfortran|xlf90|nagfor) f90|fc|f95|gfortran|ifort|pgfortran|xlf90|nagfor)
command="$SPACK_FC" command="$SPACK_FC"
language="Fortran 90" language="Fortran 90"
comp="FC"
;; ;;
f77|gfortran|ifort|pgfortran|xlf|nagfor) f77|gfortran|ifort|pgfortran|xlf|nagfor)
command="$SPACK_F77" command="$SPACK_F77"
language="Fortran 77" language="Fortran 77"
comp="F77"
;; ;;
ld) ld)
mode=ld mode=ld
@ -142,6 +152,9 @@ if [[ -z $mode ]]; then
done done
fi fi
# Set up rpath variable according to language.
eval rpath=\$SPACK_${comp}_RPATH_ARG
# Dump the version and exit if we're in testing mode. # Dump the version and exit if we're in testing mode.
if [[ $SPACK_TEST_COMMAND == dump-mode ]]; then if [[ $SPACK_TEST_COMMAND == dump-mode ]]; then
echo "$mode" echo "$mode"
@ -188,7 +201,7 @@ for dep in "${deps[@]}"; do
# Prepend lib and RPATH directories # Prepend lib and RPATH directories
if [[ -d $dep/lib ]]; then if [[ -d $dep/lib ]]; then
if [[ $mode == ccld ]]; then if [[ $mode == ccld ]]; then
$add_rpaths && args=("-Wl,-rpath,$dep/lib" "${args[@]}") $add_rpaths && args=("$rpath$dep/lib" "${args[@]}")
args=("-L$dep/lib" "${args[@]}") args=("-L$dep/lib" "${args[@]}")
elif [[ $mode == ld ]]; then elif [[ $mode == ld ]]; then
$add_rpaths && args=("-rpath" "$dep/lib" "${args[@]}") $add_rpaths && args=("-rpath" "$dep/lib" "${args[@]}")
@ -199,7 +212,7 @@ for dep in "${deps[@]}"; do
# Prepend lib64 and RPATH directories # Prepend lib64 and RPATH directories
if [[ -d $dep/lib64 ]]; then if [[ -d $dep/lib64 ]]; then
if [[ $mode == ccld ]]; then if [[ $mode == ccld ]]; then
$add_rpaths && args=("-Wl,-rpath,$dep/lib64" "${args[@]}") $add_rpaths && args=("$rpath$dep/lib64" "${args[@]}")
args=("-L$dep/lib64" "${args[@]}") args=("-L$dep/lib64" "${args[@]}")
elif [[ $mode == ld ]]; then elif [[ $mode == ld ]]; then
$add_rpaths && args=("-rpath" "$dep/lib64" "${args[@]}") $add_rpaths && args=("-rpath" "$dep/lib64" "${args[@]}")
@ -210,9 +223,11 @@ done
# Include all -L's and prefix/whatever dirs in rpath # Include all -L's and prefix/whatever dirs in rpath
if [[ $mode == ccld ]]; then if [[ $mode == ccld ]]; then
$add_rpaths && args=("-Wl,-rpath,$SPACK_PREFIX/lib" "-Wl,-rpath,$SPACK_PREFIX/lib64" "${args[@]}") $add_rpaths && args=("$rpath$SPACK_PREFIX/lib64" "${args[@]}")
$add_rpaths && args=("$rpath$SPACK_PREFIX/lib" "${args[@]}")
elif [[ $mode == ld ]]; then elif [[ $mode == ld ]]; then
$add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib" "-rpath" "$SPACK_PREFIX/lib64" "${args[@]}") $add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib64" "${args[@]}")
$add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib" "${args[@]}")
fi fi
# #

View File

@ -114,6 +114,12 @@ def set_compiler_environment_variables(pkg, env):
if compiler.fc: if compiler.fc:
env.set('SPACK_FC', compiler.fc) env.set('SPACK_FC', compiler.fc)
# Set SPACK compiler rpath flags so that our wrapper knows what to use
env.set('SPACK_CC_RPATH_ARG', compiler.cc_rpath_arg)
env.set('SPACK_CXX_RPATH_ARG', compiler.cxx_rpath_arg)
env.set('SPACK_F77_RPATH_ARG', compiler.f77_rpath_arg)
env.set('SPACK_FC_RPATH_ARG', compiler.fc_rpath_arg)
env.set('SPACK_COMPILER_SPEC', str(pkg.spec.compiler)) env.set('SPACK_COMPILER_SPEC', str(pkg.spec.compiler))
return env return env

View File

@ -91,8 +91,22 @@ class Compiler(object):
# version suffix for gcc. # version suffix for gcc.
suffixes = [r'-.*'] suffixes = [r'-.*']
# Names of generic arguments used by this compiler # Flags used by this compiler to set an rpath
arg_rpath = '-Wl,-rpath,%s' @property
def cc_rpath_arg(self):
return '-Wl,-rpath,'
@property
def cxx_rpath_arg(self):
return '-Wl,-rpath,'
@property
def f77_rpath_arg(self):
return '-Wl,-rpath,'
@property
def fc_rpath_arg(self):
return '-Wl,-rpath,'
def __init__(self, cspec, cc, cxx, f77, fc): def __init__(self, cspec, cc, cxx, f77, fc):

View File

@ -31,6 +31,17 @@ def cxx11_flag(self):
# However, it can be mixed with a compiler that does support it # However, it can be mixed with a compiler that does support it
return "-std=c++11" return "-std=c++11"
# Unlike other compilers, the NAG compiler passes options to GCC, which
# then passes them to the linker. Therefore, we need to doubly wrap the
# options with '-Wl,-Wl,,'
@property
def f77_rpath_arg(self):
return '-Wl,-Wl,,-rpath,'
@property
def fc_rpath_arg(self):
return '-Wl,-Wl,,-rpath,'
@classmethod @classmethod
def default_version(self, comp): def default_version(self, comp):
"""The '-V' option works for nag compilers. """The '-V' option works for nag compilers.

View File

@ -67,6 +67,11 @@ def setUp(self):
os.environ['SPACK_COMPILER_SPEC'] = "gcc@4.4.7" os.environ['SPACK_COMPILER_SPEC'] = "gcc@4.4.7"
os.environ['SPACK_SHORT_SPEC'] = "foo@1.2" os.environ['SPACK_SHORT_SPEC'] = "foo@1.2"
os.environ['SPACK_CC_RPATH_ARG'] = "-Wl,-rpath"
os.environ['SPACK_CXX_RPATH_ARG'] = "-Wl,-rpath"
os.environ['SPACK_F77_RPATH_ARG'] = "-Wl,-rpath"
os.environ['SPACK_FC_RPATH_ARG'] = "-Wl,-rpath"
# Make some fake dependencies # Make some fake dependencies
self.tmp_deps = tempfile.mkdtemp() self.tmp_deps = tempfile.mkdtemp()
self.dep1 = join_path(self.tmp_deps, 'dep1') self.dep1 = join_path(self.tmp_deps, 'dep1')