Fix ABI detection issues with macOS gcc. (#3854)
- gcc on macOS says it's version 4.2.1, but it's really clang, and it's actually the *same* clang as the system clang. - It also doesn't respond with a full path when called with --print-file-name=libstdc++.dylib, which is expected from gcc in abi.py. Instead, it gives a relative path and _gcc_compiler_compare doesn't understand what to do with it. This results in errors like: ``` lib/spack/spack/abi.py, line 71, in _gcc_get_libstdcxx_version libpath = os.readlink(output.strip()) OSError: [Errno 2] No such file or directory: 'libstdc++.dylib' ``` - This commit does two things: 1. Ignore any gcc that's actually clang in abi.py. We can probably do better than this, but it's not clear there is a need to, since we should handle the compiler as clang, not gcc. 2. Don't auto-detect any "gcc" that is actually clang anymore. Ignore it and expect people to use clang (which is the default macOS compiler anyway). Users can still add fake gccs to their compilers.yaml if they want, but it's discouraged.
This commit is contained in:
parent
63c3410370
commit
c67f8e4aa1
@ -29,6 +29,7 @@
|
||||
from spack.build_environment import dso_suffix
|
||||
from spack.spec import CompilerSpec
|
||||
from spack.util.executable import Executable, ProcessError
|
||||
from spack.compilers.clang import Clang
|
||||
from llnl.util.lang import memoized
|
||||
|
||||
|
||||
@ -44,7 +45,7 @@ def architecture_compatible(self, parent, child):
|
||||
@memoized
|
||||
def _gcc_get_libstdcxx_version(self, version):
|
||||
"""Returns gcc ABI compatibility info by getting the library version of
|
||||
a compiler's libstdc++.so or libgcc_s.so"""
|
||||
a compiler's libstdc++ or libgcc_s"""
|
||||
spec = CompilerSpec("gcc", version)
|
||||
compilers = spack.compilers.compilers_for_spec(spec)
|
||||
if not compilers:
|
||||
@ -62,6 +63,12 @@ def _gcc_get_libstdcxx_version(self, version):
|
||||
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,
|
||||
return_output=True)
|
||||
except ProcessError:
|
||||
|
@ -49,14 +49,15 @@ def _verify_executables(*paths):
|
||||
|
||||
|
||||
def get_compiler_version(compiler_path, version_arg, regex='(.*)'):
|
||||
if compiler_path not in _version_cache:
|
||||
key = (compiler_path, version_arg, regex)
|
||||
if key not in _version_cache:
|
||||
compiler = Executable(compiler_path)
|
||||
output = compiler(version_arg, output=str, error=str)
|
||||
|
||||
match = re.search(regex, output)
|
||||
_version_cache[compiler_path] = match.group(1) if match else 'unknown'
|
||||
_version_cache[key] = match.group(1) if match else 'unknown'
|
||||
|
||||
return _version_cache[compiler_path]
|
||||
return _version_cache[key]
|
||||
|
||||
|
||||
def dumpversion(compiler_path):
|
||||
|
@ -87,6 +87,16 @@ def cxx17_flag(self):
|
||||
def pic_flag(self):
|
||||
return "-fPIC"
|
||||
|
||||
@classmethod
|
||||
def default_version(cls, cc):
|
||||
# Skip any gcc versions that are actually clang, like Apple's gcc.
|
||||
# Returning "unknown" makes them not detected by default.
|
||||
# Users can add these manually to compilers.yaml at their own risk.
|
||||
if spack.compilers.clang.Clang.default_version(cc) != 'unknown':
|
||||
return 'unknown'
|
||||
|
||||
return super(Gcc, cls).default_version(cc)
|
||||
|
||||
@classmethod
|
||||
def fc_version(cls, fc):
|
||||
return get_compiler_version(
|
||||
|
@ -89,6 +89,4 @@ def test_compiler_add(self, mock_compiler_dir):
|
||||
# Ensure new compiler is in there
|
||||
new_compilers = set(spack.compilers.all_compiler_specs())
|
||||
new_compiler = new_compilers - old_compilers
|
||||
assert new_compiler
|
||||
assert sum(1 for c in new_compiler if
|
||||
c.version == Version(test_version)) > 0
|
||||
assert any(c.version == Version(test_version) for c in new_compiler)
|
||||
|
Loading…
Reference in New Issue
Block a user