summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorscheibelp <scheibel1@llnl.gov>2016-11-09 08:00:34 -0800
committerTodd Gamblin <tgamblin@llnl.gov>2016-11-09 08:00:34 -0800
commitbece9aca84061ef82b61f20ed2b00dbb65275b1c (patch)
tree0094d30902eb28a760cae67af09d99283b4d37d4 /lib
parent2e11e7e456668f81392b12be124d8280b511a7a4 (diff)
downloadspack-bece9aca84061ef82b61f20ed2b00dbb65275b1c.tar.gz
spack-bece9aca84061ef82b61f20ed2b00dbb65275b1c.tar.bz2
spack-bece9aca84061ef82b61f20ed2b00dbb65275b1c.tar.xz
spack-bece9aca84061ef82b61f20ed2b00dbb65275b1c.zip
Allow compiler wrapper to modify environment (#2275)
* Allow compiler wrapper to modify environment This adds the ability to set environment variables in the compiler wrappers. These are specified as part of the compilers.yaml config. The user may also specify RPATHs in compilers.yaml that should be added. * Minor doc tweak
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/docs/basic_usage.rst29
-rwxr-xr-xlib/spack/env/cc22
-rw-r--r--lib/spack/spack/build_environment.py17
-rw-r--r--lib/spack/spack/cmd/compiler.py10
-rw-r--r--lib/spack/spack/compiler.py6
-rw-r--r--lib/spack/spack/compilers/__init__.py11
-rw-r--r--lib/spack/spack/schema/compilers.py22
7 files changed, 112 insertions, 5 deletions
diff --git a/lib/spack/docs/basic_usage.rst b/lib/spack/docs/basic_usage.rst
index ca89846d46..03e6d581a4 100644
--- a/lib/spack/docs/basic_usage.rst
+++ b/lib/spack/docs/basic_usage.rst
@@ -672,6 +672,35 @@ in GNU Autotools. If all flags are set, the order is
``$cppflags $cflags|$cxxflags $ldflags <command> $ldlibs`` for C and C++ and
``$fflags $cppflags $ldflags <command> $ldlibs`` for Fortran.
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Compiler environment variables and additional RPATHs
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In the exceptional case a compiler requires setting special environment
+variables, like an explicit library load path. These can bet set in an
+extra section in the compiler configuration. The user can also specify
+additional ``RPATHs`` that the compiler will add to all executables
+generated by that compiler. This is useful for forcing certain compilers
+to RPATH their own runtime libraries, so that executables will run
+without the need to set ``LD_LIBRARY_PATH``.
+
+.. code-block:: yaml
+
+ compilers:
+ - compiler:
+ spec: gcc@4.9.3
+ paths:
+ cc: /opt/gcc/bin/gcc
+ c++: /opt/gcc/bin/g++
+ f77: /opt/gcc/bin/gfortran
+ fc: /opt/gcc/bin/gfortran
+ environment:
+ set:
+ LD_LIBRARY_PATH : /opt/gcc/lib
+ extra_rpaths:
+ - /path/to/some/compiler/runtime/directory
+ - /path/to/some/other/compiler/runtime/directory
+
^^^^^^^^^^^^^^^^^^^^^^^
Architecture specifiers
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/lib/spack/env/cc b/lib/spack/env/cc
index 84a17abf20..c4e51834a5 100755
--- a/lib/spack/env/cc
+++ b/lib/spack/env/cc
@@ -175,6 +175,18 @@ if [[ -z $command ]]; then
fi
#
+# Set paths as defined in the 'environment' section of the compiler config
+# names are stored in SPACK_ENV_TO_SET
+# values are stored in SPACK_ENV_SET_<varname>
+#
+IFS=':' read -ra env_set_varnames <<< "$SPACK_ENV_TO_SET"
+for varname in "${env_set_varnames[@]}"; do
+ spack_varname="SPACK_ENV_SET_$varname"
+ export $varname=${!spack_varname}
+ unset $spack_varname
+done
+
+#
# Filter '.' and Spack environment directories out of PATH so that
# this script doesn't just call itself
#
@@ -311,6 +323,16 @@ elif [[ $mode == ld ]]; then
$add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib" "${args[@]}")
fi
+# Set extra RPATHs
+IFS=':' read -ra extra_rpaths <<< "$SPACK_COMPILER_EXTRA_RPATHS"
+for extra_rpath in "${extra_rpaths[@]}"; do
+ if [[ $mode == ccld ]]; then
+ $add_rpaths && args=("$rpath$extra_rpath" "${args[@]}")
+ elif [[ $mode == ld ]]; then
+ $add_rpaths && args=("-rpath" "$extra_rpath" "${args[@]}")
+ fi
+done
+
# Add SPACK_LDLIBS to args
case "$mode" in
ld|ccld)
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 1e6c473efd..49df7a90b4 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -302,6 +302,23 @@ def set_build_environment_variables(pkg, env, dirty=False):
if '/macports/' in p:
env.remove_path('PATH', p)
+ # Set environment variables if specified for
+ # the given compiler
+ compiler = pkg.compiler
+ environment = compiler.environment
+ if 'set' in environment:
+ env_to_set = environment['set']
+ for key, value in env_to_set.iteritems():
+ env.set('SPACK_ENV_SET_%s' % key, value)
+ env.set('%s' % key, value)
+ # Let shell know which variables to set
+ env_variables = ":".join(env_to_set.keys())
+ env.set('SPACK_ENV_TO_SET', env_variables)
+
+ if compiler.extra_rpaths:
+ extra_rpaths = ':'.join(compiler.extra_rpaths)
+ env.set('SPACK_COMPILER_EXTRA_RPATHS', extra_rpaths)
+
# Add bin directories from dependencies to the PATH for the build.
bin_dirs = reversed(filter(os.path.isdir, [
'%s/bin' % d.prefix for d in pkg.spec.dependencies(deptype='build')]))
diff --git a/lib/spack/spack/cmd/compiler.py b/lib/spack/spack/cmd/compiler.py
index 522530a6f7..80a3c71d61 100644
--- a/lib/spack/spack/cmd/compiler.py
+++ b/lib/spack/spack/cmd/compiler.py
@@ -140,6 +140,16 @@ def compiler_info(args):
print "\tflags:"
for flag, flag_value in c.flags.iteritems():
print "\t\t%s = %s" % (flag, flag_value)
+ if len(c.environment) != 0:
+ if len(c.environment['set']) != 0:
+ print "\tenvironment:"
+ print "\t set:"
+ for key, value in c.environment['set'].iteritems():
+ print "\t %s = %s" % (key, value)
+ if c.extra_rpaths:
+ print "\tExtra rpaths:"
+ for extra_rpath in c.extra_rpaths:
+ print "\t\t%s" % extra_rpath
print "\tmodules = %s" % c.modules
print "\toperating system = %s" % c.operating_system
diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py
index fc663ea646..5170872cf7 100644
--- a/lib/spack/spack/compiler.py
+++ b/lib/spack/spack/compiler.py
@@ -113,7 +113,8 @@ class Compiler(object):
PrgEnv_compiler = None
def __init__(self, cspec, operating_system,
- paths, modules=[], alias=None, **kwargs):
+ paths, modules=[], alias=None, environment=None,
+ extra_rpaths=None, **kwargs):
self.operating_system = operating_system
self.spec = cspec
self.modules = modules
@@ -135,6 +136,9 @@ class Compiler(object):
else:
self.fc = check(paths[3])
+ self.environment = environment
+ self.extra_rpaths = extra_rpaths or []
+
# Unfortunately have to make sure these params are accepted
# in the same order they are returned by sorted(flags)
# in compilers/__init__.py
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index 72f8532d3e..5b049367cc 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -40,7 +40,8 @@ from spack.util.naming import mod_to_class
_imported_compilers_module = 'spack.compilers'
_path_instance_vars = ['cc', 'cxx', 'f77', 'fc']
-_other_instance_vars = ['modules', 'operating_system']
+_other_instance_vars = ['modules', 'operating_system', 'environment',
+ 'extra_rpaths']
_cache_config_file = []
@@ -61,6 +62,8 @@ def _to_dict(compiler):
d['flags'] = dict((fname, fvals) for fname, fvals in compiler.flags)
d['operating_system'] = str(compiler.operating_system)
d['modules'] = compiler.modules if compiler.modules else []
+ d['environment'] = compiler.environment if compiler.environment else {}
+ d['extra_rpaths'] = compiler.extra_rpaths if compiler.extra_rpaths else []
if compiler.alias:
d['alias'] = compiler.alias
@@ -238,11 +241,13 @@ def compilers_for_spec(compiler_spec, scope=None, **kwargs):
items['operating_system'], platform)
alias = items.get('alias', None)
-
compiler_flags = items.get('flags', {})
+ environment = items.get('environment', {})
+ extra_rpaths = items.get('extra_rpaths', [])
compilers.append(
- cls(cspec, os, compiler_paths, mods, alias, **compiler_flags))
+ cls(cspec, os, compiler_paths, mods, alias, environment,
+ extra_rpaths, **compiler_flags))
return compilers
diff --git a/lib/spack/spack/schema/compilers.py b/lib/spack/spack/schema/compilers.py
index ea1071729f..282eddf91b 100644
--- a/lib/spack/spack/schema/compilers.py
+++ b/lib/spack/spack/schema/compilers.py
@@ -79,7 +79,27 @@ schema = {
{'type': 'null'}]},
'modules': {'anyOf': [{'type': 'string'},
{'type': 'null'},
- {'type': 'array'}]}
+ {'type': 'array'}]},
+ 'environment': {
+ 'type': 'object',
+ 'default': {},
+ 'additionalProperties': False,
+ 'properties': {
+ 'set': {
+ 'type': 'object',
+ 'patternProperties': {
+ r'\w[\w-]*': { # variable name
+ 'type': 'string'
+ }
+ }
+ }
+ }
+ },
+ 'extra_rpaths': {
+ 'type': 'array',
+ 'default': [],
+ 'items': {'type': 'string'}
+ }
},
},
},