summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2018-08-14 11:59:11 +0200
committerTodd Gamblin <tgamblin@llnl.gov>2018-08-27 14:49:50 -0700
commit8ecf5ae2eebf85e580e0a23ccd2bebed094c507f (patch)
tree1ae8323308cab1ab512fc25bea960b9eb365d03d /lib
parent2fdfa4673571c053e1f1a72a4ead5d97464d720f (diff)
downloadspack-8ecf5ae2eebf85e580e0a23ccd2bebed094c507f.tar.gz
spack-8ecf5ae2eebf85e580e0a23ccd2bebed094c507f.tar.bz2
spack-8ecf5ae2eebf85e580e0a23ccd2bebed094c507f.tar.xz
spack-8ecf5ae2eebf85e580e0a23ccd2bebed094c507f.zip
Spack can guess lmod core compilers, if none is already present
closes #8916 Currently Spack ends with an error if asked to write lmod modules files and the 'core_compilers' entry is not found in `modules.yaml`. After this PR an attempt will be made to guess that entry and the site configuration file will be updated accordingly. This is similar to what Spack already does to guess compilers on first run.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/modules/lmod.py46
-rw-r--r--lib/spack/spack/test/modules/lmod.py23
2 files changed, 64 insertions, 5 deletions
diff --git a/lib/spack/spack/modules/lmod.py b/lib/spack/spack/modules/lmod.py
index aa41b27daa..a057f2bf3a 100644
--- a/lib/spack/spack/modules/lmod.py
+++ b/lib/spack/spack/modules/lmod.py
@@ -65,6 +65,42 @@ def make_context(spec):
return LmodContext(conf)
+def guess_core_compilers(store=False):
+ """Guesses the list of core compilers installed in the system.
+
+ Args:
+ store (bool): if True writes the core compilers to the
+ modules.yaml configuration file
+
+ Returns:
+ List of core compilers, if found, or None
+ """
+ core_compilers = []
+ for compiler_config in spack.compilers.all_compilers_config():
+ try:
+ compiler = compiler_config['compiler']
+ # A compiler is considered to be a core compiler if any of the
+ # C, C++ or Fortran compilers reside in a system directory
+ is_system_compiler = any(
+ os.path.dirname(x) in spack.util.environment.system_dirs
+ for x in compiler['paths'].values() if x is not None
+ )
+ if is_system_compiler:
+ core_compilers.append(str(compiler['spec']))
+ except (KeyError, TypeError, AttributeError):
+ continue
+
+ if store and core_compilers:
+ # If we asked to store core compilers, update the entry
+ # at 'site' scope (i.e. within the directory hierarchy
+ # of Spack itself)
+ modules_cfg = spack.config.get('modules', scope='site')
+ modules_cfg.setdefault('lmod', {})['core_compilers'] = core_compilers
+ spack.config.set('modules', modules_cfg, scope='site')
+
+ return core_compilers or None
+
+
class LmodConfiguration(BaseConfiguration):
"""Configuration class for lmod module files."""
@@ -77,12 +113,12 @@ class LmodConfiguration(BaseConfiguration):
specified in the configuration file or the sequence
is empty
"""
- value = configuration.get('core_compilers')
- if value is None:
- msg = "'core_compilers' key not found in configuration file"
- raise CoreCompilersNotFoundError(msg)
+ value = configuration.get(
+ 'core_compilers'
+ ) or guess_core_compilers(store=True)
+
if not value:
- msg = "'core_compilers' list cannot be empty"
+ msg = 'the key "core_compilers" must be set in modules.yaml'
raise CoreCompilersNotFoundError(msg)
return value
diff --git a/lib/spack/spack/test/modules/lmod.py b/lib/spack/spack/test/modules/lmod.py
index 2b3949621d..b262ab7b5b 100644
--- a/lib/spack/spack/test/modules/lmod.py
+++ b/lib/spack/spack/test/modules/lmod.py
@@ -258,3 +258,26 @@ class TestLmod(object):
writer, spec = factory('externaltool')
assert 'unknown' in writer.context.configure_options
+
+ def test_guess_core_compilers(
+ self, factory, module_configuration, monkeypatch
+ ):
+ """Check that we can guess core compilers."""
+
+ # In this case we miss the entry completely
+ module_configuration('missing_core_compilers')
+
+ # Our mock paths must be detected as system paths
+ monkeypatch.setattr(
+ spack.util.environment, 'system_dirs', ['/path/to']
+ )
+
+ # We don't want to really write into user configuration
+ # when running tests
+ def no_op_set(*args, **kwargs):
+ pass
+ monkeypatch.setattr(spack.config, 'set', no_op_set)
+
+ # Assert we have core compilers now
+ writer, _ = factory(mpileaks_spec_string)
+ assert writer.conf.core_compilers