summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@gmail.com>2019-03-11 19:15:34 +0100
committerPeter Scheibel <scheibel1@llnl.gov>2019-03-11 13:15:34 -0500
commita42fd7f27617db03f2d9d8b4539cec88d03a3949 (patch)
treed021134106732db331b6aa5fde8bb740bd6ea025 /lib
parent1fd01af77336443ca2342ae4515b27261131f124 (diff)
downloadspack-a42fd7f27617db03f2d9d8b4539cec88d03a3949.tar.gz
spack-a42fd7f27617db03f2d9d8b4539cec88d03a3949.tar.bz2
spack-a42fd7f27617db03f2d9d8b4539cec88d03a3949.tar.xz
spack-a42fd7f27617db03f2d9d8b4539cec88d03a3949.zip
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)
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/compilers/clang.py35
-rw-r--r--lib/spack/spack/test/compilers.py24
2 files changed, 47 insertions, 12 deletions
diff --git a/lib/spack/spack/compilers/clang.py b/lib/spack/spack/compilers/clang.py
index cf569cd7a8..c21fc60384 100644
--- a/lib/spack/spack/compilers/clang.py
+++ b/lib/spack/spack/compilers/clang.py
@@ -178,21 +178,32 @@ class Clang(Compiler):
if comp not in _version_cache:
compiler = Executable(comp)
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)
+ return _version_cache[comp]
- _version_cache[comp] = ver
+ @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'.
- return _version_cache[comp]
+ 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
def fc_version(cls, fc):
diff --git a/lib/spack/spack/test/compilers.py b/lib/spack/spack/test/compilers.py
index 5c46c0b251..0f0742f78e 100644
--- a/lib/spack/spack/test/compilers.py
+++ b/lib/spack/spack/test/compilers.py
@@ -3,11 +3,15 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+import pytest
+
from copy import copy
from six import iteritems
import spack.spec
+import spack.compiler
import spack.compilers as compilers
+import spack.compilers.clang
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")
supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl_r@13.1")
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