summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/architecture.py5
-rw-r--r--lib/spack/spack/concretize.py56
-rw-r--r--lib/spack/spack/operating_systems/cnl.py2
-rw-r--r--lib/spack/spack/spec.py23
-rw-r--r--lib/spack/spack/test/concretize.py30
5 files changed, 91 insertions, 25 deletions
diff --git a/lib/spack/spack/architecture.py b/lib/spack/spack/architecture.py
index 6ea7bafb6a..a77832fcb1 100644
--- a/lib/spack/spack/architecture.py
+++ b/lib/spack/spack/architecture.py
@@ -513,3 +513,8 @@ def sys_type():
"""
arch = Arch(platform(), 'default_os', 'default_target')
return str(arch)
+
+
+@memoized
+def frontend_sys_type():
+ return str(Arch(platform(), 'frontend', 'frontend'))
diff --git a/lib/spack/spack/concretize.py b/lib/spack/spack/concretize.py
index 1bc933e543..51d3c777fc 100644
--- a/lib/spack/spack/concretize.py
+++ b/lib/spack/spack/concretize.py
@@ -251,8 +251,12 @@ 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())
+ root_arch = spec.link_root().architecture
+ if spec.build_dep() and spec.disjoint_build_tree():
+ sys_arch = spack.spec.ArchSpec(
+ spack.architecture.frontend_sys_type())
+ else:
+ sys_arch = spack.spec.ArchSpec(spack.architecture.sys_type())
spec_changed = False
if spec.architecture is None:
@@ -321,14 +325,21 @@ class DefaultConcretizer(object):
spec.compiler in all_compilers):
return False
- # Find the another spec that has a compiler, or the root if none do
- other_spec = spec if spec.compiler else find_spec(
- spec, lambda x: x.compiler)
+ if spec.compiler:
+ other_spec = spec
+ elif spec.build_dep() and spec.disjoint_build_tree():
+ link_root = spec.link_root()
+ build_subtree = list(link_root.traverse(direction='children'))
+ candidates = list(x for x in build_subtree if x.compiler)
+ other_spec = candidates[0] if candidates else link_root
+ else:
+ # Find another spec that has a compiler, or the root if none do.
+ # Prefer compiler info from other specs which are not build deps.
+ other_spec = (
+ find_spec(spec, lambda x: x.compiler and not x.build_dep()) or
+ spec.root)
- if not other_spec:
- other_spec = spec.root
other_compiler = other_spec.compiler
- assert(other_spec)
# Check if the compiler is already fully specified
if other_compiler in all_compilers:
@@ -372,16 +383,20 @@ class DefaultConcretizer(object):
# changes
return True
+ def compiler_match(spec1, spec2):
+ return ((spec1.compiler, spec1.architecture) ==
+ (spec2.compiler, spec2.architecture))
+
ret = False
for flag in spack.spec.FlagMap.valid_compiler_flags():
try:
nearest = next(p for p in spec.traverse(direction='parents')
- if ((p.compiler == spec.compiler and
- p is not spec) and
+ if ((p is not spec) and
+ compiler_match(p, spec) and
flag in p.compiler_flags))
- if flag not in spec.compiler_flags or \
- not (sorted(spec.compiler_flags[flag]) >=
- sorted(nearest.compiler_flags[flag])):
+ if (flag not in spec.compiler_flags or
+ (set(nearest.compiler_flags[flag]) -
+ set(spec.compiler_flags[flag]))):
if flag in spec.compiler_flags:
spec.compiler_flags[flag] = list(
set(spec.compiler_flags[flag]) |
@@ -392,10 +407,11 @@ class DefaultConcretizer(object):
ret = True
except StopIteration:
- if (flag in spec.root.compiler_flags and
- ((flag not in spec.compiler_flags) or
- sorted(spec.compiler_flags[flag]) !=
- sorted(spec.root.compiler_flags[flag]))):
+ if (compiler_match(spec.root, spec) and
+ flag in spec.root.compiler_flags and
+ ((flag not in spec.compiler_flags) or
+ (set(spec.root.compiler_flags[flag]) -
+ set(spec.compiler_flags[flag])))):
if flag in spec.compiler_flags:
spec.compiler_flags[flag] = list(
set(spec.compiler_flags[flag]) |
@@ -419,10 +435,8 @@ class DefaultConcretizer(object):
if compiler.flags[flag] != []:
ret = True
else:
- if ((sorted(spec.compiler_flags[flag]) !=
- sorted(compiler.flags[flag])) and
- (not set(spec.compiler_flags[flag]) >=
- set(compiler.flags[flag]))):
+ if (set(compiler.flags[flag]) -
+ set(spec.compiler_flags[flag])):
ret = True
spec.compiler_flags[flag] = list(
set(spec.compiler_flags[flag]) |
diff --git a/lib/spack/spack/operating_systems/cnl.py b/lib/spack/spack/operating_systems/cnl.py
index 78807865b3..fa5394ce66 100644
--- a/lib/spack/spack/operating_systems/cnl.py
+++ b/lib/spack/spack/operating_systems/cnl.py
@@ -22,7 +22,7 @@ class Cnl(OperatingSystem):
super(Cnl, self).__init__(name, version)
def __str__(self):
- return self.name
+ return self.name + self.version
def find_compilers(self, *paths):
types = spack.compilers.all_compiler_types()
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 2ef3757689..aba0466076 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -1090,7 +1090,7 @@ class Spec(object):
successors = deps
if direction == 'parents':
- successors = self.dependents_dict() # TODO: deptype?
+ successors = self.dependents_dict(deptype)
visited.add(key)
for name in sorted(successors):
@@ -1308,6 +1308,23 @@ class Spec(object):
except Exception as e:
raise sjson.SpackJSONError("error parsing JSON spec:", str(e))
+ def build_dep(self):
+ # If this spec is the root, it will automatically be included in
+ # traverse
+ return not (self.root in
+ self.traverse(
+ deptype=('link', 'run'), direction='parents'))
+
+ def link_root(self):
+ parents = list(self.traverse(deptype=('link',), direction='parents',
+ order='pre'))
+ return parents[-1]
+
+ def disjoint_build_tree(self):
+ link_root = self.link_root()
+ build_subtree = list(link_root.traverse(direction='children'))
+ return all(x.build_dep() for x in build_subtree)
+
def _concretize_helper(self, presets=None, visited=None):
"""Recursive helper function for concretize().
This concretizes everything bottom-up. As things are
@@ -1326,8 +1343,8 @@ class Spec(object):
# Concretize deps first -- this is a bottom-up process.
for name in sorted(self._dependencies.keys()):
- changed |= self._dependencies[
- name].spec._concretize_helper(presets, visited)
+ dep = self._dependencies[name]
+ changed |= dep.spec._concretize_helper(presets, visited)
if self.name in presets:
changed |= self.constrain(presets[self.name])
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 154e0eb68e..4e2354a17a 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -85,6 +85,36 @@ class ConcretizeTest(MockPackagesTest):
self.check_concretize('mpich debug=2')
self.check_concretize('mpich')
+ def test_concretize_with_build_dep(self):
+ # Set the target as the backend. Since the cmake build dependency is
+ # not explicitly configured to target the backend it should target
+ # the frontend (whatever compiler that is, it is different)
+ spec = self.check_concretize('cmake-client platform=test target=be')
+ client_compiler = spack.compilers.compiler_for_spec(
+ spec.compiler, spec.architecture)
+ cmake_spec = spec['cmake']
+ cmake_compiler = spack.compilers.compiler_for_spec(
+ cmake_spec.compiler, cmake_spec.architecture)
+ self.assertTrue(client_compiler.operating_system !=
+ cmake_compiler.operating_system)
+
+ def test_concretize_link_dep_of_build_dep(self):
+ # The link dep of the build dep should use the same compiler as
+ # the build dep, and both should be different from the root
+ spec = self.check_concretize('dttop platform=test target=be')
+ dttop_compiler = spack.compilers.compiler_for_spec(
+ spec.compiler, spec.architecture)
+ dtlink2_spec = spec['dtlink2']
+ dtlink2_compiler = spack.compilers.compiler_for_spec(
+ dtlink2_spec.compiler, dtlink2_spec.architecture)
+ dtbuild1_spec = spec['dtbuild1']
+ dtbuild1_compiler = spack.compilers.compiler_for_spec(
+ dtbuild1_spec.compiler, dtbuild1_spec.architecture)
+ self.assertTrue(dttop_compiler.operating_system !=
+ dtlink2_compiler.operating_system)
+ self.assertTrue(dtbuild1_compiler.operating_system ==
+ dtlink2_compiler.operating_system)
+
def test_conretize_compiler_flags(self):
self.check_concretize('mpich cppflags="-O3"')