我正在尝试在Xcode 12(beta 5)中构建一个大型(正在开发Xcode 11!)项目,为iOS 14做准备。代码库以前是Objective-C中的,但现在它同时包含Objective-C和Swift,并使用Objective-C或Swift的pod。
我已经推出了支持Xcode 12的CocoaPods新测试版(目前为1.10.0.beta 2)。
Pod安装成功。当我进行构建时,在pod框架上出现以下错误:
为iOS模拟器构建,但链接到为iOS构建的对象文件中,用于体系结构arm64
以及可能的错误:
无法加载目标“arm64-apple-ios11.0”的标准库
当我在框架上运行lipo-info时,它有:armv7s armv7 i386 x86_64 arm64。
此前,该项目的有效架构设置为:armv7、armv7s和arm64。
在Xcode 12中,根据苹果的文档,该设置将消失。架构设置为$(ARCH_STANDARD)。我在排除的架构中没有任何设置。
这里可能发生了什么?我还没能用一个更简单的项目重现这一点。
TL;博士;
将库/应用程序的“仅构建活动体系结构(Only_Active_ARCH)”设置为“是”,即使在发布模式下也是如此。
在试图确定问题的根本原因时,我意识到Xcode 12的一些有趣的事实。
Xcode 12实际上是Apple silicon的垫脚石,遗憾的是(当答案写出来时)它还没有问世。但有了这个平台,我们将得到一个基于arm64的macOS,模拟器也将在arm64架构上运行,这与目前基于Intel的x86_64架构不同。Xcode通常依赖于“运行目标”来构建其库/应用程序。因此,当模拟器被选择为“运行目的地”时,它会为可用的模拟器架构构建应用程序,而当设备被选为“运行目标”时,则会为设备支持的架构(arm*)构建应用程序。Xcode 12+构建系统中的xcodebuild认为arm64是模拟器支持Apple silicon的有效架构。因此,当选择模拟器作为运行目标时,它也可以尝试编译/链接基于arm64的模拟器的libs/apps。因此,它以<architecture>-<os>-<sdk>-<destination>格式发送clang(++)一些目标标志,如arm64-apple-ios13.0-simulator,clang尝试构建/链接基于arm64的模拟器,最终在基于Intel的Mac上失败。但xcodebuild仅对Release版本尝试此操作。为什么?因为,对于“Release”配置,“Build Active Architecture Only(Only_Active_ARCH)”构建设置通常设置为“No”。这意味着xcodebuild将尝试为发布版本的选定运行目标构建libs/apps的所有架构变体。对于模拟器运行目的地,现在它将包括x86_64和arm64,因为Xcode 12+中的arm64也是模拟器支持Apple silicon的支持架构。
简单地说,Xcode在尝试命令行xcodebuild(默认为releasebuild,请参见项目设置的常规选项卡)或其他方式并尝试构建运行目标支持的所有体系结构变体时,将无法构建应用程序。因此,解决此问题的一个简单方法是在库/应用程序中将“仅构建活动体系结构(Only_Active_ARCH)”设置为“是”,即使在发布模式下也是如此。
如果库包含为Pods,并且您可以访问.podspec,则可以简单地设置:
spec.pod_target_xcconfig={“ONLY_ACTIVE_ARCH”=>“是”}
spec_user_target_xcconfig={'ONLY_ACTIVE_ARCH'=>'YES'}#否推荐
我个人不喜欢第二行,因为pods不应该污染目标项目,而且它本身可以在目标设置中被覆盖。因此,消费者项目应该负责以某种方式覆盖设置。然而,这可能是成功的柱脚过梁所必需的。
但是,如果您没有访问.podspec的权限,您可以在安装pod期间始终更新设置:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings["ONLY_ACTIVE_ARCH"] = "YES"
end
end
end
我担心的一件事是,当我们实际归档库和应用程序时,这会产生什么影响。在归档过程中,应用程序通常采用“Release”配置,因为这将创建一个只考虑当前运行目标的活动体系结构的版本构建,因此使用这种方法,我们可能会从目标构建中丢失armv7、armv7等的切片。然而,我注意到文档中说(在所附图片中突出显示),当我们选择“通用iOS设备/任何设备”作为运行目标时,将忽略此设置,因为它没有定义任何特定的架构。所以我想,如果我们将我们的应用程序归档,并将其作为跑步目的地,我们应该会很好。
在尝试了这个问题的几乎所有答案并阅读了苹果开发者论坛后,我发现只有一个解决方案适合我。
我正在构建一个通用框架,该框架在Swift应用程序中使用。我无法在没有架构错误的情况下构建模拟器。
在我的框架项目中,我在构建阶段有一个通用框架任务。如果你是这样的话:
在构建阶段将以下内容添加到xcodebuild任务中:EXCLUDED_ARCHS=“arm64”
接下来,您必须更改以下项目生成设置:
删除VALID_ARCHS用户定义的设置将ONLY_ACTIVE_ARCH设置为YES***
***如果您正在开发一个框架,并且有一个演示应用程序,则必须在两个项目中都启用此设置。
我了解arm64和Xcode 12的问题,我能够通过排除iPhone模拟器的arm64架构或通过为发布方案设置ONLY_ACTIVE_ARCH来解决构建问题。然而,我仍然有问题使用pod repo推送来推送我的框架。
我发现podspec中的设置s.pod_target_xcconfig不会将此设置应用于同一podspec中定义的依赖项。我可以在Cocoapods在验证期间生成的虚拟App项目中看到它。Cocoapods验证正在运行模拟器的发布方案,当一个或多个依赖项不排除arm64或未设置为仅构建活动体系结构时,这将失败。
解决方案可以是强制Cocoapods在验证项目时添加安装后脚本,或者让它构建调试方案,因为调试方案只是构建活动体系结构。
我最终使用Xcode 11发布了我的pod以通过验证。您可以从developer.apple.com下载Xcode 11,将其作为Xcode11.app复制到Applications文件夹,然后使用sudo Xcode select--switch/Applications/Xcode11/app/Contents/developer进行切换。完成后不要忘记切换回来。
Xcode 13.2.1、macOS v12(蒙特雷)、目标iOS 14.0和CocoaPods 1.11.2
在包括LogRocket和/或Plaid时,我也遇到过类似的问题——它们是xcframework,在我的本地上运行良好,但它们不能建立在bitrise上。我尝试了以上所有答案:
不包括ARCHS臂64在Podfile中将ONLY_ACTIVE_ARCH设置为YES将工作空间验证为是在Podfile中将ARCHS[sdk=iphonesimulator*]设置为uname-m
它们都不起作用。
但通过指定目标iOS版本或将其删除,可以:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '14.0'
# OR
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
end
Xcode版本13.2.1和macOS Monterey 12.0.1
在切换到新的M1芯片系统后,几乎每个人都面临着与旧项目和吊舱相同的问题。
“在/Users//Desktop/iOS_app/Pods/iOS/framework/(CLSInternalReport.o)中,为iOS模拟器构建,但链接到为iOS构建的对象文件中,用于体系结构的文件'/Users/y/Desktop/_iOS_app/Pods/iOS/.framework/臂64“
我已经找到了一个非常有效的解决方案。
首先,对于所有建议为您的项目排除arm64的开发人员来说,它会工作。是的,它会编译,但在安装后,当您尝试打开它时,它会显示一个弹出窗口,显示消息“此应用程序的开发人员需要更新它才能使用此版本的iOS”。这是因为根据苹果公司的说法,“在iOS 11及更高版本中,所有应用程序都使用64位架构”,如果您将arm64排除在项目之外,则不会在iOS 11或更高版本上打开应用程序。
因此,与其选择整个项目,不如将模拟器的架构排除在arm64之外。
步骤:在项目文件之上,选择目标>构建设置>体系结构>排除的体系结构。现在添加选择“任何iOS模拟器SDK”并给它一个值arm64。
参考见下图。