Skip to content

Commit

Permalink
compilers: Check if GCC has support for ObjC and/or ObjC++
Browse files Browse the repository at this point in the history
Since this is optional, we should not accept that GCC is a valid ObjC or
G++ is a valid ObjC++ Compiler unless we've tested that they can
actually do a basic compile.

This requires fixing a number of tests that have broken assumptions. In
some cases I've split tests where issues with one language would hide
the other. It would be great if we had a competent test framework that
allowed subtests to skip, unfortunately we have python's unittest
instead. Because of that we can't avoid extra tests by use of subtests.
  • Loading branch information
dcbaker committed Nov 19, 2024
1 parent dd2d0c5 commit 9899199
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 10 deletions.
6 changes: 5 additions & 1 deletion mesonbuild/compilers/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,9 +877,13 @@ def _detect_objc_or_objcpp_compiler(env: 'Environment', lang: str, for_machine:
version = _get_gnu_version_from_defines(defines)
comp = objc.GnuObjCCompiler if lang == 'objc' else objcpp.GnuObjCPPCompiler
linker = guess_nix_linker(env, compiler, comp, version, for_machine)
return comp(
c = comp(
ccache, compiler, version, for_machine, is_cross, info,
defines, linker=linker)
if not c.compiles('int main(void) { return 0; }', env)[0]:
popen_exceptions[join_args(compiler)] = f'GCC was not built with support for {"objective-c" if lang == "objc" else "objective-c++"}'
continue
return c
if 'clang' in out:
linker = None
defines = _get_clang_compiler_defines(compiler, lang)
Expand Down
19 changes: 13 additions & 6 deletions unittests/failuretests.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,19 +241,26 @@ def test_dependency_invalid_method(self):
'''
self.assertMesonRaises(code, ".* is not a config-tool dependency")

def test_objc_cpp_detection(self):
def test_objc_detection(self) -> None:
'''
Test that when we can't detect objc or objcpp, we fail gracefully.
'''
env = get_fake_env()
try:
detect_objc_compiler(env, MachineChoice.HOST)
except EnvironmentException as e:
self.assertRegex(str(e), r"(Unknown compiler|GCC was not built with support)")
else:
raise unittest.SkipTest('Working objective-c Compiler found, cannot test error.')

def test_objcpp_detection(self) -> None:
env = get_fake_env()
try:
detect_objcpp_compiler(env, MachineChoice.HOST)
except EnvironmentException:
code = "add_languages('objc')\nadd_languages('objcpp')"
self.assertMesonRaises(code, "Unknown compiler")
return
raise unittest.SkipTest("objc and objcpp found, can't test detection failure")
except EnvironmentException as e:
self.assertRegex(str(e), r"(Unknown compiler|GCC was not built with support)")
else:
raise unittest.SkipTest('Working objective-c++ Compiler found, cannot test error.')

def test_subproject_variables(self):
'''
Expand Down
16 changes: 13 additions & 3 deletions unittests/machinefiletests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import mesonbuild.environment
import mesonbuild.coredata
import mesonbuild.modules.gnome

from mesonbuild import mesonlib
from mesonbuild import machinefile

from mesonbuild.mesonlib import (
Expand Down Expand Up @@ -275,7 +275,12 @@ def cb(comp):
if not is_real_gnu_compiler(shutil.which('gcc')):
raise SkipTest('Only one compiler found, cannot test.')
return 'gcc', 'gcc'
self.helper_for_compiler('objc', cb)
try:
self.helper_for_compiler('objc', cb)
except mesonlib.EnvironmentException as e:
if 'GCC was not built with support for objective-c' in str(e):
raise unittest.SkipTest("GCC doesn't support objective-c, test cannot run")
raise

@skip_if_not_language('objcpp')
@skip_if_env_set('OBJCXX')
Expand All @@ -288,7 +293,12 @@ def cb(comp):
if not is_real_gnu_compiler(shutil.which('g++')):
raise SkipTest('Only one compiler found, cannot test.')
return 'g++', 'gcc'
self.helper_for_compiler('objcpp', cb)
try:
self.helper_for_compiler('objcpp', cb)
except mesonlib.EnvironmentException as e:
if 'GCC was not built with support for objective-c++' in str(e):
raise unittest.SkipTest("G++ doesn't support objective-c++, test cannot run")
raise

@skip_if_not_language('d')
@skip_if_env_set('DC')
Expand Down

0 comments on commit 9899199

Please sign in to comment.