Merge pull request #5560 from scivision/cstd18_bug
add clang c_std=c18 alias and cleanup logic for compiler version unit tests
This commit is contained in:
commit
d5cb1c2f19
|
@ -89,13 +89,16 @@ class ClangCCompiler(ClangCompiler, CCompiler):
|
|||
opts = CCompiler.get_options(self)
|
||||
c_stds = ['c89', 'c99', 'c11']
|
||||
g_stds = ['gnu89', 'gnu99', 'gnu11']
|
||||
if self.compiler_type is CompilerType.CLANG_OSX:
|
||||
v = '>=10.0.0'
|
||||
else:
|
||||
v = '>=7.0.0'
|
||||
# https://releases.llvm.org/6.0.0/tools/clang/docs/ReleaseNotes.html
|
||||
# https://en.wikipedia.org/wiki/Xcode#Latest_versions
|
||||
v = '>=10.0.0' if self.compiler_type is CompilerType.CLANG_OSX else '>=6.0.0'
|
||||
if version_compare(self.version, v):
|
||||
c_stds += ['c17']
|
||||
g_stds += ['gnu17']
|
||||
v = '>=11.0.0' if self.compiler_type is CompilerType.CLANG_OSX else '>=8.0.0'
|
||||
if version_compare(self.version, v):
|
||||
c_stds += ['c18']
|
||||
g_stds += ['gnu18']
|
||||
opts.update({'c_std': coredata.UserComboOption('C language standard to use',
|
||||
['none'] + c_stds + g_stds,
|
||||
'none')})
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
"""A library of random helper functionality."""
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
import sys
|
||||
import stat
|
||||
import time
|
||||
|
@ -259,7 +258,7 @@ class File:
|
|||
def endswith(self, ending: str) -> bool:
|
||||
return self.fname.endswith(ending)
|
||||
|
||||
def split(self, s: str) -> List[str]:
|
||||
def split(self, s: str) -> typing.List[str]:
|
||||
return self.fname.split(s)
|
||||
|
||||
def __eq__(self, other) -> bool:
|
||||
|
@ -463,7 +462,7 @@ def is_dragonflybsd() -> bool:
|
|||
def is_freebsd() -> bool:
|
||||
return platform.system().lower() == 'freebsd'
|
||||
|
||||
def exe_exists(arglist: List[str]) -> bool:
|
||||
def exe_exists(arglist: typing.List[str]) -> bool:
|
||||
try:
|
||||
if subprocess.run(arglist, timeout=10).returncode == 0:
|
||||
return True
|
||||
|
@ -574,7 +573,7 @@ class Version:
|
|||
# otherwise, the version with a suffix remaining is greater
|
||||
return comparator(len(self._v), len(other._v))
|
||||
|
||||
def _version_extract_cmpop(vstr2):
|
||||
def _version_extract_cmpop(vstr2: str) -> typing.Tuple[typing.Callable[[typing.Any, typing.Any], bool], str]:
|
||||
if vstr2.startswith('>='):
|
||||
cmpop = operator.ge
|
||||
vstr2 = vstr2[2:]
|
||||
|
@ -601,7 +600,7 @@ def _version_extract_cmpop(vstr2):
|
|||
|
||||
return (cmpop, vstr2)
|
||||
|
||||
def version_compare(vstr1, vstr2):
|
||||
def version_compare(vstr1: str, vstr2: str) -> bool:
|
||||
(cmpop, vstr2) = _version_extract_cmpop(vstr2)
|
||||
return cmpop(Version(vstr1), Version(vstr2))
|
||||
|
||||
|
@ -619,7 +618,7 @@ def version_compare_many(vstr1, conditions):
|
|||
|
||||
# determine if the minimum version satisfying the condition |condition| exceeds
|
||||
# the minimum version for a feature |minimum|
|
||||
def version_compare_condition_with_min(condition, minimum):
|
||||
def version_compare_condition_with_min(condition: str, minimum: str) -> bool:
|
||||
if condition.startswith('>='):
|
||||
cmpop = operator.le
|
||||
condition = condition[2:]
|
||||
|
@ -682,7 +681,7 @@ def default_libexecdir():
|
|||
def default_prefix():
|
||||
return 'c:/' if is_windows() else '/usr/local'
|
||||
|
||||
def get_library_dirs() -> List[str]:
|
||||
def get_library_dirs() -> typing.List[str]:
|
||||
if is_windows():
|
||||
return ['C:/mingw/lib'] # TODO: get programatically
|
||||
if is_osx():
|
||||
|
|
|
@ -279,6 +279,7 @@ class PatchModule:
|
|||
Fancy monkey-patching! Whee! Can't use mock.patch because it only
|
||||
patches in the local namespace.
|
||||
'''
|
||||
|
||||
def __init__(self, func, name, impl):
|
||||
self.func = func
|
||||
assert(isinstance(name, str))
|
||||
|
@ -1483,6 +1484,7 @@ class AllPlatformTests(BasePlatformTests):
|
|||
'''
|
||||
Tests that should run on all platforms
|
||||
'''
|
||||
|
||||
def test_default_options_prefix(self):
|
||||
'''
|
||||
Tests that setting a prefix in default_options in project() works.
|
||||
|
@ -4055,6 +4057,7 @@ class WindowsTests(BasePlatformTests):
|
|||
'''
|
||||
Tests that should run on Cygwin, MinGW, and MSVC
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.platform_test_dir = os.path.join(self.src_root, 'test cases/windows')
|
||||
|
@ -4169,6 +4172,7 @@ class DarwinTests(BasePlatformTests):
|
|||
'''
|
||||
Tests that should run on macOS
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.platform_test_dir = os.path.join(self.src_root, 'test cases/osx')
|
||||
|
@ -4268,6 +4272,7 @@ class LinuxlikeTests(BasePlatformTests):
|
|||
'''
|
||||
Tests that should run on Linux, macOS, and *BSD
|
||||
'''
|
||||
|
||||
def test_basic_soname(self):
|
||||
'''
|
||||
Test that the soname is set correctly for shared libraries. This can't
|
||||
|
@ -4556,20 +4561,32 @@ class LinuxlikeTests(BasePlatformTests):
|
|||
Oargs = [arg for arg in cmd if arg.startswith('-O')]
|
||||
self.assertEqual(Oargs, [Oflag, '-O0'])
|
||||
|
||||
def _test_stds_impl(self, testdir, compiler, p):
|
||||
def _test_stds_impl(self, testdir, compiler, p: str):
|
||||
lang_std = p + '_std'
|
||||
# Check that all the listed -std=xxx options for this compiler work
|
||||
# just fine when used
|
||||
|
||||
has_cpp17 = (compiler.get_id() not in {'clang', 'gcc'} or
|
||||
compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=5.0.0', '>=9.1') or
|
||||
compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=5.0.0'))
|
||||
has_cpp2a_c17 = (compiler.get_id() not in {'clang', 'gcc'} or
|
||||
compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=6.0.0', '>=10.0') or
|
||||
compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=8.0.0'))
|
||||
has_c18 = (compiler.get_id() not in {'clang', 'gcc'} or
|
||||
compiler.get_id() == 'clang' and _clang_at_least(compiler, '>=8.0.0', '>=11.0') or
|
||||
compiler.get_id() == 'gcc' and version_compare(compiler.version, '>=8.0.0'))
|
||||
# Check that all the listed -std=xxx options for this compiler work just fine when used
|
||||
# https://en.wikipedia.org/wiki/Xcode#Latest_versions
|
||||
# https://www.gnu.org/software/gcc/projects/cxx-status.html
|
||||
for v in compiler.get_options()[lang_std].choices:
|
||||
if (compiler.get_id() == 'clang' and '17' in v and
|
||||
(version_compare(compiler.version, '<5.0.0') or
|
||||
(compiler.compiler_type == mesonbuild.compilers.CompilerType.CLANG_OSX and version_compare(compiler.version, '<9.1')))):
|
||||
# we do it like this to handle gnu++17,c++17 and gnu17,c17 cleanly
|
||||
# thus, C++ first
|
||||
if '++17' in v and not has_cpp17:
|
||||
continue
|
||||
if (compiler.get_id() == 'clang' and '2a' in v and
|
||||
(version_compare(compiler.version, '<6.0.0') or
|
||||
(compiler.compiler_type == mesonbuild.compilers.CompilerType.CLANG_OSX and version_compare(compiler.version, '<9.1')))):
|
||||
elif '++2a' in v and not has_cpp2a_c17: # https://en.cppreference.com/w/cpp/compiler_support
|
||||
continue
|
||||
if (compiler.get_id() == 'gcc' and '2a' in v and version_compare(compiler.version, '<8.0.0')):
|
||||
# now C
|
||||
elif '17' in v and not has_cpp2a_c17:
|
||||
continue
|
||||
elif '18' in v and not has_c18:
|
||||
continue
|
||||
std_opt = '{}={}'.format(lang_std, v)
|
||||
self.init(testdir, extra_args=['-D' + std_opt])
|
||||
|
@ -5326,6 +5343,7 @@ class LinuxCrossArmTests(BasePlatformTests):
|
|||
'''
|
||||
Tests that cross-compilation to Linux/ARM works
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
src_root = os.path.dirname(__file__)
|
||||
|
@ -5385,6 +5403,7 @@ class LinuxCrossMingwTests(BasePlatformTests):
|
|||
'''
|
||||
Tests that cross-compilation to Windows/MinGW works
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
src_root = os.path.dirname(__file__)
|
||||
|
@ -5438,6 +5457,7 @@ class PythonTests(BasePlatformTests):
|
|||
'''
|
||||
Tests that verify compilation of python extension modules
|
||||
'''
|
||||
|
||||
def test_versions(self):
|
||||
if self.backend is not Backend.ninja:
|
||||
raise unittest.SkipTest('Skipping python tests with {} backend'.format(self.backend.name))
|
||||
|
@ -6482,6 +6502,30 @@ class TAPParserTests(unittest.TestCase):
|
|||
self.assert_test(events, number=2, name='', result=TestResult.FAIL)
|
||||
self.assert_last(events)
|
||||
|
||||
|
||||
def _clang_at_least(compiler, minver: str, apple_minver: str) -> bool:
|
||||
"""
|
||||
check that Clang compiler is at least a specified version, whether AppleClang or regular Clang
|
||||
|
||||
Parameters
|
||||
----------
|
||||
compiler:
|
||||
Meson compiler object
|
||||
minver: str
|
||||
Clang minimum version
|
||||
apple_minver: str
|
||||
AppleCLang minimum version
|
||||
|
||||
Returns
|
||||
-------
|
||||
at_least: bool
|
||||
Clang is at least the specified version
|
||||
"""
|
||||
if compiler.compiler_type == mesonbuild.compilers.CompilerType.CLANG_OSX:
|
||||
return version_compare(compiler.version, apple_minver)
|
||||
return version_compare(compiler.version, minver)
|
||||
|
||||
|
||||
def unset_envs():
|
||||
# For unit tests we must fully control all command lines
|
||||
# so that there are no unexpected changes coming from the
|
||||
|
|
Loading…
Reference in New Issue