summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2016-05-10 01:56:49 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2016-05-10 01:56:49 -0700
commit42edb6840ebcccb5b3d421c0b749333a6754d4a1 (patch)
tree64cd37b43afd66150d91e5dbfe1788b1334cedee
parenta2528a86b419d364edf86da30a7dc15921ccf96f (diff)
parent6665a996e62e2097b68392afaa45d01305bcc399 (diff)
downloadspack-42edb6840ebcccb5b3d421c0b749333a6754d4a1.tar.gz
spack-42edb6840ebcccb5b3d421c0b749333a6754d4a1.tar.bz2
spack-42edb6840ebcccb5b3d421c0b749333a6754d4a1.tar.xz
spack-42edb6840ebcccb5b3d421c0b749333a6754d4a1.zip
Merge pull request #905 from adamjstewart/features/rpath_flag
Allow compilers to specify their own rpath linking flags
-rw-r--r--lib/spack/docs/packaging_guide.rst16
-rwxr-xr-xlib/spack/env/cc39
-rw-r--r--lib/spack/spack/build_environment.py14
-rw-r--r--lib/spack/spack/compiler.py18
-rw-r--r--lib/spack/spack/compilers/nag.py11
-rw-r--r--lib/spack/spack/test/cc.py5
6 files changed, 80 insertions, 23 deletions
diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst
index 31c676d4f5..1b7941ab24 100644
--- a/lib/spack/docs/packaging_guide.rst
+++ b/lib/spack/docs/packaging_guide.rst
@@ -1803,15 +1803,15 @@ Compile-time library search paths
* ``-L$dep_prefix/lib``
* ``-L$dep_prefix/lib64``
Runtime library search paths (RPATHs)
- * ``-Wl,-rpath,$dep_prefix/lib``
- * ``-Wl,-rpath,$dep_prefix/lib64``
+ * ``$rpath_flag$dep_prefix/lib``
+ * ``$rpath_flag$dep_prefix/lib64``
Include search paths
* ``-I$dep_prefix/include``
An example of this would be the ``libdwarf`` build, which has one
dependency: ``libelf``. Every call to ``cc`` in the ``libdwarf``
build will have ``-I$LIBELF_PREFIX/include``,
-``-L$LIBELF_PREFIX/lib``, and ``-Wl,-rpath,$LIBELF_PREFIX/lib``
+``-L$LIBELF_PREFIX/lib``, and ``$rpath_flag$LIBELF_PREFIX/lib``
inserted on the command line. This is done transparently to the
project's build system, which will just think it's using a system
where ``libelf`` is readily available. Because of this, you **do
@@ -1831,6 +1831,14 @@ successfully find ``libdwarf.h`` and ``libdwarf.so``, without the
packager having to provide ``--with-libdwarf=/path/to/libdwarf`` on
the command line.
+.. note::
+
+ For most compilers, ``$rpath_flag`` is ``-Wl,-rpath,``. However, NAG
+ passes its flags to GCC instead of passing them directly to the linker.
+ Therefore, its ``$rpath_flag`` is doubly wrapped: ``-Wl,-Wl,,-rpath,``.
+ ``$rpath_flag`` can be overriden on a compiler specific basis in
+ ``lib/spack/spack/compilers/$compiler.py``.
+
Compiler flags
~~~~~~~~~~~~~~
In rare circumstances such as compiling and running small unit tests, a package
@@ -1848,8 +1856,6 @@ package supports additional variants like
variant('openmp', default=True, description="Enable OpenMP support.")
-
-
Message Parsing Interface (MPI)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is common for high performance computing software/packages to use ``MPI``.
diff --git a/lib/spack/env/cc b/lib/spack/env/cc
index cb07a2ffea..4564e84bd2 100755
--- a/lib/spack/env/cc
+++ b/lib/spack/env/cc
@@ -38,15 +38,20 @@
# -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
# as part of spack.package.Package.do_install().
-parameters="
-SPACK_PREFIX
-SPACK_ENV_PATH
-SPACK_DEBUG_LOG_DIR
-SPACK_COMPILER_SPEC
-SPACK_SHORT_SPEC"
+parameters=(
+ SPACK_PREFIX
+ SPACK_ENV_PATH
+ SPACK_DEBUG_LOG_DIR
+ SPACK_COMPILER_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:
# SPACK_CC, SPACK_CXX, SPACK_F77, SPACK_FC
@@ -64,7 +69,7 @@ function die {
exit 1
}
-for param in $parameters; do
+for param in ${parameters[@]}; do
if [[ -z ${!param} ]]; then
die "Spack compiler must be run from Spack! Input '$param' is missing."
fi
@@ -85,6 +90,7 @@ done
# ccld compile & link
command=$(basename "$0")
+comp="CC"
case "$command" in
cpp)
mode=cpp
@@ -92,18 +98,22 @@ case "$command" in
cc|c89|c99|gcc|clang|icc|pgcc|xlc)
command="$SPACK_CC"
language="C"
+ comp="CC"
;;
c++|CC|g++|clang++|icpc|pgc++|xlc++)
command="$SPACK_CXX"
language="C++"
+ comp="CXX"
;;
f90|fc|f95|gfortran|ifort|pgfortran|xlf90|nagfor)
command="$SPACK_FC"
language="Fortran 90"
+ comp="FC"
;;
f77|gfortran|ifort|pgfortran|xlf|nagfor)
command="$SPACK_F77"
language="Fortran 77"
+ comp="F77"
;;
ld)
mode=ld
@@ -142,6 +152,9 @@ if [[ -z $mode ]]; then
done
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.
if [[ $SPACK_TEST_COMMAND == dump-mode ]]; then
echo "$mode"
@@ -188,7 +201,7 @@ for dep in "${deps[@]}"; do
# Prepend lib and RPATH directories
if [[ -d $dep/lib ]]; 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[@]}")
elif [[ $mode == ld ]]; then
$add_rpaths && args=("-rpath" "$dep/lib" "${args[@]}")
@@ -199,7 +212,7 @@ for dep in "${deps[@]}"; do
# Prepend lib64 and RPATH directories
if [[ -d $dep/lib64 ]]; 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[@]}")
elif [[ $mode == ld ]]; then
$add_rpaths && args=("-rpath" "$dep/lib64" "${args[@]}")
@@ -210,9 +223,11 @@ done
# Include all -L's and prefix/whatever dirs in rpath
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
- $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
#
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index cd9f647ddf..8961886049 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -98,21 +98,27 @@ def set_compiler_environment_variables(pkg, env):
# and return it
# TODO : add additional kwargs for better diagnostics, like requestor, ttyout, ttyerr, etc.
link_dir = spack.build_env_path
- env.set('CC', join_path(link_dir, pkg.compiler.link_paths['cc']))
+ env.set('CC', join_path(link_dir, pkg.compiler.link_paths['cc']))
env.set('CXX', join_path(link_dir, pkg.compiler.link_paths['cxx']))
env.set('F77', join_path(link_dir, pkg.compiler.link_paths['f77']))
- env.set('FC', join_path(link_dir, pkg.compiler.link_paths['fc']))
+ env.set('FC', join_path(link_dir, pkg.compiler.link_paths['fc']))
# Set SPACK compiler variables so that our wrapper knows what to call
compiler = pkg.compiler
if compiler.cc:
- env.set('SPACK_CC', compiler.cc)
+ env.set('SPACK_CC', compiler.cc)
if compiler.cxx:
env.set('SPACK_CXX', compiler.cxx)
if compiler.f77:
env.set('SPACK_F77', compiler.f77)
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))
return env
diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py
index 030dc449fc..0f208caaf3 100644
--- a/lib/spack/spack/compiler.py
+++ b/lib/spack/spack/compiler.py
@@ -91,8 +91,22 @@ class Compiler(object):
# version suffix for gcc.
suffixes = [r'-.*']
- # Names of generic arguments used by this compiler
- arg_rpath = '-Wl,-rpath,%s'
+ # Default flags used by a compiler to set an rpath
+ @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):
diff --git a/lib/spack/spack/compilers/nag.py b/lib/spack/spack/compilers/nag.py
index e9038c1039..49b77eae6b 100644
--- a/lib/spack/spack/compilers/nag.py
+++ b/lib/spack/spack/compilers/nag.py
@@ -31,6 +31,17 @@ class Nag(Compiler):
# However, it can be mixed with a compiler that does support it
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
def default_version(self, comp):
"""The '-V' option works for nag compilers.
diff --git a/lib/spack/spack/test/cc.py b/lib/spack/spack/test/cc.py
index 594cd6efe9..35392d9d6d 100644
--- a/lib/spack/spack/test/cc.py
+++ b/lib/spack/spack/test/cc.py
@@ -67,6 +67,11 @@ class CompilerTest(unittest.TestCase):
os.environ['SPACK_COMPILER_SPEC'] = "gcc@4.4.7"
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
self.tmp_deps = tempfile.mkdtemp()
self.dep1 = join_path(self.tmp_deps, 'dep1')