summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/spack/spack/concretize.py34
-rw-r--r--lib/spack/spack/test/concretize.py40
2 files changed, 57 insertions, 17 deletions
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 4d1ddf7ac9..c722a5506c 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -222,27 +222,29 @@ class DefaultConcretizer(object):
DAG has an architecture, then use the root otherwise use the defaults
on the platform.
"""
- root_arch = spec.root.architecture
- sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
+ try:
+ # Get the nearest architecture with any fields set
+ nearest = next(p for p in spec.traverse(direction='parents')
+ if (p.architecture and p is not spec))
+ nearest_arch = nearest.architecture
+ except StopIteration:
+ # Default to the system architecture if nothing set
+ nearest_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
+
spec_changed = False
+ # ensure type safety for the architecture
if spec.architecture is None:
- spec.architecture = spack.spec.ArchSpec(sys_arch)
+ spec.architecture = spack.spec.ArchSpec()
spec_changed = True
- default_archs = list(x for x in [root_arch, sys_arch] if x)
- for arch in default_archs:
- if spec.architecture.concrete:
- break
-
- replacement_fields = [k for k, v in iteritems(arch.to_cmp_dict())
- if v and not getattr(spec.architecture, k)]
- for field in replacement_fields:
- setattr(spec.architecture, field, getattr(arch, field))
- spec_changed = True
-
- if not spec.architecture.concrete:
- raise InsufficientArchitectureInfoError(spec, default_archs)
+ # replace each of the fields (platform, os, target) separately
+ nearest_dict = nearest_arch.to_cmp_dict()
+ replacement_fields = [k for k, v in iteritems(nearest_dict)
+ if v and not getattr(spec.architecture, k)]
+ for field in replacement_fields:
+ setattr(spec.architecture, field, getattr(nearest_arch, field))
+ spec_changed = True
return spec_changed
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 7885ca279f..87a4e03b4d 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1,4 +1,4 @@
-##############################################################################
+#############################################################################
# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
# Produced at the Lawrence Livermore National Laboratory.
#
@@ -31,6 +31,7 @@ from spack.concretize import find_spec
from spack.spec import Spec, CompilerSpec
from spack.spec import ConflictsInSpecError, SpecError
from spack.version import ver
+from spack.test.conftest import MockPackage, MockPackageMultiRepo
def check_spec(abstract, concrete):
@@ -204,6 +205,42 @@ class TestConcretize(object):
assert set(client.compiler_flags['fflags']) == set(['-O0'])
assert not set(cmake.compiler_flags['fflags'])
+ def test_architecture_inheritance(self):
+ """test_architecture_inheritance is likely to fail with an
+ UnavailableCompilerVersionError if the architecture is concretized
+ incorrectly.
+ """
+ spec = Spec('cmake-client %gcc@4.7.2 os=fe ^ cmake')
+ spec.concretize()
+ assert spec['cmake'].architecture == spec.architecture
+
+ def test_architecture_deep_inheritance(self):
+ """Make sure that indirect dependencies receive architecture
+ information from the root even when partial architecture information
+ is provided by an intermediate dependency.
+ """
+ saved_repo = spack.repo
+
+ default_dep = ('link', 'build')
+
+ bazpkg = MockPackage('bazpkg', [], [])
+ barpkg = MockPackage('barpkg', [bazpkg], [default_dep])
+ foopkg = MockPackage('foopkg', [barpkg], [default_dep])
+ mock_repo = MockPackageMultiRepo([foopkg, barpkg, bazpkg])
+
+ spack.repo = mock_repo
+
+ try:
+ spec = Spec('foopkg %clang@3.3 os=CNL target=footar' +
+ ' ^barpkg os=SuSE11 ^bazpkg os=be')
+ spec.concretize()
+
+ for s in spec.traverse(root=False):
+ assert s.architecture.target == spec.architecture.target
+
+ finally:
+ spack.repo = saved_repo
+
def test_compiler_flags_from_user_are_grouped(self):
spec = Spec('a%gcc cflags="-O -foo-flag foo-val" platform=test')
spec.concretize()
@@ -216,6 +253,7 @@ class TestConcretize(object):
assert s['mpi'].version == ver('1.10.3')
def test_concretize_two_virtuals(self):
+
"""Test a package with multiple virtual dependencies."""
Spec('hypre').concretize()