diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index 41ecf25288a7..8cb9acd9200f 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -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) diff --git a/unittests/failuretests.py b/unittests/failuretests.py index baa59204766f..038a43755f25 100644 --- a/unittests/failuretests.py +++ b/unittests/failuretests.py @@ -238,19 +238,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: + self.assertMesonRaises("add_languages('objc')", 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") + self.assertMesonRaises("add_languages('objcpp')", 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): ''' diff --git a/unittests/machinefiletests.py b/unittests/machinefiletests.py index ba9cb11530dd..99c2701e7dd5 100644 --- a/unittests/machinefiletests.py +++ b/unittests/machinefiletests.py @@ -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 ( @@ -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') @@ -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')