Improved detection of Clang versions (#10316)

Fixes #10191

* Add more regular expressions to detect clang versions that were
  not being picked up
* Add a test for parsing versions from the output of Clang (this
  does not run Clang, but rather uses example outputs from Clang)
* Separate Clang version parsing into its own method (to make it
  easier to test)
This commit is contained in:
Massimiliano Culpo 2019-03-11 19:15:34 +01:00 committed by Peter Scheibel
parent 1fd01af773
commit a42fd7f276
2 changed files with 48 additions and 13 deletions

View File

@ -178,22 +178,33 @@ def default_version(cls, comp):
if comp not in _version_cache: if comp not in _version_cache:
compiler = Executable(comp) compiler = Executable(comp)
output = compiler('--version', output=str, error=str) output = compiler('--version', output=str, error=str)
_version_cache[comp] = cls.detect_version_from_str(output)
ver = 'unknown'
match = re.search(r'^Apple LLVM version ([^ )]+)', output)
if match:
# Apple's LLVM compiler has its own versions, so suffix them.
ver = match.group(1) + '-apple'
else:
# Normal clang compiler versions are left as-is
match = re.search(r'clang version ([^ )]+)', output)
if match:
ver = match.group(1)
_version_cache[comp] = ver
return _version_cache[comp] return _version_cache[comp]
@classmethod
def detect_version_from_str(cls, output):
"""Returns the version that has been detected from the string
passed as input. If no detection is possible returns the
string 'unknown'.
Args:
output (str): string used to detect a compiler version
"""
ver = 'unknown'
match = re.search(
# Apple's LLVM compiler has its own versions, so suffix them.
r'^Apple LLVM version ([^ )]+)|'
# Normal clang compiler versions are left as-is
r'clang version ([^ )]+)-svn[~.\w\d-]*|'
r'clang version ([^ )]+)',
output
)
if match:
suffix = '-apple' if match.lastindex == 1 else ''
ver = match.group(match.lastindex) + suffix
return ver
@classmethod @classmethod
def fc_version(cls, fc): def fc_version(cls, fc):
# We could map from gcc/gfortran version to clang version, but on macOS # We could map from gcc/gfortran version to clang version, but on macOS

View File

@ -3,11 +3,15 @@
# #
# SPDX-License-Identifier: (Apache-2.0 OR MIT) # SPDX-License-Identifier: (Apache-2.0 OR MIT)
import pytest
from copy import copy from copy import copy
from six import iteritems from six import iteritems
import spack.spec import spack.spec
import spack.compiler
import spack.compilers as compilers import spack.compilers as compilers
import spack.compilers.clang
from spack.compiler import _get_versioned_tuple, Compiler from spack.compiler import _get_versioned_tuple, Compiler
@ -227,3 +231,23 @@ def test_xl_r_flags():
unsupported_flag_test("cxx11_flag", "xl_r@13.0") unsupported_flag_test("cxx11_flag", "xl_r@13.0")
supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl_r@13.1") supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl_r@13.1")
supported_flag_test("pic_flag", "-qpic", "xl_r@1.0") supported_flag_test("pic_flag", "-qpic", "xl_r@1.0")
@pytest.mark.regression('10191')
@pytest.mark.parametrize('version_str,expected_version', [
# macOS clang
('Apple LLVM version 7.0.2 (clang-700.1.81)\n'
'Target: x86_64-apple-darwin15.2.0\n'
'Thread model: posix\n', '7.0.2-apple'),
# Other platforms
('clang version 6.0.1-svn334776-1~exp1~20181018152737.116 (branches/release_60)\n' # noqa
'Target: x86_64-pc-linux-gnu\n'
'Thread model: posix\n'
'InstalledDir: /usr/bin\n', '6.0.1'),
('clang version 3.1 (trunk 149096)\n'
'Target: x86_64-unknown-linux-gnu\n'
'Thread model: posix\n', '3.1'),
])
def test_clang_version_detection(version_str, expected_version):
version = spack.compilers.clang.Clang.detect_version_from_str(version_str)
assert version == expected_version