(WIP) Fix LMod module generation
Signed-off-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
This commit is contained in:
parent
6674ce6dc4
commit
a1866d7a4b
@ -5,6 +5,7 @@
|
|||||||
import collections
|
import collections
|
||||||
import itertools
|
import itertools
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
from typing import Dict, List, Optional, Tuple
|
from typing import Dict, List, Optional, Tuple
|
||||||
|
|
||||||
import llnl.util.filesystem as fs
|
import llnl.util.filesystem as fs
|
||||||
@ -58,7 +59,7 @@ def make_context(
|
|||||||
return LmodContext(make_configuration(spec, module_set_name, explicit))
|
return LmodContext(make_configuration(spec, module_set_name, explicit))
|
||||||
|
|
||||||
|
|
||||||
def guess_core_compilers(name, store=False) -> List[spack.spec.CompilerSpec]:
|
def guess_core_compilers(name, store=False) -> List[spack.spec.Spec]:
|
||||||
"""Guesses the list of core compilers installed in the system.
|
"""Guesses the list of core compilers installed in the system.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -71,14 +72,10 @@ def guess_core_compilers(name, store=False) -> List[spack.spec.CompilerSpec]:
|
|||||||
core_compilers = []
|
core_compilers = []
|
||||||
for compiler in spack.compilers.config.all_compilers():
|
for compiler in spack.compilers.config.all_compilers():
|
||||||
try:
|
try:
|
||||||
# A compiler is considered to be a core compiler if any of the
|
cc_dir = pathlib.Path(compiler.package.cc).parent
|
||||||
# C, C++ or Fortran compilers reside in a system directory
|
is_system_compiler = str(cc_dir) in spack.util.environment.SYSTEM_DIRS
|
||||||
is_system_compiler = any(
|
|
||||||
os.path.dirname(getattr(compiler, x, "")) in spack.util.environment.SYSTEM_DIRS
|
|
||||||
for x in ("cc", "cxx", "f77", "fc")
|
|
||||||
)
|
|
||||||
if is_system_compiler:
|
if is_system_compiler:
|
||||||
core_compilers.append(compiler.spec)
|
core_compilers.append(compiler)
|
||||||
except (KeyError, TypeError, AttributeError):
|
except (KeyError, TypeError, AttributeError):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -100,18 +97,32 @@ class LmodConfiguration(BaseConfiguration):
|
|||||||
|
|
||||||
default_projections = {"all": "{name}/{version}"}
|
default_projections = {"all": "{name}/{version}"}
|
||||||
|
|
||||||
|
def __init__(self, spec: spack.spec.Spec, module_set_name: str, explicit: bool) -> None:
|
||||||
|
super().__init__(spec, module_set_name, explicit)
|
||||||
|
|
||||||
|
# FIXME (compiler as nodes): make this a bit more robust
|
||||||
|
candidates = collections.defaultdict(list)
|
||||||
|
for node in spec.traverse(deptype=("link", "run")):
|
||||||
|
candidates["c"].extend(node.dependencies(virtuals="c"))
|
||||||
|
candidates["cxx"].extend(node.dependencies(virtuals="c"))
|
||||||
|
|
||||||
|
# FIXME (compiler as nodes): decide what to do when we have more than one C compiler
|
||||||
|
if candidates["c"] and len(set(candidates["c"])) == 1:
|
||||||
|
self.compiler = candidates["c"][0]
|
||||||
|
elif not candidates["c"]:
|
||||||
|
self.compiler = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def core_compilers(self) -> List[spack.spec.CompilerSpec]:
|
def core_compilers(self) -> List[spack.spec.Spec]:
|
||||||
"""Returns the list of "Core" compilers
|
"""Returns the list of "Core" compilers
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
CoreCompilersNotFoundError: if the key was not
|
CoreCompilersNotFoundError: if the key was not specified in the configuration file or
|
||||||
specified in the configuration file or the sequence
|
the sequence is empty
|
||||||
is empty
|
|
||||||
"""
|
"""
|
||||||
compilers = [
|
compilers = []
|
||||||
spack.spec.CompilerSpec(c) for c in configuration(self.name).get("core_compilers", [])
|
for c in configuration(self.name).get("core_compilers", []):
|
||||||
]
|
compilers.extend(spack.spec.Spec(f"%{c}").dependencies())
|
||||||
|
|
||||||
if not compilers:
|
if not compilers:
|
||||||
compilers = guess_core_compilers(self.name, store=True)
|
compilers = guess_core_compilers(self.name, store=True)
|
||||||
@ -160,12 +171,15 @@ def hierarchy_tokens(self):
|
|||||||
@property
|
@property
|
||||||
@lang.memoized
|
@lang.memoized
|
||||||
def requires(self):
|
def requires(self):
|
||||||
"""Returns a dictionary mapping all the requirements of this spec
|
"""Returns a dictionary mapping all the requirements of this spec to the actual provider.
|
||||||
to the actual provider. 'compiler' is always present among the
|
|
||||||
requirements.
|
The 'compiler' key is always present among the requirements.
|
||||||
"""
|
"""
|
||||||
# If it's a core_spec, lie and say it requires a core compiler
|
# If it's a core_spec, lie and say it requires a core compiler
|
||||||
if any(self.spec.satisfies(core_spec) for core_spec in self.core_specs):
|
if (
|
||||||
|
any(self.spec.satisfies(core_spec) for core_spec in self.core_specs)
|
||||||
|
or self.compiler is None
|
||||||
|
):
|
||||||
return {"compiler": self.core_compilers[0]}
|
return {"compiler": self.core_compilers[0]}
|
||||||
|
|
||||||
hierarchy_filter_list = []
|
hierarchy_filter_list = []
|
||||||
@ -176,7 +190,8 @@ def requires(self):
|
|||||||
|
|
||||||
# Keep track of the requirements that this package has in terms
|
# Keep track of the requirements that this package has in terms
|
||||||
# of virtual packages that participate in the hierarchical structure
|
# of virtual packages that participate in the hierarchical structure
|
||||||
requirements = {"compiler": self.spec.compiler}
|
|
||||||
|
requirements = {"compiler": self.compiler}
|
||||||
# For each virtual dependency in the hierarchy
|
# For each virtual dependency in the hierarchy
|
||||||
for x in self.hierarchy_tokens:
|
for x in self.hierarchy_tokens:
|
||||||
# Skip anything filtered for this spec
|
# Skip anything filtered for this spec
|
||||||
@ -200,11 +215,11 @@ def provides(self):
|
|||||||
|
|
||||||
# If it is in the list of supported compilers family -> compiler
|
# If it is in the list of supported compilers family -> compiler
|
||||||
if self.spec.name in spack.compilers.config.supported_compilers():
|
if self.spec.name in spack.compilers.config.supported_compilers():
|
||||||
provides["compiler"] = spack.spec.CompilerSpec(self.spec.format("{name}{@versions}"))
|
provides["compiler"] = spack.spec.Spec(self.spec.format("{name}{@versions}"))
|
||||||
elif self.spec.name in spack.compilers.config.package_name_to_compiler_name:
|
elif self.spec.name in spack.compilers.config.package_name_to_compiler_name:
|
||||||
# If it is the package for a supported compiler, but of a different name
|
# If it is the package for a supported compiler, but of a different name
|
||||||
cname = spack.compilers.config.package_name_to_compiler_name[self.spec.name]
|
cname = spack.compilers.config.package_name_to_compiler_name[self.spec.name]
|
||||||
provides["compiler"] = spack.spec.CompilerSpec(cname, self.spec.versions)
|
provides["compiler"] = spack.spec.Spec(cname, self.spec.versions)
|
||||||
|
|
||||||
# All the other tokens in the hierarchy must be virtual dependencies
|
# All the other tokens in the hierarchy must be virtual dependencies
|
||||||
for x in self.hierarchy_tokens:
|
for x in self.hierarchy_tokens:
|
||||||
@ -300,12 +315,10 @@ def path_part_fmt(token):
|
|||||||
|
|
||||||
# If we are dealing with a core compiler, return 'Core'
|
# If we are dealing with a core compiler, return 'Core'
|
||||||
core_compilers = self.conf.core_compilers
|
core_compilers = self.conf.core_compilers
|
||||||
if name == "compiler" and any(
|
if name == "compiler" and any(spack.spec.Spec(value).satisfies(c) for c in core_compilers):
|
||||||
spack.spec.CompilerSpec(value).satisfies(c) for c in core_compilers
|
|
||||||
):
|
|
||||||
return "Core"
|
return "Core"
|
||||||
|
|
||||||
# CompilerSpec does not have a hash, as we are not allowed to
|
# Spec does not have a hash, as we are not allowed to
|
||||||
# use different flavors of the same compiler
|
# use different flavors of the same compiler
|
||||||
if name == "compiler":
|
if name == "compiler":
|
||||||
return path_part_fmt(token=value)
|
return path_part_fmt(token=value)
|
||||||
|
Loading…
Reference in New Issue
Block a user