summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDennis Klein <dennis.klein.github@gmail.com>2020-07-24 19:00:55 +0200
committerGitHub <noreply@github.com>2020-07-24 10:00:55 -0700
commit0c63c94103acae33c4f3adfe7b90d2ea1165ce46 (patch)
treef28438ba77c501e524c501a51af5353c53a8e3e2 /lib
parent99c46e818629b18f06ac0bc3cde5aa4f7c5c897f (diff)
downloadspack-0c63c94103acae33c4f3adfe7b90d2ea1165ce46.tar.gz
spack-0c63c94103acae33c4f3adfe7b90d2ea1165ce46.tar.bz2
spack-0c63c94103acae33c4f3adfe7b90d2ea1165ce46.tar.xz
spack-0c63c94103acae33c4f3adfe7b90d2ea1165ce46.zip
Relax architecture compatibility check (#15972)
* Relax architecture compatibility check * Add test coverage for the spack.abi module
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/abi.py19
-rw-r--r--lib/spack/spack/test/abi.py66
2 files changed, 77 insertions, 8 deletions
diff --git a/lib/spack/spack/abi.py b/lib/spack/spack/abi.py
index 9e1ef14551..a29a9eef3b 100644
--- a/lib/spack/spack/abi.py
+++ b/lib/spack/spack/abi.py
@@ -18,10 +18,13 @@ class ABI(object):
"""This class provides methods to test ABI compatibility between specs.
The current implementation is rather rough and could be improved."""
- def architecture_compatible(self, parent, child):
- """Return true if parent and child have ABI compatible targets."""
- return not parent.architecture or not child.architecture or \
- parent.architecture == child.architecture
+ def architecture_compatible(self, target, constraint):
+ """Return true if architecture of target spec is ABI compatible
+ to the architecture of constraint spec. If either the target
+ or constraint specs have no architecture, target is also defined
+ as architecture ABI compatible to constraint."""
+ return not target.architecture or not constraint.architecture or \
+ target.architecture.satisfies(constraint.architecture)
@memoized
def _gcc_get_libstdcxx_version(self, version):
@@ -107,8 +110,8 @@ class ABI(object):
return True
return False
- def compatible(self, parent, child, **kwargs):
- """Returns true iff a parent and child spec are ABI compatible"""
+ def compatible(self, target, constraint, **kwargs):
+ """Returns true if target spec is ABI compatible to constraint spec"""
loosematch = kwargs.get('loose', False)
- return self.architecture_compatible(parent, child) and \
- self.compiler_compatible(parent, child, loose=loosematch)
+ return self.architecture_compatible(target, constraint) and \
+ self.compiler_compatible(target, constraint, loose=loosematch)
diff --git a/lib/spack/spack/test/abi.py b/lib/spack/spack/test/abi.py
new file mode 100644
index 0000000000..dd41228941
--- /dev/null
+++ b/lib/spack/spack/test/abi.py
@@ -0,0 +1,66 @@
+# Copyright 2013-2020 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)
+""" Test ABI compatibility helpers"""
+
+import pytest
+
+from spack.abi import ABI
+from spack.spec import Spec
+
+
+@pytest.mark.parametrize(
+ 'target,constraint,expected',
+ [
+ ('foo', 'bar', True),
+ ('platform=linux', 'foo', True),
+ ('foo', 'arch=linux-fedora31-x86_64', True),
+ ('arch=linux-fedora31-skylake', 'arch=linux-fedora31-skylake', True),
+ ('arch=linux-fedora31-skylake', 'arch=linux-fedora31-x86_64', False),
+ ('platform=linux os=fedora31', 'arch=linux-fedora31-x86_64', True),
+ ('platform=linux', 'arch=linux-fedora31-x86_64', True),
+ ('platform=linux os=fedora31', 'platform=linux', True),
+ ('platform=darwin', 'arch=linux-fedora31-x86_64', False),
+ ('os=fedora31', 'platform=linux', False), # TODO should be true ?
+ ])
+def test_architecture_compatibility(target, constraint, expected):
+ assert ABI().architecture_compatible(Spec(target),
+ Spec(constraint)) == expected
+
+
+@pytest.mark.parametrize(
+ 'target,constraint,loose,expected',
+ [
+ ('foo', 'bar', False, True),
+ ('%gcc', 'foo', False, True),
+ ('foo', '%gcc', False, True),
+ ('%gcc', '%gcc', False, True),
+ ('%gcc', '%intel', False, False),
+ ('%gcc', '%clang', False, False),
+ ('%gcc@9.1', '%gcc@9.2', False, False), # TODO should be true ?
+ ('%gcc@9.2.1', '%gcc@9.2.2', False, False), # TODO should be true ?
+ ('%gcc@4.9', '%gcc@9.2', False, False),
+ ('%clang@5', '%clang@6', False, False),
+ ('%gcc@9.1', '%gcc@9.2', True, True),
+ ('%gcc@9.2.1', '%gcc@9.2.2', True, True),
+ ('%gcc@4.9', '%gcc@9.2', True, True),
+ ('%clang@5', '%clang@6', True, True),
+ ])
+def test_compiler_compatibility(target, constraint, loose, expected):
+ assert ABI().compiler_compatible(Spec(target),
+ Spec(constraint),
+ loose=loose) == expected
+
+
+@pytest.mark.parametrize('target,constraint,loose,expected', [
+ ('foo', 'bar', False, True),
+ ('%gcc', 'platform=linux', False, True),
+ ('%gcc@9.2.1', '%gcc@8.3.1 platform=linux', False, False),
+ ('%gcc@9.2.1', '%gcc@8.3.1 platform=linux', True, True),
+ ('%gcc@9.2.1 arch=linux-fedora31-skylake', '%gcc@9.2.1 platform=linux',
+ False, True),
+])
+def test_compatibility(target, constraint, loose, expected):
+ assert ABI().compatible(Spec(target), Spec(constraint),
+ loose=loose) == expected