abi.py: remove (#46047)
This commit is contained in:
parent
900765901d
commit
297e43b097
@ -1,131 +0,0 @@
|
||||
# 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)
|
||||
|
||||
import os
|
||||
|
||||
from llnl.util.lang import memoized
|
||||
|
||||
import spack.spec
|
||||
import spack.version
|
||||
from spack.compilers.clang import Clang
|
||||
from spack.util.executable import Executable, ProcessError
|
||||
|
||||
|
||||
class ABI:
|
||||
"""This class provides methods to test ABI compatibility between specs.
|
||||
The current implementation is rather rough and could be improved."""
|
||||
|
||||
def architecture_compatible(
|
||||
self, target: spack.spec.Spec, constraint: spack.spec.Spec
|
||||
) -> bool:
|
||||
"""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.intersects(constraint.architecture)
|
||||
)
|
||||
|
||||
@memoized
|
||||
def _gcc_get_libstdcxx_version(self, version):
|
||||
"""Returns gcc ABI compatibility info by getting the library version of
|
||||
a compiler's libstdc++ or libgcc_s"""
|
||||
from spack.build_environment import dso_suffix
|
||||
|
||||
spec = spack.spec.CompilerSpec("gcc", version)
|
||||
compilers = spack.compilers.compilers_for_spec(spec)
|
||||
if not compilers:
|
||||
return None
|
||||
compiler = compilers[0]
|
||||
rungcc = None
|
||||
libname = None
|
||||
output = None
|
||||
if compiler.cxx:
|
||||
rungcc = Executable(compiler.cxx)
|
||||
libname = "libstdc++." + dso_suffix
|
||||
elif compiler.cc:
|
||||
rungcc = Executable(compiler.cc)
|
||||
libname = "libgcc_s." + dso_suffix
|
||||
else:
|
||||
return None
|
||||
try:
|
||||
# Some gcc's are actually clang and don't respond properly to
|
||||
# --print-file-name (they just print the filename, not the
|
||||
# full path). Ignore these and expect them to be handled as clang.
|
||||
if Clang.default_version(rungcc.exe[0]) != "unknown":
|
||||
return None
|
||||
|
||||
output = rungcc("--print-file-name=%s" % libname, output=str)
|
||||
except ProcessError:
|
||||
return None
|
||||
if not output:
|
||||
return None
|
||||
libpath = os.path.realpath(output.strip())
|
||||
if not libpath:
|
||||
return None
|
||||
return os.path.basename(libpath)
|
||||
|
||||
@memoized
|
||||
def _gcc_compiler_compare(self, pversion, cversion):
|
||||
"""Returns true iff the gcc version pversion and cversion
|
||||
are ABI compatible."""
|
||||
plib = self._gcc_get_libstdcxx_version(pversion)
|
||||
clib = self._gcc_get_libstdcxx_version(cversion)
|
||||
if not plib or not clib:
|
||||
return False
|
||||
return plib == clib
|
||||
|
||||
def _intel_compiler_compare(
|
||||
self, pversion: spack.version.ClosedOpenRange, cversion: spack.version.ClosedOpenRange
|
||||
) -> bool:
|
||||
"""Returns true iff the intel version pversion and cversion
|
||||
are ABI compatible"""
|
||||
|
||||
# Test major and minor versions. Ignore build version.
|
||||
pv = pversion.lo
|
||||
cv = cversion.lo
|
||||
return pv.up_to(2) == cv.up_to(2)
|
||||
|
||||
def compiler_compatible(
|
||||
self, parent: spack.spec.Spec, child: spack.spec.Spec, loose: bool = False
|
||||
) -> bool:
|
||||
"""Return true if compilers for parent and child are ABI compatible."""
|
||||
if not parent.compiler or not child.compiler:
|
||||
return True
|
||||
|
||||
if parent.compiler.name != child.compiler.name:
|
||||
# Different compiler families are assumed ABI incompatible
|
||||
return False
|
||||
|
||||
if loose:
|
||||
return True
|
||||
|
||||
# TODO: Can we move the specialized ABI matching stuff
|
||||
# TODO: into compiler classes?
|
||||
for pversion in parent.compiler.versions:
|
||||
for cversion in child.compiler.versions:
|
||||
# For a few compilers use specialized comparisons.
|
||||
# Otherwise match on version match.
|
||||
if pversion.intersects(cversion):
|
||||
return True
|
||||
elif parent.compiler.name == "gcc" and self._gcc_compiler_compare(
|
||||
pversion, cversion
|
||||
):
|
||||
return True
|
||||
elif parent.compiler.name == "intel" and self._intel_compiler_compare(
|
||||
pversion, cversion
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def compatible(
|
||||
self, target: spack.spec.Spec, constraint: spack.spec.Spec, loose: bool = False
|
||||
) -> bool:
|
||||
"""Returns true if target spec is ABI compatible to constraint spec"""
|
||||
return self.architecture_compatible(target, constraint) and self.compiler_compatible(
|
||||
target, constraint, loose=loose
|
||||
)
|
@ -8,7 +8,6 @@
|
||||
from contextlib import contextmanager
|
||||
from itertools import chain
|
||||
|
||||
import spack.abi
|
||||
import spack.compilers
|
||||
import spack.config
|
||||
import spack.environment
|
||||
|
@ -1,66 +0,0 @@
|
||||
# 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)
|
||||
""" 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", 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
|
Loading…
Reference in New Issue
Block a user