Xcode 来自 Apple Silicon M1 的错误 'building for iOS Simulator, but linking in dylib built for iOS .. for architecture arm64' Mac

Xcode error 'building for iOS Simulator, but linking in dylib built for iOS .. for architecture arm64' from Apple Silicon M1 Mac

我有一个应用程序可以编译,运行在物理设备和 iOS 模拟器中使用英特尔处理器的旧 Macs 很好。

同样的应用程序也可以编译,并且 运行 可以从更新的 Apple Silicon Mac 使用 M1 处理器和 物理 iPhone 设备,但是它拒绝为iOS模拟器编译。

没有模拟器支持,调试周转时间会变得很长,所以我正在尝试解决这个问题。更不用说 Xcode 预览功能也不起作用,这很烦人。

我在没有做任何更改(但从 Intel Mac 移动到 M1 Mac)时遇到的第一个错误如下所示。

building for iOS Simulator, but linking in dylib built for iOS, file '/Users/andy/workspace/app/Pods/GoogleWebRTC/Frameworks/frameworks/WebRTC.framework/WebRTC' for architecture arm64

我使用的 Cocoapods 库是 GoogleWebRTC,根据 its doc,应该支持 arm64,所以我很困惑为什么会抛出上述错误。正如我之前所说,它在真实设备中编译得很好,我相信在 arm64 上 运行ning。

根据文档..

This pod contains the WebRTC iOS SDK in binary form. It is a dynamic library that contains the armv7, arm64 and x86_64 slices. Bitcode is not supported. Our currently provided API’s are Objective C only.

我在网上搜索 这个问题似乎有 2 个解决方法。

  1. 第一个是将arm64添加到Excluded Architectures
  2. 第二个选项是为 Release 构建标记 Build Active Architecture Only

即使我在 M1 Mac 上编译我的应用程序时,我也不完全明白以上是否必要,这是 运行ning 在 arm64 架构下,因为该解决方案似乎仅适用于对于不支持 arm64 模拟器的 Intel Mac,对于 Intel Mac,模拟器可能 运行ning 在 x86_64 中,而不是 arm64,所以解决方案 #1 不是适用于我的情况。

当我只调整第二个更改时,实际上没有任何更改并抛出相同的错误。

当我进行更改并尝试构建时,我现在在构建过程中遇到以下第二个错误。 (不是真的 100% 确定我是否解决了第一个错误/我可能通过调整两个更改在第一个错误之外引入了第二个错误)

Could not find module 'Lottie' for target 'x86_64-apple-ios-simulator'; found: arm64, arm64-apple-ios-simulator

我使用的第二个库是 lottie-ios,我使用 swift 包管理器将其引入。我想发生的事情是因为我在 iOS 模拟器的构建设置中排除了 arm64,Xcode 试图 运行 我在 x86_64 中的应用程序。但是,出于某种原因,运行ning 在 x86_64 中不支持库,并且会引发错误。我对是什么决定库是否可以在 x86_64 或 arm64 中 运行 没有太多见解,所以我无法深入研究这个问题。

我的结论是,出于某种原因,GoogleWebRTC 无法在 iOS 模拟器中使用 arm64 编译为 运行(与 its doc 所说的不同) ,并且 lottie-ios 无法在 iOS 模拟器中使用 x86_64 编译为 运行。所以在这种情况下我不能同时使用它们。

Q1。我想知道我可以做什么样的改变来解决这个问题...

当从 Intel Mac 编译时,应用程序在设备和模拟器中编译和 运行s 完美。当从 Apple Silicon Mac 编译时,应用程序编译并且 运行 在设备中正常。只是应用程序拒绝在 Apple Silicon Mac 的 iOS 模拟器中编译和 运行,我似乎无法弄清楚为什么。

Q2。如果没有可用的解决方案,我想首先了解为什么会发生这种情况。

我真的不希望再次购买旧的英特尔 Mac 只是为了在模拟器中运行。

回答我自己的问题,希望能帮助遇到类似问题的其他人。 (直到另一个用户添加了一个好的答案)

我发现 GoogleWebRTC 实际上需要根据其源代码库使用 x64 编译其源代码。

For builds targeting iOS devices, this should be set to either "arm" or "arm64", depending on the architecture of the device. For builds to run in the simulator, this should be set to "x64".

https://webrtc.github.io/webrtc-org/native-code/ios/

这一定是我收到以下错误的原因。

building for iOS Simulator, but linking in dylib built for iOS, file '/Users/andy/workspace/app/Pods/GoogleWebRTC/Frameworks/frameworks/WebRTC.framework/WebRTC' for architecture arm64

如果我错了请纠正我,但默认情况下,Apple M1 芯片中的 Xcode 运行ning 似乎会启动 iOS 模拟器 arm拱型。由于我的应用程序 运行 在 Intel Mac 的模拟器上表现良好,我现在做了以下解决方法。

  1. 退出 Xcode.
  2. 转到 Finder 并打开应用程序文件夹。
  3. 右键单击 Xcode 应用程序,select Get Info
  4. 在“Xcode 信息 Window”中勾选 Open using Rosetta
  5. 打开 Xcode 并重试 运行ning。

我需要做的就是让我的应用程序再次运行,它依赖于 arm 模拟器尚未完全支持的库。 (我相信在 Rosetta 模式下启动 Xcode 运行s 模拟器也在 x86 中......这解释了为什么在进行上述更改后一切正常)

很多在线资源(通常在 Nov/2020 上发布 M1 Mac 之前发布)谈论“将 arm64 添加到 Excluded Architectures”,但该解决方案似乎仅适用于英特尔 Mac,而不是 M1 Mac,因为我不需要进行更改即可使一切正常运行。

当然,在 Rosetta 模式下 运行ning Xcode 不是永久解决方案,Xcode 会减慢一点点,但它是一个临时解决方案,可以让事情顺利进行如果您正在使用的库之一在 arm64 模拟器中 运行nable.. 但是

退出Xcode。 转到 Finder 并打开应用程序文件夹。 右键单击 Xcode 应用程序,select 获取信息 在“Xcode Info Window”中勾选 Open using Rosetta。 打开 Xcode 并重试 运行。enter image description here

Apple 不支持通过 Rosetta 到 运行 Xcode 模拟器。有很多错误。

最好通过 Cocoapods 隔离有问题的库并只将它们构建到受支持的架构。

post_install do |installer|  
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      # Targets that do not support m1 simulator
      if ['Lib1', 'Lib2'].include? target.name
        config.build_settings['ARCHS[sdk=iphonesimulator*]'] = 'x86_64'
      end
    end
  end
end

然后您可以使用 #if 隔离使用此框架的代码。

#if !((arch(arm64)) && targetEnvironment(simulator))
// Not M1
#else
// M1
#endif

P.S。 这是 create pod with any framework.

的方法

我找到了修复程序 here 感谢@Narlei

1- 在项目中设置排除 arm64 架构

2- 这在你的 Podfile 的末尾

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
  end
end