summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/build_environment.py22
-rw-r--r--lib/spack/spack/compilers/__init__.py70
-rw-r--r--lib/spack/spack/environment/environment.py2
-rw-r--r--lib/spack/spack/installer.py6
-rw-r--r--lib/spack/spack/solver/asp.py241
-rw-r--r--lib/spack/spack/solver/concretize.lp5
-rw-r--r--lib/spack/spack/test/cmd/compiler.py12
-rw-r--r--lib/spack/spack/test/compilers/basics.py2
-rw-r--r--lib/spack/spack/test/concretize.py42
-rw-r--r--lib/spack/spack/test/config.py2
-rw-r--r--lib/spack/spack/test/conftest.py1
-rw-r--r--lib/spack/spack/test/data/config/packages.yaml1
-rw-r--r--lib/spack/spack/test/solver/intermediate.py51
-rw-r--r--var/spack/repos/builtin/packages/cray-mpich/package.py15
-rw-r--r--var/spack/repos/builtin/packages/cray-mvapich2/package.py23
-rw-r--r--var/spack/repos/builtin/packages/intel-mpi/package.py16
-rw-r--r--var/spack/repos/builtin/packages/intel-oneapi-mpi/package.py11
-rw-r--r--var/spack/repos/builtin/packages/intel-parallel-studio/package.py16
-rw-r--r--var/spack/repos/builtin/packages/mpich/package.py15
-rw-r--r--var/spack/repos/builtin/packages/mpitrampoline/package.py7
-rw-r--r--var/spack/repos/builtin/packages/mpt/package.py16
-rw-r--r--var/spack/repos/builtin/packages/msmpi/package.py10
-rw-r--r--var/spack/repos/builtin/packages/mvapich/package.py13
-rwxr-xr-xvar/spack/repos/builtin/packages/mvapich2-gdr/package.py13
-rw-r--r--var/spack/repos/builtin/packages/mvapich2/package.py16
-rw-r--r--var/spack/repos/builtin/packages/mvapich2x/package.py12
-rw-r--r--var/spack/repos/builtin/packages/openmpi/package.py11
-rw-r--r--var/spack/repos/builtin/packages/spectrum-mpi/package.py10
28 files changed, 421 insertions, 240 deletions
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 39444f0b52..a567951918 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -57,8 +57,10 @@ import spack.build_systems.cmake
import spack.build_systems.meson
import spack.build_systems.python
import spack.builder
+import spack.compilers
import spack.config
import spack.deptypes as dt
+import spack.error
import spack.main
import spack.package_base
import spack.paths
@@ -583,10 +585,22 @@ def set_package_py_globals(pkg, context: Context = Context.BUILD):
# Put spack compiler paths in module scope. (Some packages use it
# in setup_run_environment etc, so don't put it context == build)
link_dir = spack.paths.build_env_path
- module.spack_cc = os.path.join(link_dir, pkg.compiler.link_paths["cc"])
- module.spack_cxx = os.path.join(link_dir, pkg.compiler.link_paths["cxx"])
- module.spack_f77 = os.path.join(link_dir, pkg.compiler.link_paths["f77"])
- module.spack_fc = os.path.join(link_dir, pkg.compiler.link_paths["fc"])
+ pkg_compiler = None
+ try:
+ pkg_compiler = pkg.compiler
+ except spack.compilers.NoCompilerForSpecError as e:
+ tty.debug(f"cannot set 'spack_cc': {str(e)}")
+
+ if pkg_compiler is not None:
+ module.spack_cc = os.path.join(link_dir, pkg_compiler.link_paths["cc"])
+ module.spack_cxx = os.path.join(link_dir, pkg_compiler.link_paths["cxx"])
+ module.spack_f77 = os.path.join(link_dir, pkg_compiler.link_paths["f77"])
+ module.spack_fc = os.path.join(link_dir, pkg_compiler.link_paths["fc"])
+ else:
+ module.spack_cc = None
+ module.spack_cxx = None
+ module.spack_f77 = None
+ module.spack_fc = None
# Useful directories within the prefix are encapsulated in
# a Prefix object.
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index 17010f8667..ed3244da2e 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -109,27 +109,33 @@ def _to_dict(compiler):
return {"compiler": d}
-def get_compiler_config(scope=None, init_config=False):
+def get_compiler_config(
+ configuration: "spack.config.Configuration",
+ *,
+ scope: Optional[str] = None,
+ init_config: bool = False,
+) -> List[Dict]:
"""Return the compiler configuration for the specified architecture."""
-
- config = spack.config.CONFIG.get("compilers", scope=scope) or []
+ config = configuration.get("compilers", scope=scope) or []
if config or not init_config:
return config
- merged_config = spack.config.CONFIG.get("compilers")
+ merged_config = configuration.get("compilers")
if merged_config:
# Config is empty for this scope
# Do not init config because there is a non-empty scope
return config
- _init_compiler_config(scope=scope)
- config = spack.config.CONFIG.get("compilers", scope=scope)
+ _init_compiler_config(configuration, scope=scope)
+ config = configuration.get("compilers", scope=scope)
return config
-def get_compiler_config_from_packages(scope=None):
+def get_compiler_config_from_packages(
+ configuration: "spack.config.Configuration", *, scope: Optional[str] = None
+) -> List[Dict]:
"""Return the compiler configuration from packages.yaml"""
- config = spack.config.get("packages", scope=scope)
+ config = configuration.get("packages", scope=scope)
if not config:
return []
@@ -216,13 +222,15 @@ def _compiler_config_from_external(config):
return compiler_entry
-def _init_compiler_config(*, scope):
+def _init_compiler_config(
+ configuration: "spack.config.Configuration", *, scope: Optional[str]
+) -> None:
"""Compiler search used when Spack has no compilers."""
compilers = find_compilers()
compilers_dict = []
for compiler in compilers:
compilers_dict.append(_to_dict(compiler))
- spack.config.set("compilers", compilers_dict, scope=scope)
+ configuration.set("compilers", compilers_dict, scope=scope)
def compiler_config_files():
@@ -233,7 +241,7 @@ def compiler_config_files():
compiler_config = config.get("compilers", scope=name)
if compiler_config:
config_files.append(config.get_config_filename(name, "compilers"))
- compiler_config_from_packages = get_compiler_config_from_packages(scope=name)
+ compiler_config_from_packages = get_compiler_config_from_packages(config, scope=name)
if compiler_config_from_packages:
config_files.append(config.get_config_filename(name, "packages"))
return config_files
@@ -246,7 +254,9 @@ def add_compilers_to_config(compilers, scope=None):
compilers: a list of Compiler objects.
scope: configuration scope to modify.
"""
- compiler_config = get_compiler_config(scope, init_config=False)
+ compiler_config = get_compiler_config(
+ configuration=spack.config.CONFIG, scope=scope, init_config=False
+ )
for compiler in compilers:
if not compiler.cc:
tty.debug(f"{compiler.spec} does not have a C compiler")
@@ -295,7 +305,9 @@ def _remove_compiler_from_scope(compiler_spec, scope):
True if one or more compiler entries were actually removed, False otherwise
"""
assert scope is not None, "a specific scope is needed when calling this function"
- compiler_config = get_compiler_config(scope, init_config=False)
+ compiler_config = get_compiler_config(
+ configuration=spack.config.CONFIG, scope=scope, init_config=False
+ )
filtered_compiler_config = [
compiler_entry
for compiler_entry in compiler_config
@@ -310,18 +322,23 @@ def _remove_compiler_from_scope(compiler_spec, scope):
# We need to preserve the YAML type for comments, hence we are copying the
# items in the list that has just been retrieved
compiler_config[:] = filtered_compiler_config
- spack.config.set("compilers", compiler_config, scope=scope)
+ spack.config.CONFIG.set("compilers", compiler_config, scope=scope)
return True
-def all_compilers_config(scope=None, init_config=True):
+def all_compilers_config(
+ configuration: "spack.config.Configuration",
+ *,
+ scope: Optional[str] = None,
+ init_config: bool = True,
+) -> List["spack.compiler.Compiler"]:
"""Return a set of specs for all the compiler versions currently
available to build with. These are instances of CompilerSpec.
"""
- from_packages_yaml = get_compiler_config_from_packages(scope)
+ from_packages_yaml = get_compiler_config_from_packages(configuration, scope=scope)
if from_packages_yaml:
init_config = False
- from_compilers_yaml = get_compiler_config(scope, init_config)
+ from_compilers_yaml = get_compiler_config(configuration, scope=scope, init_config=init_config)
result = from_compilers_yaml + from_packages_yaml
key = lambda c: _compiler_from_config_entry(c["compiler"])
@@ -332,7 +349,7 @@ def all_compiler_specs(scope=None, init_config=True):
# Return compiler specs from the merged config.
return [
spack.spec.parse_with_version_concrete(s["compiler"]["spec"], compiler=True)
- for s in all_compilers_config(scope, init_config)
+ for s in all_compilers_config(spack.config.CONFIG, scope=scope, init_config=init_config)
]
@@ -492,9 +509,16 @@ def find_specs_by_arch(compiler_spec, arch_spec, scope=None, init_config=True):
def all_compilers(scope=None, init_config=True):
- config = all_compilers_config(scope, init_config=init_config)
- compilers = list()
- for items in config:
+ return all_compilers_from(
+ configuration=spack.config.CONFIG, scope=scope, init_config=init_config
+ )
+
+
+def all_compilers_from(configuration, scope=None, init_config=True):
+ compilers = []
+ for items in all_compilers_config(
+ configuration=configuration, scope=scope, init_config=init_config
+ ):
items = items["compiler"]
compilers.append(_compiler_from_config_entry(items))
return compilers
@@ -507,7 +531,7 @@ def compilers_for_spec(
"""This gets all compilers that satisfy the supplied CompilerSpec.
Returns an empty list if none are found.
"""
- config = all_compilers_config(scope, init_config)
+ config = all_compilers_config(spack.config.CONFIG, scope=scope, init_config=init_config)
matches = set(find(compiler_spec, scope, init_config))
compilers = []
@@ -517,7 +541,7 @@ def compilers_for_spec(
def compilers_for_arch(arch_spec, scope=None):
- config = all_compilers_config(scope)
+ config = all_compilers_config(spack.config.CONFIG, scope=scope)
return list(get_compilers(config, arch_spec=arch_spec))
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index ed59b5cdf1..da241417d6 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -1427,7 +1427,7 @@ class Environment:
# Ensure we have compilers in compilers.yaml to avoid that
# processes try to write the config file in parallel
- _ = spack.compilers.get_compiler_config(init_config=True)
+ _ = spack.compilers.get_compiler_config(spack.config.CONFIG, init_config=True)
# Early return if there is nothing to do
if len(args) == 0:
diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py
index 2d20674617..ee67c07fd3 100644
--- a/lib/spack/spack/installer.py
+++ b/lib/spack/spack/installer.py
@@ -976,7 +976,11 @@ class BuildTask:
# a dependency of the build task. Here we add it to self.dependencies
compiler_spec = self.pkg.spec.compiler
arch_spec = self.pkg.spec.architecture
- if not spack.compilers.compilers_for_spec(compiler_spec, arch_spec=arch_spec):
+ strict = spack.concretize.Concretizer().check_for_compiler_existence
+ if (
+ not spack.compilers.compilers_for_spec(compiler_spec, arch_spec=arch_spec)
+ and not strict
+ ):
# The compiler is in the queue, identify it as dependency
dep = spack.compilers.pkg_spec_for_compiler(compiler_spec)
dep.constrain(f"platform={str(arch_spec.platform)}")
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 3c55941a56..c7acbafaf4 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -267,8 +267,8 @@ def _create_counter(specs: List[spack.spec.Spec], tests: bool):
return NoDuplicatesCounter(specs, tests=tests)
-def all_compilers_in_config():
- return spack.compilers.all_compilers()
+def all_compilers_in_config(configuration):
+ return spack.compilers.all_compilers_from(configuration)
def extend_flag_list(flag_list, new_flags):
@@ -688,8 +688,9 @@ class ErrorHandler:
raise UnsatisfiableSpecError(msg)
-#: Data class to collect information on a requirement
class RequirementRule(NamedTuple):
+ """Data class to collect information on a requirement"""
+
pkg_name: str
policy: str
requirements: List["spack.spec.Spec"]
@@ -698,6 +699,27 @@ class RequirementRule(NamedTuple):
message: Optional[str]
+class KnownCompiler(NamedTuple):
+ """Data class to collect information on compilers"""
+
+ spec: "spack.spec.Spec"
+ os: str
+ target: str
+ available: bool
+ compiler_obj: Optional["spack.compiler.Compiler"]
+
+ def _key(self):
+ return self.spec, self.os, self.target
+
+ def __eq__(self, other: object):
+ if not isinstance(other, KnownCompiler):
+ return NotImplemented
+ return self._key() == other._key()
+
+ def __hash__(self):
+ return hash(self._key())
+
+
class PyclingoDriver:
def __init__(self, cores=True):
"""Driver for the Python clingo interface.
@@ -1065,36 +1087,28 @@ class SpackSolverSetup:
"""Facts about available compilers."""
self.gen.h2("Available compilers")
- indexed_possible_compilers = list(enumerate(self.possible_compilers))
- for compiler_id, compiler in indexed_possible_compilers:
+ for compiler_id, compiler in enumerate(self.possible_compilers):
self.gen.fact(fn.compiler_id(compiler_id))
self.gen.fact(fn.compiler_name(compiler_id, compiler.spec.name))
self.gen.fact(fn.compiler_version(compiler_id, compiler.spec.version))
- if compiler.operating_system:
- self.gen.fact(fn.compiler_os(compiler_id, compiler.operating_system))
-
- if compiler.target == "any":
- compiler.target = None
+ if compiler.os:
+ self.gen.fact(fn.compiler_os(compiler_id, compiler.os))
if compiler.target is not None:
self.gen.fact(fn.compiler_target(compiler_id, compiler.target))
- for flag_type, flags in compiler.flags.items():
- for flag in flags:
- self.gen.fact(fn.compiler_flag(compiler_id, flag_type, flag))
-
- self.gen.newline()
-
- # Set compiler defaults, given a list of possible compilers
- self.gen.h2("Default compiler preferences (CompilerID, Weight)")
+ if compiler.compiler_obj is not None:
+ c = compiler.compiler_obj
+ for flag_type, flags in c.flags.items():
+ for flag in flags:
+ self.gen.fact(fn.compiler_flag(compiler_id, flag_type, flag))
- ppk = spack.package_prefs.PackagePrefs("all", "compiler", all=False)
- matches = sorted(indexed_possible_compilers, key=lambda x: ppk(x[1].spec))
+ if compiler.available:
+ self.gen.fact(fn.compiler_available(compiler_id))
- for weight, (compiler_id, cspec) in enumerate(matches):
- f = fn.compiler_weight(compiler_id, weight)
- self.gen.fact(f)
+ self.gen.fact(fn.compiler_weight(compiler_id, compiler_id))
+ self.gen.newline()
def package_requirement_rules(self, pkg):
parser = RequirementParser(spack.config.CONFIG)
@@ -1624,23 +1638,6 @@ class SpackSolverSetup:
for i, preferred in enumerate(package_targets):
self.gen.fact(fn.target_weight(str(preferred.architecture.target), i))
- def flag_defaults(self):
- self.gen.h2("Compiler flag defaults")
-
- # types of flags that can be on specs
- for flag in spack.spec.FlagMap.valid_compiler_flags():
- self.gen.fact(fn.flag_type(flag))
- self.gen.newline()
-
- # flags from compilers.yaml
- compilers = all_compilers_in_config()
- for compiler in compilers:
- for name, flags in compiler.flags.items():
- for flag in flags:
- self.gen.fact(
- fn.compiler_version_flag(compiler.name, compiler.version, name, flag)
- )
-
def spec_clauses(
self,
spec: spack.spec.Spec,
@@ -2046,9 +2043,16 @@ class SpackSolverSetup:
candidate_targets.append(ancestor)
best_targets = {uarch.family.name}
- for compiler_id, compiler in enumerate(self.possible_compilers):
+ for compiler_id, known_compiler in enumerate(self.possible_compilers):
+ if not known_compiler.available:
+ continue
+
+ compiler = known_compiler.compiler_obj
# Stub support for cross-compilation, to be expanded later
- if compiler.target is not None and compiler.target != str(uarch.family):
+ if known_compiler.target is not None and compiler.target not in (
+ str(uarch.family),
+ "any",
+ ):
self.gen.fact(fn.compiler_supports_target(compiler_id, compiler.target))
self.gen.newline()
continue
@@ -2104,58 +2108,6 @@ class SpackSolverSetup:
self.gen.fact(fn.virtual(vspec))
self.gen.newline()
- def generate_possible_compilers(self, specs):
- compilers = all_compilers_in_config()
-
- # Search for compilers which differs only by aspects that are
- # not selectable by users using the spec syntax
- seen, sanitized_list = set(), []
- for compiler in compilers:
- key = compiler.spec, compiler.operating_system, compiler.target
- if key in seen:
- warnings.warn(
- f"duplicate found for {compiler.spec} on "
- f"{compiler.operating_system}/{compiler.target}. "
- f"Edit your compilers.yaml configuration to remove it."
- )
- continue
- sanitized_list.append(compiler)
- seen.add(key)
-
- cspecs = set([c.spec for c in compilers])
-
- # add compiler specs from the input line to possibilities if we
- # don't require compilers to exist.
- strict = spack.concretize.Concretizer().check_for_compiler_existence
- for s in traverse.traverse_nodes(specs):
- # we don't need to validate compilers for already-built specs
- if s.concrete or not s.compiler:
- continue
-
- version = s.compiler.versions.concrete
-
- if not version or any(c.satisfies(s.compiler) for c in cspecs):
- continue
-
- # Error when a compiler is not found and strict mode is enabled
- if strict:
- raise spack.concretize.UnavailableCompilerVersionError(s.compiler)
-
- # Make up a compiler matching the input spec. This is for bootstrapping.
- compiler_cls = spack.compilers.class_for_compiler_name(s.compiler.name)
- compilers.append(
- compiler_cls(s.compiler, operating_system=None, target=None, paths=[None] * 4)
- )
- self.gen.fact(fn.allow_compiler(s.compiler.name, version))
-
- return list(
- sorted(
- compilers,
- key=lambda compiler: (compiler.spec.name, compiler.spec.version),
- reverse=True,
- )
- )
-
def define_version_constraints(self):
"""Define what version_satisfies(...) means in ASP logic."""
for pkg_name, versions in sorted(self.version_constraints):
@@ -2331,6 +2283,8 @@ class SpackSolverSetup:
self.explicitly_required_namespaces[node.name] = node.namespace
self.gen = ProblemInstanceBuilder()
+ compiler_parser = CompilerParser(configuration=spack.config.CONFIG).with_input_specs(specs)
+
if not allow_deprecated:
self.gen.fact(fn.deprecated_versions_not_allowed())
@@ -2349,17 +2303,17 @@ class SpackSolverSetup:
)
specs = tuple(specs) # ensure compatible types to add
- # get possible compilers
- self.possible_compilers = self.generate_possible_compilers(specs)
-
self.gen.h1("Reusable concrete specs")
self.define_concrete_input_specs(specs, self.pkgs)
if reuse:
self.gen.fact(fn.optimize_for_reuse())
for reusable_spec in reuse:
+ compiler_parser.add_compiler_from_concrete_spec(reusable_spec)
self.register_concrete_spec(reusable_spec, self.pkgs)
self.concrete_specs()
+ self.possible_compilers = compiler_parser.possible_compilers()
+
self.gen.h1("Generic statements on possible packages")
node_counter.possible_packages_facts(self.gen, fn)
@@ -2460,9 +2414,12 @@ class SpackSolverSetup:
def define_runtime_constraints(self):
"""Define the constraints to be imposed on the runtimes"""
recorder = RuntimePropertyRecorder(self)
+ # TODO: Use only available compilers ?
for compiler in self.possible_compilers:
compiler_with_different_cls_names = {"oneapi": "intel-oneapi-compilers"}
- compiler_cls_name = compiler_with_different_cls_names.get(compiler.name, compiler.name)
+ compiler_cls_name = compiler_with_different_cls_names.get(
+ compiler.spec.name, compiler.spec.name
+ )
try:
compiler_cls = spack.repo.PATH.get_pkg_class(compiler_cls_name)
except spack.repo.UnknownPackageError:
@@ -2840,6 +2797,90 @@ class RequirementParser:
return False
+class CompilerParser:
+ """Parses configuration files, and builds a list of possible compilers for the solve."""
+
+ def __init__(self, configuration) -> None:
+ self.compilers: Set[KnownCompiler] = set()
+ for c in all_compilers_in_config(configuration):
+ target = c.target if c.target != "any" else None
+ candidate = KnownCompiler(
+ spec=c.spec, os=c.operating_system, target=target, available=True, compiler_obj=c
+ )
+ if candidate in self.compilers:
+ warnings.warn(
+ f"duplicate found for {c.spec} on {c.operating_system}/{c.target}. "
+ f"Edit your compilers.yaml configuration to remove it."
+ )
+ continue
+
+ self.compilers.add(candidate)
+
+ def with_input_specs(self, input_specs: List["spack.spec.Spec"]) -> "CompilerParser":
+ """Accounts for input specs when building the list of possible compilers.
+
+ Args:
+ input_specs: specs to be concretized
+ """
+ strict = spack.concretize.Concretizer().check_for_compiler_existence
+ default_os = str(spack.platforms.host().default_os)
+ default_target = str(archspec.cpu.host().family)
+ for s in traverse.traverse_nodes(input_specs):
+ # we don't need to validate compilers for already-built specs
+ if s.concrete or not s.compiler:
+ continue
+
+ version = s.compiler.versions.concrete
+
+ if not version or any(item.spec.satisfies(s.compiler) for item in self.compilers):
+ continue
+
+ # Error when a compiler is not found and strict mode is enabled
+ if strict:
+ raise spack.concretize.UnavailableCompilerVersionError(s.compiler)
+
+ # Make up a compiler matching the input spec. This is for bootstrapping.
+ compiler_cls = spack.compilers.class_for_compiler_name(s.compiler.name)
+ compiler_obj = compiler_cls(
+ s.compiler, operating_system=default_os, target=default_target, paths=[None] * 4
+ )
+ self.compilers.add(
+ KnownCompiler(
+ spec=s.compiler,
+ os=default_os,
+ target=default_target,
+ available=True,
+ compiler_obj=compiler_obj,
+ )
+ )
+
+ return self
+
+ def add_compiler_from_concrete_spec(self, spec: "spack.spec.Spec") -> None:
+ """Account for compilers that are coming from concrete specs, through reuse.
+
+ Args:
+ spec: concrete spec to be reused
+ """
+ assert spec.concrete, "the spec argument must be concrete"
+ candidate = KnownCompiler(
+ spec=spec.compiler,
+ os=str(spec.architecture.os),
+ target=str(spec.architecture.target.microarchitecture.family),
+ available=False,
+ compiler_obj=None,
+ )
+ self.compilers.add(candidate)
+
+ def possible_compilers(self) -> List[KnownCompiler]:
+ # Here we have to sort two times, first sort by name and ascending version
+ result = sorted(self.compilers, key=lambda x: (x.spec.name, x.spec.version), reverse=True)
+ # Then stable sort to prefer available compilers and account for preferences
+ ppk = spack.package_prefs.PackagePrefs("all", "compiler", all=False)
+ result.sort(key=lambda x: (not x.available, ppk(x.spec)))
+ return result
+
+
class RuntimePropertyRecorder:
"""An object of this class is injected in callbacks to compilers, to let them declare
properties of the runtimes they support and of the runtimes they provide, and to add
@@ -3179,7 +3220,9 @@ class SpecBuilder:
imposes order afterwards.
"""
# reverse compilers so we get highest priority compilers that share a spec
- compilers = dict((c.spec, c) for c in reversed(all_compilers_in_config()))
+ compilers = dict(
+ (c.spec, c) for c in reversed(all_compilers_in_config(spack.config.CONFIG))
+ )
cmd_specs = dict((s.name, s) for spec in self._command_line_specs for s in spec.traverse())
for spec in self._specs.values():
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index 1c6709602d..4a2edaa067 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -1110,7 +1110,7 @@ error(100, "'{0} target={1}' is not compatible with this machine", Package, Targ
% Compiler semantics
%-----------------------------------------------------------------------------
% There must be only one compiler set per built node.
-{ node_compiler(PackageNode, CompilerID) : compiler_id(CompilerID) } :-
+{ node_compiler(PackageNode, CompilerID) : compiler_id(CompilerID), compiler_available(CompilerID) } :-
attr("node", PackageNode),
build(PackageNode).
@@ -1127,6 +1127,7 @@ attr("node_compiler_version", PackageNode, CompilerName, CompilerVersion)
:- node_compiler(PackageNode, CompilerID),
compiler_name(CompilerID, CompilerName),
compiler_version(CompilerID, CompilerVersion),
+ compiler_available(CompilerID),
build(PackageNode).
attr("node_compiler", PackageNode, CompilerName)
@@ -1189,7 +1190,6 @@ error(100, "{0} compiler '%{1}@{2}' incompatible with 'os={3}'", Package, Compil
compiler_version(CompilerID, Version),
compiler_os(CompilerID, CompilerOS),
not os_compatible(CompilerOS, OS),
- not allow_compiler(Compiler, Version),
build(node(X, Package)).
% If a package and one of its dependencies don't have the
@@ -1210,7 +1210,6 @@ compiler_mismatch_required(PackageNode, DependencyNode)
not compiler_match(PackageNode, DependencyNode).
#defined compiler_os/3.
-#defined allow_compiler/2.
% compilers weighted by preference according to packages.yaml
node_compiler_weight(node(ID, Package), Weight)
diff --git a/lib/spack/spack/test/cmd/compiler.py b/lib/spack/spack/test/cmd/compiler.py
index 46613b41fb..150fd1af54 100644
--- a/lib/spack/spack/test/cmd/compiler.py
+++ b/lib/spack/spack/test/cmd/compiler.py
@@ -175,7 +175,9 @@ def test_compiler_find_mixed_suffixes(
assert "clang@11.0.0" in output
assert "gcc@8.4.0" in output
- config = spack.compilers.get_compiler_config("site", False)
+ config = spack.compilers.get_compiler_config(
+ no_compilers_yaml, scope="site", init_config=False
+ )
clang = next(c["compiler"] for c in config if c["compiler"]["spec"] == "clang@=11.0.0")
gcc = next(c["compiler"] for c in config if c["compiler"]["spec"] == "gcc@=8.4.0")
@@ -210,7 +212,9 @@ def test_compiler_find_prefer_no_suffix(no_compilers_yaml, working_env, compiler
assert "clang@11.0.0" in output
assert "gcc@8.4.0" in output
- config = spack.compilers.get_compiler_config("site", False)
+ config = spack.compilers.get_compiler_config(
+ no_compilers_yaml, scope="site", init_config=False
+ )
clang = next(c["compiler"] for c in config if c["compiler"]["spec"] == "clang@=11.0.0")
assert clang["paths"]["cc"] == str(compilers_dir / "clang")
@@ -229,7 +233,9 @@ def test_compiler_find_path_order(no_compilers_yaml, working_env, compilers_dir)
compiler("find", "--scope=site")
- config = spack.compilers.get_compiler_config("site", False)
+ config = spack.compilers.get_compiler_config(
+ no_compilers_yaml, scope="site", init_config=False
+ )
gcc = next(c["compiler"] for c in config if c["compiler"]["spec"] == "gcc@=8.4.0")
assert gcc["paths"] == {
"cc": str(new_dir / "gcc-8"),
diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py
index 879257fcb2..2d99b53466 100644
--- a/lib/spack/spack/test/compilers/basics.py
+++ b/lib/spack/spack/test/compilers/basics.py
@@ -700,7 +700,7 @@ def test_raising_if_compiler_target_is_over_specific(config):
]
arch_spec = spack.spec.ArchSpec(("linux", "ubuntu18.04", "haswell"))
with spack.config.override("compilers", compilers):
- cfg = spack.compilers.get_compiler_config()
+ cfg = spack.compilers.get_compiler_config(config)
with pytest.raises(ValueError):
spack.compilers.get_compilers(cfg, spack.spec.CompilerSpec("gcc@9.0.1"), arch_spec)
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 81d4f3190f..d7df2d6bc8 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -120,14 +120,16 @@ def current_host(request, monkeypatch):
# is_preference is not empty if we want to supply the
# preferred target via packages.yaml
cpu, _, is_preference = request.param.partition("-")
- target = archspec.cpu.TARGETS[cpu]
monkeypatch.setattr(spack.platforms.Test, "default", cpu)
monkeypatch.setattr(spack.platforms.Test, "front_end", cpu)
if not is_preference:
+ target = archspec.cpu.TARGETS[cpu]
monkeypatch.setattr(archspec.cpu, "host", lambda: target)
yield target
else:
+ target = archspec.cpu.TARGETS["sapphirerapids"]
+ monkeypatch.setattr(archspec.cpu, "host", lambda: target)
with spack.config.override("packages:all", {"target": [cpu]}):
yield target
@@ -874,7 +876,7 @@ class TestConcretize:
@pytest.mark.parametrize(
"spec_str,expected_str",
[
- # Unconstrained versions select default compiler (gcc@4.5.0)
+ # Unconstrained versions select default compiler (gcc@10.2.1)
("bowtie@1.4.0", "%gcc@10.2.1"),
# Version with conflicts and no valid gcc select another compiler
("bowtie@1.3.0", "%clang@15.0.0"),
@@ -1012,7 +1014,7 @@ class TestConcretize:
[("cmake", ["%clang"]), ("cmake %gcc", ["%gcc"]), ("cmake %clang", ["%clang"])],
)
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
- def test_external_package_and_compiler_preferences(self, spec_str, expected):
+ def test_external_package_and_compiler_preferences(self, spec_str, expected, mutable_config):
packages_yaml = {
"all": {"compiler": ["clang", "gcc"]},
"cmake": {
@@ -1020,7 +1022,7 @@ class TestConcretize:
"buildable": False,
},
}
- spack.config.set("packages", packages_yaml)
+ mutable_config.set("packages", packages_yaml)
s = Spec(spec_str).concretized()
assert s.external
@@ -1877,19 +1879,16 @@ class TestConcretize:
@pytest.mark.regression("31169")
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
- def test_not_reusing_incompatible_os_or_compiler(self):
+ def test_not_reusing_incompatible_os(self):
root_spec = Spec("b")
s = root_spec.concretized()
- wrong_compiler, wrong_os = s.copy(), s.copy()
- wrong_compiler.compiler = spack.spec.CompilerSpec("gcc@12.1.0")
+ wrong_os = s.copy()
wrong_os.architecture = spack.spec.ArchSpec("test-ubuntu2204-x86_64")
- reusable_specs = [wrong_compiler, wrong_os]
with spack.config.override("concretizer:reuse", True):
solver = spack.solver.asp.Solver()
setup = spack.solver.asp.SpackSolverSetup()
- result, _, _ = solver.driver.solve(setup, [root_spec], reuse=reusable_specs)
+ result, _, _ = solver.driver.solve(setup, [root_spec], reuse=[wrong_os])
concrete_spec = result.specs[0]
- assert concrete_spec.satisfies("%{}".format(s.compiler))
assert concrete_spec.satisfies("os={}".format(s.architecture.os))
@pytest.mark.only_clingo("Use case not supported by the original concretizer")
@@ -2360,6 +2359,29 @@ class TestConcretize:
assert s[name].concrete
assert s[name].namespace == namespace
+ @pytest.mark.only_clingo("Old concretizer cannot reuse")
+ def test_reuse_specs_from_non_available_compilers(self, mutable_config, mutable_database):
+ """Tests that we can reuse specs with compilers that are not configured locally."""
+ # All the specs in the mutable DB have been compiled with %gcc@=10.2.1
+ specs = mutable_database.query_local()
+ assert all(s.satisfies("%gcc@=10.2.1") for s in specs)
+
+ spack.compilers.remove_compiler_from_config("gcc@=10.2.1")
+ assert not spack.compilers.compilers_for_spec("gcc@=10.2.1")
+ mutable_config.set("concretizer:reuse", True)
+
+ # mpileaks is in the database, it will be reused with gcc@=10.2.1
+ root = Spec("mpileaks").concretized()
+ for s in root.traverse():
+ assert s.satisfies("%gcc@10.2.1")
+
+ # fftw is not in the database, therefore the root will be compiled with gcc@=9.4.0,
+ # while the mpi is reused from the database and is compiled with gcc@=10.2.1
+ root = Spec("fftw").concretized()
+ assert root.satisfies("%gcc@=9.4.0")
+ for s in root.traverse(root=False):
+ assert s.satisfies("%gcc@10.2.1")
+
@pytest.fixture()
def duplicates_test_repository():
diff --git a/lib/spack/spack/test/config.py b/lib/spack/spack/test/config.py
index 83a652cd41..76052eeb38 100644
--- a/lib/spack/spack/test/config.py
+++ b/lib/spack/spack/test/config.py
@@ -977,7 +977,7 @@ def test_single_file_scope(config, env_yaml):
# from the single-file config
assert spack.config.get("config:verify_ssl") is False
assert spack.config.get("config:dirty") is False
- assert spack.config.get("packages:all:compiler") == ["gcc@4.5.3"]
+ assert spack.config.get("packages:all:compiler") == ["gcc@4.5.3", "gcc", "clang"]
# from the lower config scopes
assert spack.config.get("config:checksum") is True
diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py
index 7a38d4ccba..543cfb4b2f 100644
--- a/lib/spack/spack/test/conftest.py
+++ b/lib/spack/spack/test/conftest.py
@@ -790,6 +790,7 @@ def no_compilers_yaml(mutable_config):
compilers_yaml = os.path.join(local_config.path, "compilers.yaml")
if os.path.exists(compilers_yaml):
os.remove(compilers_yaml)
+ return mutable_config
@pytest.fixture()
diff --git a/lib/spack/spack/test/data/config/packages.yaml b/lib/spack/spack/test/data/config/packages.yaml
index 3d5cac7664..25fbe888c5 100644
--- a/lib/spack/spack/test/data/config/packages.yaml
+++ b/lib/spack/spack/test/data/config/packages.yaml
@@ -1,5 +1,6 @@
packages:
all:
+ compiler: [gcc, clang]
providers:
mpi: [openmpi, mpich, zmpi]
lapack: [openblas-with-lapack]
diff --git a/lib/spack/spack/test/solver/intermediate.py b/lib/spack/spack/test/solver/intermediate.py
new file mode 100644
index 0000000000..42fdb316aa
--- /dev/null
+++ b/lib/spack/spack/test/solver/intermediate.py
@@ -0,0 +1,51 @@
+# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+"""Unit tests for objects turning configuration into an intermediate format used by the solver."""
+import pytest
+
+import spack.compilers
+import spack.config
+import spack.spec
+from spack.concretize import UnavailableCompilerVersionError
+from spack.solver import asp
+
+
+class TestCompilerParser:
+ def test_expected_order_mock_config(self, config):
+ """Tests the expected preference order in the mock compiler configuration"""
+ parser = asp.CompilerParser(config)
+ expected_order = ["gcc@=10.2.1", "gcc@=9.4.0", "gcc@=9.4.0", "clang@=15.0.0"]
+ for c, expected in zip(parser.possible_compilers(), expected_order):
+ assert c.spec.satisfies(expected)
+
+ @pytest.mark.parametrize("spec_str", ["a %gcc@=13.2.0", "a ^b %gcc@=13.2.0"])
+ def test_compiler_from_input_raise(self, spec_str, config):
+ """Tests that having an unknown compiler in the input spec raises an exception, if we
+ don't allow bootstrapping missing compilers.
+ """
+ spec = spack.spec.Spec(spec_str)
+ with pytest.raises(UnavailableCompilerVersionError):
+ asp.CompilerParser(config).with_input_specs([spec])
+
+ def test_compilers_inferred_from_concrete_specs(self, mutable_config, mutable_database):
+ """Test that compilers inferred from concrete specs, that are not in the local
+ configuration too, are last in the preference order.
+ """
+ spack.compilers.remove_compiler_from_config("gcc@=10.2.1")
+ assert not spack.compilers.compilers_for_spec("gcc@=10.2.1")
+
+ parser = asp.CompilerParser(mutable_config)
+ for reuse_spec in mutable_database.query():
+ parser.add_compiler_from_concrete_spec(reuse_spec)
+
+ expected_order = [
+ ("gcc@=9.4.0", True),
+ ("gcc@=9.4.0", True),
+ ("clang@=15.0.0", True),
+ ("gcc@=10.2.1", False),
+ ]
+ for c, (expected, available) in zip(parser.possible_compilers(), expected_order):
+ assert c.spec.satisfies(expected)
+ assert c.available is available
diff --git a/var/spack/repos/builtin/packages/cray-mpich/package.py b/var/spack/repos/builtin/packages/cray-mpich/package.py
index fb7405f443..4b422bf38e 100644
--- a/var/spack/repos/builtin/packages/cray-mpich/package.py
+++ b/var/spack/repos/builtin/packages/cray-mpich/package.py
@@ -70,18 +70,19 @@ class CrayMpich(Package):
env.set("MPICXX", join_path(self.prefix.bin, "mpicxx"))
env.set("MPIF77", join_path(self.prefix.bin, "mpif77"))
env.set("MPIF90", join_path(self.prefix.bin, "mpif90"))
- else:
+ elif spack_cc is not None:
env.set("MPICC", spack_cc)
env.set("MPICXX", spack_cxx)
env.set("MPIF77", spack_fc)
env.set("MPIF90", spack_fc)
def setup_dependent_build_environment(self, env, dependent_spec):
- env.set("MPICH_CC", spack_cc)
- env.set("MPICH_CXX", spack_cxx)
- env.set("MPICH_F77", spack_f77)
- env.set("MPICH_F90", spack_fc)
- env.set("MPICH_FC", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("MPICH_CC", dependent_module.spack_cc)
+ env.set("MPICH_CXX", dependent_module.spack_cxx)
+ env.set("MPICH_F77", dependent_module.spack_f77)
+ env.set("MPICH_F90", dependent_module.spack_fc)
+ env.set("MPICH_FC", dependent_module.spack_fc)
def setup_dependent_package(self, module, dependent_spec):
spec = self.spec
@@ -90,7 +91,7 @@ class CrayMpich(Package):
spec.mpicxx = join_path(self.prefix.bin, "mpicxx")
spec.mpifc = join_path(self.prefix.bin, "mpif90")
spec.mpif77 = join_path(self.prefix.bin, "mpif77")
- else:
+ elif spack_cc is not None:
spec.mpicc = spack_cc
spec.mpicxx = spack_cxx
spec.mpifc = spack_fc
diff --git a/var/spack/repos/builtin/packages/cray-mvapich2/package.py b/var/spack/repos/builtin/packages/cray-mvapich2/package.py
index 88615093d2..b76d583c2b 100644
--- a/var/spack/repos/builtin/packages/cray-mvapich2/package.py
+++ b/var/spack/repos/builtin/packages/cray-mvapich2/package.py
@@ -27,24 +27,29 @@ class CrayMvapich2(Package):
provides("mpi@3")
def setup_run_environment(self, env):
+ if spack_cc is None:
+ return
+
env.set("MPICC", spack_cc)
env.set("MPICXX", spack_cxx)
env.set("MPIF77", spack_fc)
env.set("MPIF90", spack_fc)
def setup_dependent_build_environment(self, env, dependent_spec):
- env.set("MPICH_CC", spack_cc)
- env.set("MPICH_CXX", spack_cxx)
- env.set("MPICH_F77", spack_f77)
- env.set("MPICH_F90", spack_fc)
- env.set("MPICH_FC", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("MPICH_CC", dependent_module.spack_cc)
+ env.set("MPICH_CXX", dependent_module.spack_cxx)
+ env.set("MPICH_F77", dependent_module.spack_f77)
+ env.set("MPICH_F90", dependent_module.spack_fc)
+ env.set("MPICH_FC", dependent_module.spack_fc)
def setup_dependent_package(self, module, dependent_spec):
spec = self.spec
- spec.mpicc = spack_cc
- spec.mpicxx = spack_cxx
- spec.mpifc = spack_fc
- spec.mpif77 = spack_f77
+ dependent_module = dependent_spec.package.module
+ spec.mpicc = dependent_module.spack_cc
+ spec.mpicxx = dependent_module.spack_cxx
+ spec.mpifc = dependent_module.spack_fc
+ spec.mpif77 = dependent_module.spack_f77
spec.mpicxx_shared_libs = [
join_path(self.prefix.lib, "libmpicxx.{0}".format(dso_suffix)),
diff --git a/var/spack/repos/builtin/packages/intel-mpi/package.py b/var/spack/repos/builtin/packages/intel-mpi/package.py
index aa1ae55752..3e8ce47e9d 100644
--- a/var/spack/repos/builtin/packages/intel-mpi/package.py
+++ b/var/spack/repos/builtin/packages/intel-mpi/package.py
@@ -150,19 +150,21 @@ class IntelMpi(IntelPackage):
depends_on("libfabric", when="+external-libfabric", type=("build", "link", "run"))
depends_on("cpio", type="build")
- def setup_dependent_build_environment(self, *args):
+ def setup_dependent_build_environment(self, env, dependent_spec):
# Handle in callback, conveying client's compilers in additional arg.
# CAUTION - DUP code in:
# ../intel-mpi/package.py
# ../intel-parallel-studio/package.py
+ dependent_module = dependent_spec.package.module
self._setup_dependent_env_callback(
- *args,
+ env,
+ dependent_spec,
compilers_of_client={
- "CC": spack_cc,
- "CXX": spack_cxx,
- "F77": spack_f77,
- "F90": spack_fc,
- "FC": spack_fc,
+ "CC": dependent_module.spack_cc,
+ "CXX": dependent_module.spack_cxx,
+ "F77": dependent_module.spack_f77,
+ "F90": dependent_module.spack_fc,
+ "FC": dependent_module.spack_fc,
},
)
diff --git a/var/spack/repos/builtin/packages/intel-oneapi-mpi/package.py b/var/spack/repos/builtin/packages/intel-oneapi-mpi/package.py
index 973f6cb295..388f6cb742 100644
--- a/var/spack/repos/builtin/packages/intel-oneapi-mpi/package.py
+++ b/var/spack/repos/builtin/packages/intel-oneapi-mpi/package.py
@@ -151,11 +151,12 @@ class IntelOneapiMpi(IntelOneApiLibraryPackage):
self.spec.mpifc = join_path(self.component_prefix.bin, "mpiifort")
def setup_dependent_build_environment(self, env, dependent_spec):
- env.set("I_MPI_CC", spack_cc)
- env.set("I_MPI_CXX", spack_cxx)
- env.set("I_MPI_F77", spack_f77)
- env.set("I_MPI_F90", spack_fc)
- env.set("I_MPI_FC", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("I_MPI_CC", dependent_module.spack_cc)
+ env.set("I_MPI_CXX", dependent_module.spack_cxx)
+ env.set("I_MPI_F77", dependent_module.spack_f77)
+ env.set("I_MPI_F90", dependent_module.spack_fc)
+ env.set("I_MPI_FC", dependent_module.spack_fc)
# Set compiler wrappers for dependent build stage
if "+generic-names" in self.spec:
diff --git a/var/spack/repos/builtin/packages/intel-parallel-studio/package.py b/var/spack/repos/builtin/packages/intel-parallel-studio/package.py
index b6ab4e405e..5a64a75820 100644
--- a/var/spack/repos/builtin/packages/intel-parallel-studio/package.py
+++ b/var/spack/repos/builtin/packages/intel-parallel-studio/package.py
@@ -666,19 +666,21 @@ class IntelParallelStudio(IntelPackage):
msg="SSE3 is not supported on MacOS x86_64",
)
- def setup_dependent_build_environment(self, *args):
+ def setup_dependent_build_environment(self, env, dependent_spec):
# Handle in callback, conveying client's compilers in additional arg.
# CAUTION - DUP code in:
# ../intel-mpi/package.py
# ../intel-parallel-studio/package.py
+ dependent_module = dependent_spec.package.module
self._setup_dependent_env_callback(
- *args,
+ env,
+ dependent_spec,
compilers_of_client={
- "CC": spack_cc,
- "CXX": spack_cxx,
- "F77": spack_f77,
- "F90": spack_fc,
- "FC": spack_fc,
+ "CC": dependent_module.spack_cc,
+ "CXX": dependent_module.spack_cxx,
+ "F77": dependent_module.spack_f77,
+ "F90": dependent_module.spack_fc,
+ "FC": dependent_module.spack_fc,
},
)
diff --git a/var/spack/repos/builtin/packages/mpich/package.py b/var/spack/repos/builtin/packages/mpich/package.py
index 1143074eaf..b624bfe866 100644
--- a/var/spack/repos/builtin/packages/mpich/package.py
+++ b/var/spack/repos/builtin/packages/mpich/package.py
@@ -442,7 +442,7 @@ supported, and netmod is ignored if device is ch3:sock.""",
# their run environments the code to make the compilers available.
# For Cray MPIs, the regular compiler wrappers *are* the MPI wrappers.
# Cray MPIs always have cray in the module name, e.g. "cray-mpich"
- if self.spec.satisfies("platform=cray"):
+ if self.spec.satisfies("platform=cray") and spack_cc is not None:
# This is intended to support external MPICH instances registered
# by Spack on Cray machines prior to a879c87; users defining an
# external MPICH entry for Cray should generally refer to the
@@ -458,18 +458,19 @@ supported, and netmod is ignored if device is ch3:sock.""",
env.set("MPIF90", join_path(self.prefix.bin, "mpif90"))
def setup_dependent_build_environment(self, env, dependent_spec):
- env.set("MPICH_CC", spack_cc)
- env.set("MPICH_CXX", spack_cxx)
- env.set("MPICH_F77", spack_f77)
- env.set("MPICH_F90", spack_fc)
- env.set("MPICH_FC", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("MPICH_CC", dependent_module.spack_cc)
+ env.set("MPICH_CXX", dependent_module.spack_cxx)
+ env.set("MPICH_F77", dependent_module.spack_f77)
+ env.set("MPICH_F90", dependent_module.spack_fc)
+ env.set("MPICH_FC", dependent_module.spack_fc)
def setup_dependent_package(self, module, dependent_spec):
spec = self.spec
# For Cray MPIs, the regular compiler wrappers *are* the MPI wrappers.
# Cray MPIs always have cray in the module name, e.g. "cray-mpich"
- if self.spec.satisfies("platform=cray"):
+ if self.spec.satisfies("platform=cray") and spack_cc is not None:
spec.mpicc = spack_cc
spec.mpicxx = spack_cxx
spec.mpifc = spack_fc
diff --git a/var/spack/repos/builtin/packages/mpitrampoline/package.py b/var/spack/repos/builtin/packages/mpitrampoline/package.py
index 39fa57564d..f6e440ebd4 100644
--- a/var/spack/repos/builtin/packages/mpitrampoline/package.py
+++ b/var/spack/repos/builtin/packages/mpitrampoline/package.py
@@ -90,10 +90,11 @@ class Mpitrampoline(CMakePackage):
env.set("MPIF90", join_path(self.prefix.bin, "mpifc"))
def setup_dependent_build_environment(self, env, dependent_spec):
+ dependent_module = dependent_spec.package.module
# Use the Spack compiler wrappers under MPI
- env.set("MPITRAMPOLINE_CC", spack_cc)
- env.set("MPITRAMPOLINE_CXX", spack_cxx)
- env.set("MPITRAMPOLINE_FC", spack_fc)
+ env.set("MPITRAMPOLINE_CC", dependent_module.spack_cc)
+ env.set("MPITRAMPOLINE_CXX", dependent_module.spack_cxx)
+ env.set("MPITRAMPOLINE_FC", dependent_module.spack_fc)
fflags = []
if (
self.spec.satisfies("%apple-clang")
diff --git a/var/spack/repos/builtin/packages/mpt/package.py b/var/spack/repos/builtin/packages/mpt/package.py
index 7a1a01e482..e9a6c6f18c 100644
--- a/var/spack/repos/builtin/packages/mpt/package.py
+++ b/var/spack/repos/builtin/packages/mpt/package.py
@@ -36,9 +36,10 @@ class Mpt(BundlePackage):
def setup_dependent_build_environment(self, env, dependent_spec):
# use the Spack compiler wrappers under MPI
- env.set("MPICC_CC", spack_cc)
- env.set("MPICXX_CXX", spack_cxx)
- env.set("MPIF90_F90", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("MPICC_CC", dependent_module.spack_cc)
+ env.set("MPICXX_CXX", dependent_module.spack_cxx)
+ env.set("MPIF90_F90", dependent_module.spack_fc)
def setup_run_environment(self, env):
# Because MPI is both runtime and compiler, we have to setup the mpi
@@ -50,10 +51,11 @@ class Mpt(BundlePackage):
def setup_dependent_package(self, module, dependent_spec):
if "platform=cray" in self.spec:
- self.spec.mpicc = spack_cc
- self.spec.mpicxx = spack_cxx
- self.spec.mpifc = spack_fc
- self.spec.mpif77 = spack_f77
+ dependent_module = dependent_spec.package.module
+ self.spec.mpicc = dependent_module.spack_cc
+ self.spec.mpicxx = dependent_module.spack_cxx
+ self.spec.mpifc = dependent_module.spack_fc
+ self.spec.mpif77 = dependent_module.spack_f77
else:
self.spec.mpicc = self.prefix.bin.mpicc
self.spec.mpicxx = self.prefix.bin.mpicxx
diff --git a/var/spack/repos/builtin/packages/msmpi/package.py b/var/spack/repos/builtin/packages/msmpi/package.py
index 5d05dd2c25..738e2e0550 100644
--- a/var/spack/repos/builtin/packages/msmpi/package.py
+++ b/var/spack/repos/builtin/packages/msmpi/package.py
@@ -41,14 +41,14 @@ class Msmpi(Package):
return Version(ver_str.group(1)) if ver_str else None
def setup_dependent_package(self, module, dependent_spec):
- spec = self.spec
# MSMPI does not vendor compiler wrappers, instead arguments should
# be manually supplied to compiler by consuming package
# Note: This is not typical of MPI installations
- spec.mpicc = spack_cc
- spec.mpicxx = spack_cxx
- spec.mpifc = spack_fc
- spec.mpif77 = spack_f77
+ dependent_module = dependent_spec.package.module
+ self.spec.mpicc = dependent_module.spack_cc
+ self.spec.mpicxx = dependent_module.spack_cxx
+ self.spec.mpifc = dependent_module.spack_fc
+ self.spec.mpif77 = dependent_module.spack_f77
class GenericBuilder(GenericBuilder):
diff --git a/var/spack/repos/builtin/packages/mvapich/package.py b/var/spack/repos/builtin/packages/mvapich/package.py
index d2b429d3c1..bdb66c763d 100644
--- a/var/spack/repos/builtin/packages/mvapich/package.py
+++ b/var/spack/repos/builtin/packages/mvapich/package.py
@@ -215,16 +215,17 @@ class Mvapich(AutotoolsPackage):
self.setup_compiler_environment(env)
# use the Spack compiler wrappers under MPI
- env.set("MPICH_CC", spack_cc)
- env.set("MPICH_CXX", spack_cxx)
- env.set("MPICH_F77", spack_f77)
- env.set("MPICH_F90", spack_fc)
- env.set("MPICH_FC", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("MPICH_CC", dependent_module.spack_cc)
+ env.set("MPICH_CXX", dependent_module.spack_cxx)
+ env.set("MPICH_F77", dependent_module.spack_f77)
+ env.set("MPICH_F90", dependent_module.spack_fc)
+ env.set("MPICH_FC", dependent_module.spack_fc)
def setup_compiler_environment(self, env):
# For Cray MPIs, the regular compiler wrappers *are* the MPI wrappers.
# Cray MPIs always have cray in the module name, e.g. "cray-mvapich"
- if self.spec.satisfies("platform=cray"):
+ if self.spec.satisfies("platform=cray") and spack_cc is not None:
env.set("MPICC", spack_cc)
env.set("MPICXX", spack_cxx)
env.set("MPIF77", spack_fc)
diff --git a/var/spack/repos/builtin/packages/mvapich2-gdr/package.py b/var/spack/repos/builtin/packages/mvapich2-gdr/package.py
index a284f6ffa0..ae9ad23d02 100755
--- a/var/spack/repos/builtin/packages/mvapich2-gdr/package.py
+++ b/var/spack/repos/builtin/packages/mvapich2-gdr/package.py
@@ -166,13 +166,12 @@ class Mvapich2Gdr(AutotoolsPackage):
def setup_dependent_build_environment(self, env, dependent_spec):
self.setup_compiler_environment(env)
-
- # use the Spack compiler wrappers under MPI
- env.set("MPICH_CC", spack_cc)
- env.set("MPICH_CXX", spack_cxx)
- env.set("MPICH_F77", spack_f77)
- env.set("MPICH_F90", spack_fc)
- env.set("MPICH_FC", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("MPICH_CC", dependent_module.spack_cc)
+ env.set("MPICH_CXX", dependent_module.spack_cxx)
+ env.set("MPICH_F77", dependent_module.spack_f77)
+ env.set("MPICH_F90", dependent_module.spack_fc)
+ env.set("MPICH_FC", dependent_module.spack_fc)
def setup_compiler_environment(self, env):
env.set("MPICC", join_path(self.prefix.bin, "mpicc"))
diff --git a/var/spack/repos/builtin/packages/mvapich2/package.py b/var/spack/repos/builtin/packages/mvapich2/package.py
index 7e9204ffbd..9ab54c3eaa 100644
--- a/var/spack/repos/builtin/packages/mvapich2/package.py
+++ b/var/spack/repos/builtin/packages/mvapich2/package.py
@@ -375,18 +375,18 @@ class Mvapich2(AutotoolsPackage):
def setup_dependent_build_environment(self, env, dependent_spec):
self.setup_compiler_environment(env)
-
# use the Spack compiler wrappers under MPI
- env.set("MPICH_CC", spack_cc)
- env.set("MPICH_CXX", spack_cxx)
- env.set("MPICH_F77", spack_f77)
- env.set("MPICH_F90", spack_fc)
- env.set("MPICH_FC", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("MPICH_CC", dependent_module.spack_cc)
+ env.set("MPICH_CXX", dependent_module.spack_cxx)
+ env.set("MPICH_F77", dependent_module.spack_f77)
+ env.set("MPICH_F90", dependent_module.spack_fc)
+ env.set("MPICH_FC", dependent_module.spack_fc)
def setup_compiler_environment(self, env):
# For Cray MPIs, the regular compiler wrappers *are* the MPI wrappers.
# Cray MPIs always have cray in the module name, e.g. "cray-mvapich"
- if self.spec.satisfies("platform=cray"):
+ if self.spec.satisfies("platform=cray") and spack_cc is not None:
env.set("MPICC", spack_cc)
env.set("MPICXX", spack_cxx)
env.set("MPIF77", spack_fc)
@@ -400,7 +400,7 @@ class Mvapich2(AutotoolsPackage):
def setup_dependent_package(self, module, dependent_spec):
# For Cray MPIs, the regular compiler wrappers *are* the MPI wrappers.
# Cray MPIs always have cray in the module name, e.g. "cray-mvapich"
- if self.spec.satisfies("platform=cray"):
+ if self.spec.satisfies("platform=cray") and spack_cc is not None:
self.spec.mpicc = spack_cc
self.spec.mpicxx = spack_cxx
self.spec.mpifc = spack_fc
diff --git a/var/spack/repos/builtin/packages/mvapich2x/package.py b/var/spack/repos/builtin/packages/mvapich2x/package.py
index b817f3cd34..5962ef6968 100644
--- a/var/spack/repos/builtin/packages/mvapich2x/package.py
+++ b/var/spack/repos/builtin/packages/mvapich2x/package.py
@@ -218,13 +218,13 @@ class Mvapich2x(AutotoolsPackage):
def setup_dependent_build_environment(self, env, dependent_spec):
self.setup_compiler_environment(env)
-
# use the Spack compiler wrappers under MPI
- env.set("MPICH_CC", spack_cc)
- env.set("MPICH_CXX", spack_cxx)
- env.set("MPICH_F77", spack_f77)
- env.set("MPICH_F90", spack_fc)
- env.set("MPICH_FC", spack_fc)
+ dependent_module = dependent_spec.package.module
+ env.set("MPICH_CC", dependent_module.spack_cc)
+ env.set("MPICH_CXX", dependent_module.spack_cxx)
+ env.set("MPICH_F77", dependent_module.spack_f77)
+ env.set("MPICH_F90", dependent_module.spack_fc)
+ env.set("MPICH_FC", dependent_module.spack_fc)
def setup_compiler_environment(self, env):
# For Cray MPIs, the regular compiler wrappers *are* the MPI wrappers.
diff --git a/var/spack/repos/builtin/packages/openmpi/package.py b/var/spack/repos/builtin/packages/openmpi/package.py
index a995a271b4..abbf212857 100644
--- a/var/spack/repos/builtin/packages/openmpi/package.py
+++ b/var/spack/repos/builtin/packages/openmpi/package.py
@@ -845,10 +845,11 @@ class Openmpi(AutotoolsPackage, CudaPackage):
def setup_dependent_build_environment(self, env, dependent_spec):
# Use the spack compiler wrappers under MPI
- env.set("OMPI_CC", spack_cc)
- env.set("OMPI_CXX", spack_cxx)
- env.set("OMPI_FC", spack_fc)
- env.set("OMPI_F77", spack_f77)
+ dependent_module = dependent_spec.package.module
+ env.set("OMPI_CC", dependent_module.spack_cc)
+ env.set("OMPI_CXX", dependent_module.spack_cxx)
+ env.set("OMPI_FC", dependent_module.spack_fc)
+ env.set("OMPI_F77", dependent_module.spack_f77)
# See https://www.open-mpi.org/faq/?category=building#installdirs
for suffix in [
@@ -870,7 +871,7 @@ class Openmpi(AutotoolsPackage, CudaPackage):
"PKGLIBDIR",
"PKGINCLUDEDIR",
]:
- env.unset("OPAL_%s" % suffix)
+ env.unset(f"OPAL_{suffix}")
def setup_dependent_package(self, module, dependent_spec):
self.spec.mpicc = join_path(self.prefix.bin, "mpicc")
diff --git a/var/spack/repos/builtin/packages/spectrum-mpi/package.py b/var/spack/repos/builtin/packages/spectrum-mpi/package.py
index ca7a55e599..eeb878b876 100644
--- a/var/spack/repos/builtin/packages/spectrum-mpi/package.py
+++ b/var/spack/repos/builtin/packages/spectrum-mpi/package.py
@@ -136,11 +136,11 @@ class SpectrumMpi(BundlePackage):
env.set("MPIF77", os.path.join(self.prefix.bin, "mpif77"))
env.set("MPIF90", os.path.join(self.prefix.bin, "mpif90"))
- env.set("OMPI_CC", spack_cc)
- env.set("OMPI_CXX", spack_cxx)
- env.set("OMPI_FC", spack_fc)
- env.set("OMPI_F77", spack_f77)
-
+ dependent_module = dependent_spec.package.module
+ env.set("OMPI_CC", dependent_module.spack_cc)
+ env.set("OMPI_CXX", dependent_module.spack_cxx)
+ env.set("OMPI_FC", dependent_module.spack_fc)
+ env.set("OMPI_F77", dependent_module.spack_f77)
env.prepend_path("LD_LIBRARY_PATH", self.prefix.lib)
def setup_run_environment(self, env):