Mac SDK:使用最新的SDK,但确保与早期部署目标的向后兼容性

问题描述 投票:14回答:6

与Apple一起更新OS X时一样,最新的XCode 4.4转储旧的(10.6)SDK,我发现自己需要使用10.7 SDK(或者我认为是10.8)并将我的部署目标设置为10.6以保持兼容性。

我更喜欢链接到较旧的SDK,因为我知道我不能错误地引入对尚不存在的API的调用。当我上次尝试逆向方法时,我发现自己经常做的事情。

我发现自己在做的是我使用XCode中的代码完成功能来选择像NSWorkspace这样的简单类的“正确”调用,然后在开发过程中一切正常,我忘了它,当我发布新版本时:Kaboum!整个应用程序在运行时在早期的OS X版本上爆炸;经常在那些难以到达的地方:-)

或者至少这是我几年前的情况。

当然,到目前为止,有一种方法可以:

  • 确保您不会引入部署目标中尚未提供的API调用,即使它们已在SDK中定义
  • 在构建或静态分析时检测此类调用

我确定我错过了什么,在某个地方的某个地方..请赐教!

最好的祝福,

坦率

xcode macos cocoa xcode4 sdk
6个回答
8
投票

当然,到目前为止,有一种方法可以:

  • 确保您不会引入部署目标中尚未提供的API调用,即使它们已在SDK中定义
  • 在构建或静态分析时检测此类调用

不,那里没有。是的,你应该打开雷达(bugreport.apple.com)。如果你愿意,你可以欺骗我的:rdar://11985733

是的,尽管Apple建议,唯一可行的解​​决方案是复制旧的SDK并链接它们。

我花了很长时间与Xcode团队讨论WWDC 2012上的这个问题。他们一致认为它已经坏了。目前没有计划修复它。升级雷达是我们如何影响Apple对这些事情的影响。


2
投票

我通常将SDK从旧版本复制到较新版本,这样如果我使用不支持的东西,编译器会惹我生气。

您也可以在调用一些您不确定的方法时查看快速帮助,例如在屏幕截图中,您可以看到launchApplicationAtURL方法仅适用于10.6


2
投票

我在iOS上也有这个烦人的问题。它实际上在iOS上更加烦人,因为用户必须将他们的设备与iTunes同步,并在发送崩溃报告之前启用崩溃报告发送,而不像Mac OS X那样你不需要做所有这些。最近,我设法添加了一个编译时检查,用于检查旧版SDK的API。我将首先解释我是如何首先为iOS做的,然后尝试帮助您在Mac OS X中使用这种技术。我不会为Mac atm编写太多代码,因此我只能从我的经验中指导您正确的方向使用iOS,但是一旦我下班回来,我会在今天晚些时候测试我的建议。


所以这就是我为iOS所做的:

我首先得到了我想要的旧版Simulator SDK。我可以通过下载包含所需SDK的旧Xcode 3(不是4个)版本来轻松获得此功能。

我接下来必须安装SDK。这不是太难,所以我不会在这里解释太多。但SDK存储在Packages文件夹中。此文件夹在早期的Xcode 3版本中清晰可见,但在更高版本中隐藏。您也可以通过终端轻松打开它。此外,在Xcode 4.3中更改Developer文件夹移动到Xcode.app之后,所以我必须将SDK安装到tmp文件夹中并自己将SDK移动到Xcode.app中。如果我打开它,我需要重启Xcode。

在那之后,我在你的项目中复制了我的debug配置并命名了它,在我的例子中,像iOS 4.3 API Check或类似的东西 - 并不重要。然后我将这个新配置的Base SDK更改为我安装的旧SDK。我安装的SDK没有列出,所以我不得不选择other并再次输入,在我的情况下,iphonesimulator4.3

最后,当我需要检查SDK的旧版本时,我将项目方案中Run <appname>.app的配置更改为我的iOS 4.3 API Check配置。我们去,针对iOS 4.3进行编译时检查。


