【问题标题】:Why are MAC_OS_X_VERSION_MIN_REQUIRED and MAC_OS_X_VERSION_MAX_ALLOWED no longer being honored after upgrading to macOS Sierra/Xcode 8?为什么升级到 macOS Sierra/Xcode 8 后 MAC_OS_X_VERSION_MIN_REQUIRED 和 MAC_OS_X_VERSION_MAX_ALLOWED 不再受支持?
【发布时间】:2017-06-01 22:36:26
【问题描述】:

我的 libui 项目必须在 OS X 10.8 和更高版本上编译并以 OS X 10.8 和更高版本为目标,所以我有

#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_8
#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_8

在 Cocoa 代码的共享头文件中。到目前为止,这已经奏效;我没有看到关于 10.9 后弃用的功能。但是,昨晚升级到 10.12 和 Xcode 8 后,我突然看到一大堆弃用警告,例如

/Users/pietro/src/github.com/andlabs/libui/darwin/entry.m:181:28: warning: 
      'NSRegularControlSize' is deprecated: first deprecated in macOS 10.12
      [-Wdeprecated-declarations]
        uiDarwinSetControlFont(t, NSRegularControlSize);
                                  ^~~~~~~~~~~~~~~~~~~~
                                  NSControlSizeRegular
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSCell.h:102:28: note: 
      'NSRegularControlSize' has been explicitly marked deprecated here
static const NSControlSize NSRegularControlSize API_DEPRECATED_WITH_REPL...
                           ^

好像我提供的宏被忽略了。我试图弄清楚发生了什么,但我得到的只是混合信号:Apple 开发人员网站上的一些消息来源告诉我它真的是 __MAC_OS_X_VERSION_MIN_REQUIRED (并使用数字而不是版本本身的符号常量),而其他人告诉我我是的。一些消息来源似乎暗示这些值是由编译器设置决定的?我也说不出Availability.h想要什么。

值得一提的是,这个项目使用 CMake 构建,并没有直接使用 Xcode 项目。

那么我做错了什么?谢谢。

【问题讨论】:

  • 不是自动包含在<Cocoa/Cocoa.h>中吗?
  • 您的部署目标是否在构建设置中设置为
  • @Wevah 是的,它是 10.8,用 set(CMAKE_OSX_DEPLOYMENT_TARGET "10.8") 完成。
  • 哦,对了,您正在使用 CMake 进行构建。我破坏了那条线。

标签: objective-c macos cocoa


【解决方案1】:

我总是用编译器标志设置那些:-mmacosx-version-min=10.8。 CMake 还有一个CMAKE_OSX_DEPLOYMENT_TARGET 变量,我认为它设置了它。

我认为它不会摆脱那些弃用警告。对于那些不推荐使用的 AppKit 常量,不推荐使用的和新的常量具有相同的值。您可以使用新的常量,其值是相同的,并且应该与旧操作系统兼容。

使用新的常量阻止代码在早于 10.12 的系统上编译。 emacs fixed this 使用代码中的新常量,但 #defining 在使用 10.12 之前的 SDK 编译时将旧常量转换为新常量。我implemented the same thingqemu

【讨论】:

  • 谢谢。我稍后会仔细阅读/回复(当我有更多时间时),但我会说我的 CMakeLists.txt 中已经有 set(CMAKE_OSX_DEPLOYMENT_TARGET "10.8")
  • 另外我想知道 -mmacosx-version-min 标志或 CMake 在那里产生的其他任何东西(我现在忘记了细节,抱歉)只会影响目标文件和链接步骤。
  • 实际上我刚刚注意到一些事情:一些弃用警告位于static const 变量上,这意味着我不能在ISO C99 模式下的switch 语句中使用它们而不会发出警告。我很想在这一点上打开一个雷达,如果这样我可以从源代码中了解当前宏应该是什么,或者如果你链接的开源代码是我唯一真正的选择......(我是希望我可以使用不同的 SDK,但我现在似乎只有 10.12.sdk。)
  • 每个警告都应该告诉您替换宏是什么,您还可以在标题中查看它们是如何定义的。比如NSControlSizeRegular(新的)定义在一个NS_ENUM中,那么废弃的NSRegularControlSize就是static const NSControlSize NSRegularControlSize = NSControlSizeRegular;,使用新的应该不会有同样的static const问题。
  • 不会,但它会破坏旧系统上的编译,因此您链接的那些开源项目必须自己制作#defines。
【解决方案2】:

叹息。问题是 CMake 很愚蠢。

好的,事实证明所有这些新的弃用系统都记录在案,但是以一种迂回的方式。首先,新的弃用宏是mentioned here in the 10.12 SDK release notes。如果我查看定义它们的 Availability.h,我看到它们在 clang 中扩展为一个新的 availability 属性。你瞧,they are controlled by the -mmacosx-deployment-target option after all

但是等等,我有

set(CMAKE_OSX_DEPLOYMENT_TARGET "10.8")

在我的 CMakeLists.txt 中。这还不够吗?显然不是,因为 -mmacosx-version-min 没有被放入 Makefiles!

As it turns outCMAKE_OSX_DEPLOYMENT_TARGET 是那些愚蠢的 CMake 变量之一,需要您使用 CACHE STRING "" FORCE 实际的 set() 才能使它们工作。因此,一旦我将行更改为

set(CMAKE_OSX_DEPLOYMENT_TARGET "10.8" CACHE STRING "" FORCE)

弃用警告消失了。为什么这么多 CMake 变量坚持这样缓存? set() 不够好吗?以及为什么我需要FORCE 缓存;甚至CACHE 还不够好? :|尝试用纯 Makefile 维护 libui 实在是太可惜了,但事实证明这太笨拙了,而 CMake 是大多数人想要的选择。 :/


当然,弃用警告已经消失了,但这并没有把我们带到那里,因为一些被重命名的常量被保留为static const 变量。这意味着我不能说

case NSKeyUp:

switch 声明中没有关于标准合规性的警告,因为在 C99 中技术上不允许这样做(const 只是对编译器的提示)并且我明确禁用 GNU 语言扩展(主要是个人偏好)。我也不认为它在 C++ 中是允许的(事实上,我很确定 C++11 出于这个原因引入了constexpr),但是一旦我确认我将在这个问题上提交一个雷达。我会在更新时提供更多详细信息。

感谢您在此期间提供的所有帮助!

【讨论】:

  • 您能举个例子吗?我只是设置了编译器标志ADD_COMPILE_OPTIONS(-mmacosx-version-min=10.10)SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.10" CACHE STRING "" FORCE),但没有任何改变。我使用 CMake 3.20.2。
猜你喜欢
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 2014-12-14
  • 1970-01-01
  • 2017-01-30
  • 1970-01-01
  • 2023-01-30
相关资源
最近更新 更多