CocoaPods校验的报错
最近,我执行pod lib lint --verbose --no-clean --verbose --allow-warnings
校验CocoaPods,结果却是一个以前没有见过的错误:
ld: building for iOS Simulator, but linking in dylib built for iOS, file '/var/folders/pn/4cgjvr1j7mzbnl55pfnzlgr00000gq/T/CocoaPods-Lint-20200929-48311-11st24n-DroneKit/Pods/DJI-SDK-iOS/iOS_Mobile_SDK/DJISDK.framework/DJISDK' for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
GitHub Issue:https://github.com/CocoaPods/CocoaPods/issues/10104
CocoaPods打包的报错
在执行pod package
时也出现了跟arm64架构有关的错误
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: Pods/build/package.a and Pods/build-sim/package.a have the same architectures (arm64) and can't be in the same fat output file
Github Issue:https://github.com/CocoaPods/cocoapods-packager/issues/259
出现问题的原因
根据这篇Medium的文章,由于我们的项目对于架构的设置是默认的:ARCHS_STANDARD
,随着Xcode 12 的正式发布,苹果在这个字段里面加入了arm64架构的模拟器,⚠️注意,是模拟器。
随着苹果的Apple Silicon计划和M1芯片的推出,Xcode为了适配arm64架构的Mac,让M1的用户可以在模拟器上调试,苹果加入了arm64架构模拟器的字段,导致了CocoaPods校验和打包的报错。
详细的原因
至于详细的原因,这篇StackOverFLow的回答给出了答案,下面粘贴部分内容并翻译(大部分使用DeepL翻译后校对):
The Build Settings editor no longer includes the Valid Architectures build setting "VALID ARCHS", and its use is discouraged. Instead, there is a new Excluded Architectures build setting (EXCLUDED ARCHS)
构建设置编辑器不再包含有效的架构构建设置 "VALID ARCHS",并且不鼓励使用它。取而代之的是一个新的排除架构构建设置(EXCLUDED ARCHS)。
Xcode 12 is actually the stepping stone for Apple Silicon which unfortunately is not yet available. But with that platform, we are gonna get arm64 based macOS where simulators will also run on arm64 architecture unlike the present Intel-based x86_64 architecture.
Xcode 12其实是苹果Silicon的垫脚石,可惜目前还没有上市。但有了这个平台,我们使用基于arm64的macOS,其中模拟器也将运行在arm64架构上,而不像现在基于英特尔的x86_64架构。
Xcode usually depends on the "Run Destination" to build its libraries/apps. So when a simulator is chosen as the "Run Destination", it builds the app for available simulator architectures and when a device is chosen as the "Run Destination" it builds for the architecture that the device supports (arm*).
Xcode通常依赖于 "运行目的地 (Run Destination)"来构建它的库/应用程序。因此,当模拟器被选择为 "运行目的地(Run Destination) "时,它会为可用的模拟器架构构建应用程序,而当设备被选择为 "运行目的地 "时,它会为设备支持的架构(arm*)构建。
xcodebuild, in the Xcode 12+ build system, considers arm64 as a valid architecture for the simulator. So when a simulator is chosen as the run destination, it can potentially try to compile/link your libs/apps against arm64 based simulators as well (not available yet). So it sends clang(++) some -target flag like arm64-apple-ios13.0-simulator in --- format and clang tries to build/link against arm64 based simulator that eventually fails on Intel-based mac.
xcodebuild,在Xcode 12+构建系统中,认为arm64是模拟器的有效架构。所以当一个模拟器被选择为运行目标时,它有可能会尝试对基于arm64的模拟器也编译/链接你的lib/apps(目前还没有)(2021.3.16注:已经有了)。因此,它向clang(++)发送一些-target标志,如arm64-apple-ios13.0-simulator,格式为----,然后clang就会尝试对基于arm64的模拟器进行编译/链接,最终在基于Intel的Mac上失败。
But xcodebuild tries this only for Release builds. Why? Because, "Build Active Architecture Only (ONLY_ACTIVE_ARCH)" build settings is usually set to "No" for the "Release" configuration only. And that means xcodebuild will try to build all architectural variants of your libs/apps for the selected run destination for release builds. And for the Simulator run destination, it will includes both x86_64 and arm64 now on, since arm64 in Xcode 12+ is also a supported architecture for simulators to support Apple Silicon.
但xcodebuild只在Release构建时才会尝试这样做。为什么呢?因为,"仅构建活动架构(ONLY_ACTIVE_ARCH) "构建设置通常只在 "Release "配置中设置为 "No"。这意味着xcodebuild将尝试为所选的运行目标构建发行版构建的所有lib/apps的架构变体。对于模拟器的运行目标,它将包括x86_64和arm64,因为在Xcode 12+中arm64也是模拟器支持的架构,以支持Apple Silicon。
Simply putting, Xcode will fail to build your app anytime it tries the command line, xcodebuild, (which defaults to release build, see the general tab of your project setting) or otherwise in release mode. So a simple workaround to this issue is to set "Build Active Architecture Only (ONLY_ACTIVE_ARCH)" to Yes in your libraries/apps, even for release mode.
简单地说,Xcode在任何时候尝试命令行、xcodebuild(默认为release build,见项目设置的general选项卡)或其他release模式下,都会导致你的应用程序构建失败。所以这个问题的一个简单的变通方法就是在你的库/应用中把 "仅构建活动架构(ONLY_ACTIVE_ARCH)"设置为 "是",即使是发布模式。
解决方案
目前似乎只有临时的解决方案,就是在podspec文件里添加两行绕过arm64架构模拟器的配置:
s.pod_target_xcconfig = {
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64'
}
s.user_target_xcconfig = {
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64'
}
根据大家的描述:
This will eventually be a problem when we are running on Apple Silicon Macs, but for now we'll be OK.
一个疑问
如果在podspec上设置绕开了arm64架构的模拟器,那开发者不就没有办法在M1的Mac上面使用模拟器调试了吗?该怎么样让自己的库适配arm64的模拟器呢?
网友评论