This fixes compilation, provided the executable is linked to libobjc (-lobjc should be added to ninja patch), however at least on 10.6.8 it returns then 0.0.0 for the OS version. Still, may be useful for some macOS, keep it. --- bee.lua/bee/platform/version.cpp +++ bee.lua/bee/platform/version.cpp 2025-08-08 02:36:23.000000000 +0800 @@ -2,6 +2,10 @@ #if defined(__APPLE__) # include +# include +# include +# include +# include #else # if defined(_WIN32) # include @@ -71,27 +75,35 @@ version os_version() { #if defined(__APPLE__) // id processInfo = [NSProcessInfo processInfo] - id processInfo = reinterpret_cast(objc_msgSend)(objc_getClass("NSProcessInfo"), sel_getUid("processInfo")); + id processInfo = ((id (*)(id, SEL))objc_msgSend)( + objc_getClass("NSProcessInfo"), + sel_getUid("processInfo") + ); if (!processInfo) { - return { 0, 0, 0 }; + return {0, 0, 0}; } - struct OSVersion { - int64_t major_version; - int64_t minor_version; - int64_t patch_version; - }; -# if defined(_M_ARM64) || defined(__aarch64__) -# define msgSend objc_msgSend -# else -# define msgSend objc_msgSend_stret -# endif - // NSOperatingSystemVersion version = [processInfo operatingSystemVersion] - OSVersion version = reinterpret_cast(msgSend)(processInfo, sel_getUid("operatingSystemVersion")); - return { - static_cast(version.major_version), - static_cast(version.minor_version), - static_cast(version.patch_version) - }; + // id versionStringObj = [processInfo operatingSystemVersionString] + SEL versionSel = sel_getUid("operatingSystemVersionString"); + id versionStringObj = ((id (*)(id, SEL))objc_msgSend)(processInfo, versionSel); + if (!versionStringObj) { + return {0, 0, 0}; + } + // Check if respondsToSelector:UTF8String + SEL utf8Sel = sel_getUid("UTF8String"); + if (!class_respondsToSelector(object_getClass(versionStringObj), utf8Sel)) { + return {0, 0, 0}; + } + const char* versionCString = ((const char* (*)(id, SEL))objc_msgSend)(versionStringObj, utf8Sel); + if (!versionCString) { + return {0, 0, 0}; + } + unsigned major = 0, minor = 0, patch = 0; + const char* ver = std::strstr(versionCString, "Version "); + if (ver) { + ver += 8; + std::sscanf(ver, "%u.%u.%u", &major, &minor, &patch); + } + return {major, minor, patch}; #elif defined(_WIN32) OSVERSIONINFOW osvi = {}; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);