summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/compilers/__init__.py11
-rw-r--r--lib/spack/spack/concretize.py77
-rw-r--r--lib/spack/spack/test/concretize.py10
3 files changed, 77 insertions, 21 deletions
diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py
index 771c8c0559..cb3aab9b97 100644
--- a/lib/spack/spack/compilers/__init__.py
+++ b/lib/spack/spack/compilers/__init__.py
@@ -230,10 +230,15 @@ def compilers_for_spec(compiler_spec, arch_spec=None, scope=None,
matches = set(find(compiler_spec, scope, init_config))
compilers = []
for cspec in matches:
- compilers.extend(get_compilers(cspec, config, arch_spec))
+ compilers.extend(get_compilers(config, cspec, arch_spec))
return compilers
+def compilers_for_arch(arch_spec, scope=None):
+ config = all_compilers_config(scope)
+ return list(get_compilers(config, arch_spec=arch_spec))
+
+
def compiler_from_config_entry(items):
cspec = spack.spec.CompilerSpec(items['spec'])
os = items.get('operating_system', None)
@@ -266,12 +271,12 @@ def compiler_from_config_entry(items):
environment, extra_rpaths, **compiler_flags)
-def get_compilers(cspec, config, arch_spec=None):
+def get_compilers(config, cspec=None, arch_spec=None):
compilers = []
for items in config:
items = items['compiler']
- if items['spec'] != str(cspec):
+ if cspec and items['spec'] != str(cspec):
continue
# If an arch spec is given, confirm that this compiler
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 3d38f22cb6..126db8b780 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -315,11 +315,16 @@ class DefaultConcretizer(object):
def _proper_compiler_style(cspec, aspec):
return spack.compilers.compilers_for_spec(cspec, arch_spec=aspec)
- all_compilers = spack.compilers.all_compiler_specs()
+ all_compiler_specs = spack.compilers.all_compiler_specs()
+ if not all_compiler_specs:
+ raise spack.compilers.NoCompilersError()
if (spec.compiler and
spec.compiler.concrete and
- spec.compiler in all_compilers):
+ spec.compiler in all_compiler_specs):
+ if not _proper_compiler_style(spec.compiler, spec.architecture):
+ _compiler_concretization_failure(
+ spec.compiler, spec.architecture)
return False
# Find the another spec that has a compiler, or the root if none do
@@ -332,22 +337,23 @@ class DefaultConcretizer(object):
assert(other_spec)
# Check if the compiler is already fully specified
- if other_compiler in all_compilers:
+ if other_compiler in all_compiler_specs:
spec.compiler = other_compiler.copy()
+ if not _proper_compiler_style(spec.compiler, spec.architecture):
+ _compiler_concretization_failure(
+ spec.compiler, spec.architecture)
return True
# Filter the compilers into a sorted list based on the compiler_order
# from spackconfig
- compiler_list = all_compilers if not other_compiler else \
+ compiler_list = all_compiler_specs if not other_compiler else \
spack.compilers.find(other_compiler)
+ if not compiler_list:
+ # No compiler with a satisfactory spec was found
+ raise UnavailableCompilerVersionError(other_compiler)
cmp_compilers = partial(
pkgsort().compiler_compare, other_spec.name)
matches = sorted(compiler_list, cmp=cmp_compilers)
- if not matches:
- arch = spec.architecture
- raise UnavailableCompilerVersionError(other_compiler,
- arch.platform_os,
- arch.target)
# copy concrete version into other_compiler
try:
@@ -355,10 +361,9 @@ class DefaultConcretizer(object):
c for c in matches
if _proper_compiler_style(c, spec.architecture)).copy()
except StopIteration:
- raise UnavailableCompilerVersionError(
- spec.compiler, spec.architecture.platform_os,
- spec.architecture.target
- )
+ # No compiler with a satisfactory spec has a suitable arch
+ _compiler_concretization_failure(
+ other_compiler, spec.architecture)
assert(spec.compiler.concrete)
return True # things changed.
@@ -443,17 +448,53 @@ def find_spec(spec, condition):
return None # Nothing matched the condition.
+def _compiler_concretization_failure(compiler_spec, arch):
+ # Distinguish between the case that there are compilers for
+ # the arch but not with the given compiler spec and the case that
+ # there are no compilers for the arch at all
+ if not spack.compilers.compilers_for_arch(arch):
+ available_os_targets = set(
+ (c.operating_system, c.target) for c in
+ spack.compilers.all_compilers())
+ raise NoCompilersForArchError(arch, available_os_targets)
+ else:
+ raise UnavailableCompilerVersionError(compiler_spec, arch)
+
+
+class NoCompilersForArchError(spack.error.SpackError):
+ def __init__(self, arch, available_os_targets):
+ err_msg = ("No compilers found"
+ " for operating system %s and target %s."
+ "\nIf previous installations have succeeded, the"
+ " operating system may have been updated." %
+ (arch.platform_os, arch.target))
+
+ available_os_target_strs = list()
+ for os, t in available_os_targets:
+ os_target_str = "%s-%s" % (os, t) if t else os
+ available_os_target_strs.append(os_target_str)
+ err_msg += (
+ "\nCompilers are defined for the following"
+ " operating systems and targets:\n\t" +
+ "\n\t".join(available_os_target_strs))
+
+ super(NoCompilersForArchError, self).__init__(
+ err_msg, "Run 'spack compiler find' to add compilers.")
+
+
class UnavailableCompilerVersionError(spack.error.SpackError):
"""Raised when there is no available compiler that satisfies a
compiler spec."""
- def __init__(self, compiler_spec, operating_system, target):
+ def __init__(self, compiler_spec, arch=None):
+ err_msg = "No compilers with spec %s found" % compiler_spec
+ if arch:
+ err_msg += (" for operating system %s and target %s." %
+ (compiler_spec, arch.platform_os, arch.target))
+
super(UnavailableCompilerVersionError, self).__init__(
- "No available compiler version matches '%s' on operating_system "
- "'%s' for target '%s'"
- % (compiler_spec, operating_system, target),
- "Run 'spack compilers' to see available compiler Options.")
+ err_msg, "Run 'spack compiler find' to add compilers.")
class NoValidVersionError(spack.error.SpackError):
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 0cb3a34a48..f4021a89ee 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -221,6 +221,16 @@ class TestConcretize(object):
with pytest.raises(spack.spec.MultipleProviderError):
s.concretize()
+ def test_no_matching_compiler_specs(self):
+ s = Spec('a %gcc@0.0.0')
+ with pytest.raises(spack.concretize.UnavailableCompilerVersionError):
+ s.concretize()
+
+ def test_no_compilers_for_arch(self):
+ s = Spec('a arch=linux-rhel0-x86_64')
+ with pytest.raises(spack.concretize.NoCompilersForArchError):
+ s.concretize()
+
def test_virtual_is_fully_expanded_for_callpath(self):
# force dependence on fake "zmpi" by asking for MPI 10.0
spec = Spec('callpath ^mpi@10.0')