Skip collection of compilers which report an empty version (#6684)

Fixes #6200

For compilers that successfully run a version detection script but
don't actually return a version, Spack was keeping track of the
empty version and then failing when attempting to construct a
compiler spec. This skips any attempt to add a compiler entry when
no version is reported (but logs when a compiler fails to report
a version).
This commit is contained in:
scheibelp 2017-12-14 17:54:57 -08:00 committed by GitHub
parent 1aed3f7c01
commit 020ce7735d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 19 deletions

View File

@ -278,27 +278,11 @@ def _find_matches_in_path(cls, compiler_names, detect_version, *path):
match = re.match(regex, exe)
if match:
key = (full_path,) + match.groups()
key = (full_path,) + match.groups() + (detect_version,)
checks.append(key)
def check(key):
try:
full_path, prefix, suffix = key
version = detect_version(full_path)
return (version, prefix, suffix, full_path)
except ProcessError as e:
tty.debug(
"Couldn't get version for compiler %s" % full_path, e)
return None
except Exception as e:
# Catching "Exception" here is fine because it just
# means something went wrong running a candidate executable.
tty.debug("Error while executing candidate compiler %s"
% full_path,
"%s: %s" % (e.__class__.__name__, e))
return None
successful = [k for k in parmap(check, checks) if k is not None]
successful = [k for k in parmap(_get_versioned_tuple, checks)
if k is not None]
# The 'successful' list is ordered like the input paths.
# Reverse it here so that the dict creation (last insert wins)
@ -322,6 +306,28 @@ def __str__(self):
str(self.operating_system)))))
def _get_versioned_tuple(compiler_check_tuple):
full_path, prefix, suffix, detect_version = compiler_check_tuple
try:
version = detect_version(full_path)
if (not version) or (not str(version).strip()):
tty.debug(
"Couldn't get version for compiler %s" % full_path)
return None
return (version, prefix, suffix, full_path)
except ProcessError as e:
tty.debug(
"Couldn't get version for compiler %s" % full_path, e)
return None
except Exception as e:
# Catching "Exception" here is fine because it just
# means something went wrong running a candidate executable.
tty.debug("Error while executing candidate compiler %s"
% full_path,
"%s: %s" % (e.__class__.__name__, e))
return None
class CompilerAccessError(spack.error.SpackError):
def __init__(self, path):

View File

@ -27,6 +27,7 @@
import spack.spec
import spack.compilers as compilers
from spack.compiler import _get_versioned_tuple
@pytest.mark.usefixtures('config')
@ -49,6 +50,19 @@ def test_all_compilers(self):
assert len(filtered) == 1
def test_version_detection_is_empty():
no_version = lambda x: None
compiler_check_tuple = ('/usr/bin/gcc', '', r'\d\d', no_version)
assert not _get_versioned_tuple(compiler_check_tuple)
def test_version_detection_is_successful():
version = lambda x: '4.9'
compiler_check_tuple = ('/usr/bin/gcc', '', r'\d\d', version)
assert _get_versioned_tuple(compiler_check_tuple) == (
'4.9', '', r'\d\d', '/usr/bin/gcc')
def test_compiler_flags_from_config_are_grouped():
compiler_entry = {
'spec': 'intel@17.0.2',