You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

旧SDK编译的x86_64应用如何在Apple Silicon Mac获取真实macOS版本

问题背景
  • 采用macOS 10.15 SDK编译的x86_64架构应用,通过Rosetta 2运行在Apple Silicon芯片的macOS 11+设备上时,所有常规系统版本获取API、sysctlbyname("kern.osproductversion", ...)均会返回伪装的兼容版本号10.16,无法获取真实系统版本。
解决方案

方案1:直接读取系统版本属性列表(推荐)

系统真实版本号明文存储在/System/Library/CoreServices/SystemVersion.plist文件中,该文件不受SDK兼容层、Rosetta转译环境的版本伪装逻辑影响,所有用户(包括沙盒应用)均有读取权限,解析即可拿到真实版本:

// Objective-C 示例代码
NSString *versionPlistPath = @"/System/Library/CoreServices/SystemVersion.plist";
NSDictionary *systemVersionInfo = [NSDictionary dictionaryWithContentsOfFile:versionPlistPath];
NSString *realOSVersion = systemVersionInfo[@"ProductVersion"];

注意:不要尝试读取同目录下的ServerVersion.plist,该文件仅在安装了macOS Server组件的设备上存在,普通消费级系统无此文件。

如果是纯C实现,可以用CoreFoundation的API解析该plist,同样不需要依赖Foundation框架。

方案2:内核版本映射法(无Foundation/CoreFoundation依赖场景适用)

Rosetta兼容层不会伪装kern.osrelease字段返回的内核版本号,可通过该值映射得到真实macOS版本:

  1. 调用sysctlbyname("kern.osrelease", ...)获取内核版本字符串
  2. 提取字符串第一段的主版本号,按对应关系映射即可:
    • 内核主版本20 → macOS 11.x (Big Sur)
    • 内核主版本21 → macOS 12.x (Monterey)
    • 内核主版本22 → macOS 13.x (Ventura)
    • 内核主版本23 → macOS 14.x (Sonoma)
    • 内核主版本24 → macOS 15.x (Sequoia)
// C 示例代码
size_t bufSize = 0;
sysctlbyname("kern.osrelease", NULL, &bufSize, NULL, 0);
char *kernelVersion = malloc(bufSize);
sysctlbyname("kern.osrelease", kernelVersion, &bufSize, NULL, 0);
// 解析kernelVersion字符串,取第一个'.'前的数字即为主版本号,按映射关系匹配系统版本
free(kernelVersion);

该方案无需读取文件系统,但需要随macOS版本更新维护映射关系,适合纯C、无系统框架依赖的开发场景。

旧方案失效原因

Apple为了保证未适配macOS 11新SDK的旧应用能正常运行,对所有链接macOS 11.0之前SDK的应用做了版本兼容伪装:无论实际运行的系统版本是多少,上层版本API、kern.osproductversion sysctl节点都会返回10.16,避免旧应用中硬编码的版本判断逻辑(例如判断系统版本>=11时走新分支但未做兼容)触发崩溃或异常。上述两个方案均绕过了该兼容伪装层,直接读取未被篡改的原始系统信息,因此可以拿到准确结果。

内容的提问来源于stack exchange,提问作者Bri Bri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 01:39:18