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.
This commit is contained in:
parent
2fdfa46735
commit
8ecf5ae2ee
@ -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 @@ def core_compilers(self):
|
||||
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
|
||||
|
||||
|
@ -258,3 +258,26 @@ def test_external_configure_args(
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user