diff --git a/lib/spack/spack/abi.py b/lib/spack/spack/abi.py index b3b1dd6d27838b868a935ead63be0161d11630aa..ad3cae6ee2b721d863de2fa50e06d5346ba33075 100644 --- a/lib/spack/spack/abi.py +++ b/lib/spack/spack/abi.py @@ -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: diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py index 90af900d0da448fd6249ab46c610ffadb3a93a70..bfce31a9a381e8dfce0d1c190211df0da3fe7aed 100644 --- a/lib/spack/spack/compiler.py +++ b/lib/spack/spack/compiler.py @@ -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): diff --git a/lib/spack/spack/compilers/gcc.py b/lib/spack/spack/compilers/gcc.py index 304f82a492e211d67837e73e3c8830870092f9fc..826ddbf432fe7c012cceaff7a7d96e79df560798 100644 --- a/lib/spack/spack/compilers/gcc.py +++ b/lib/spack/spack/compilers/gcc.py @@ -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( diff --git a/lib/spack/spack/test/cmd/test_compiler_cmd.py b/lib/spack/spack/test/cmd/test_compiler_cmd.py index 842b64039e45a0427d32bd49a599bc2a2b59bc4a..b046cdb9228a58027cc94411401d779f600e4e22 100644 --- a/lib/spack/spack/test/cmd/test_compiler_cmd.py +++ b/lib/spack/spack/test/cmd/test_compiler_cmd.py @@ -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)