至于Mac OS X,我相信你可以用同样的方法达到同样的目标。 Mac SDK没有模拟器,所以我认为常规SDK将适用于此。至于获取较旧的SDK,如果你仍然安装了Xcode 4.2(在Xcode 4.3更改后,Developer文件夹在Xcode.app中),那么你应该在那里找到10.6 SDK。如果你不这样做,我认为Apple与iOS有类似的东西,SDK下载可以在开发中心或互联网上的某个地方使用......

至于设置Base SDK,如果它没有列出,那么我认为名称是MacOSX10.6或你所追求的任何版本。

其他一切应该是相同的,但如前所述,我将在今天晚些时候测试这个方法并编辑我的答案以给出一个更明确的答案,但我想这个方法适用于Mac SDK。


2
投票

我还假设编译器会警告我有关部署目标操作系统版本的“太新”的API使用情况。但事实证明,默认情况下,编译器不会向您发出警告。其中一个原因可能是您仍然可以通过使用“respondsToSelector:”在运行时检查可用性来使用新API,例如,在较新的操作系统版本上,即使部署目标版本较旧时也是如此。你需要添加编译器选项-Wpartial-availability,它可以在Xcode 7.3+上获得(待确认),以获得“警告:'某些东西'是部分:在macOS 10.x中引入”警告信息。

使用Xcode 8.2.1在macOS 10.12.3上:

$ cat foo.m
#include <Foundation/Foundation.h>

BOOL foo()
{
    return [@"foo" containsString:@"bar"];
}

$ cc -mmacosx-version-min=10.9 -Wpartial-availability foo.m -c -o foo.o
foo.m:5:20: warning: 'containsString:' is partial: introduced in macOS 10.10 [-Wpartial-availability]
    return [@"foo" containsString:@"bar"];
                   ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSString.h:132:1: note: 
      'containsString:' has been explicitly marked partial here
- (BOOL)containsString:(NSString *)str NS_AVAILABLE(10_10, 8_0);
^
foo.m:5:20: note: explicitly redeclare 'containsString:' to silence this warning
    return [@"foo" containsString:@"bar"];
                   ^
1 warning generated.

另见:Is there a way for XCode to warn about new API calls?


0
投票

我通过黑客攻击Availability.h检查我的代码,让编译器将弱链接符号标记为警告/错误。在我目前的(Xcode 5 / llvm)版本中,我正在使用下面的代码。每当我使用iOS 6.0或更高版本中引入的符号时,它都会发出警告。我认为这是相当不言自明的。宏似乎需要在每次SDK更新时进行更新,因此请谨慎行事。哦,你也放弃了弃用警告,所以我只是偶尔使用它来仔细检查我的条件代码。

#undef __NSi_6_0
#define __NSi_6_0 deprecated=1.0
#undef __NSi_6_1
#define __NSi_6_1 deprecated=1.0
#undef __NSi_7_0
#define __NSi_7_0 deprecated=1.0

#undef __NSd_6_0
#define __NSd_6_0
#undef __NSd_6_1
#define __NSd_6_1
#undef __NSd_7_0
#define  __NSd_7_0

另见http://iphone.m20.nl/wp/2013/10/xcode-5-and-flagging-weak-linked-unavailable-symbols-from-a-newer-sdk/


0
投票

从Xcode 9开始,有一个构建设置完成此操作,打开警告-Wunguarded-availability和/或-Wunguarded-availability-new

前者在使用比部署目标更新的API时发出警告。后者仅在以类似方式使用比macOS 10.13或iOS 11更新的API时发出警告。

对于现有项目,前者默认为关闭,后者默认为打开。

此设置在Xcode的构建设置窗格中称为“无人看守的可用性”,您可以为所有版本选择“是”,“是”,或者从GUI中选择“否”。

有关更多详细信息,请参阅WWDC17会话411,“LLVM中的新功能”,https://developer.apple.com/videos/play/wwdc2017/411/

© www.soinside.com 2019 - 2024. All rights reserved.