diff options
author | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2018-08-14 11:59:11 +0200 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2018-08-27 14:49:50 -0700 |
commit | 8ecf5ae2eebf85e580e0a23ccd2bebed094c507f (patch) | |
tree | 1ae8323308cab1ab512fc25bea960b9eb365d03d /lib | |
parent | 2fdfa4673571c053e1f1a72a4ead5d97464d720f (diff) | |
download | spack-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.py | 46 | ||||
-rw-r--r-- | lib/spack/spack/test/modules/lmod.py | 23 |
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 |