From c7a543620d72ced18ca6edb9afbb29834593c176 Mon Sep 17 00:00:00 2001 From: Tom J Nowell Date: Mon, 29 Jun 2026 12:34:25 +0100 Subject: [PATCH] macOS: compile Objective-C sources with clang when building with GCC GCC on macOS cannot target Apple's Objective-C runtime, so any Objective-C or Objective-C++ source (.m / .mm) fails to build (or interoperate) under a GCC toolchain. macOS platform integration in the renderer needs a small amount of such code (e.g. Metal presentation glue), so the engine otherwise has to be built entirely with AppleClang just to compile those few files. Enable the OBJC and OBJCXX languages on Apple and, when the C/C++ compiler is GCC, point them at clang. CMake selects a compiler per source language (.m -> OBJC, .mm -> OBJCXX, .c/.cpp -> C/CXX), so Objective-C sources are routed to clang automatically with no per-file or per-target handling, while the rest of the engine keeps building with GCC. CMake also links libc++ for targets containing such objects automatically. Scope: this covers Objective-C only, which keeps a clean ABI story -- clang compiles .m/.mm against libc++, and these sources must expose an extern "C" boundary so no C++ standard-library type crosses to the engine's libstdc++ side. C++ that must be compiled with clang is intentionally out of scope: it would require clang to use libstdc++ for ABI compatibility, which macOS does not ship; such code should instead be isolated behind a C boundary. No functional change on non-Apple platforms, and no change when already building with AppleClang (the languages are simply enabled). --- CMakeLists.txt | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index d016d27287..719ab889b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,30 @@ else (APPLE) set(MACOSX_BUNDLE FALSE) endif (APPLE) +# Objective-C / Objective-C++ are needed for some macOS platform integration +# (e.g. Metal presentation glue in the renderer). GCC on macOS cannot target +# Apple's Objective-C runtime, so when the engine is built with GCC we route +# .m / .mm sources to clang while everything else keeps building with GCC. +# CMake selects the compiler per source language (.m -> OBJC, .mm -> OBJCXX) +# and links libc++ for such targets automatically, so no per-file or +# per-target handling is required. Objective-C sources used this way must keep +# an extern "C" boundary: clang compiles them against libc++, so no C++ +# standard-library types may cross to the libstdc++ side of the engine. +if (APPLE) + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + find_program(OBJC_CLANG NAMES clang) + find_program(OBJCXX_CLANG NAMES clang++) + if (NOT OBJC_CLANG OR NOT OBJCXX_CLANG) + message(FATAL_ERROR "Building on macOS with GCC requires clang/clang++ for Objective-C sources, but they were not found") + endif () + set(CMAKE_OBJC_COMPILER "${OBJC_CLANG}") + set(CMAKE_OBJCXX_COMPILER "${OBJCXX_CLANG}") + message(STATUS "macOS: compiling Objective-C/C++ with clang (${OBJCXX_CLANG}); C/C++ use ${CMAKE_CXX_COMPILER}") + endif () + enable_language(OBJC) + enable_language(OBJCXX) +endif (APPLE) + ### Compiler flags and defines based on build type include(TestCXXFlags)