Xcode在为iOS模拟器构建时,却将一个为iOS构建的目标文件链接进来,架构为'arm64'。

895
我正在尝试在Xcode 12(beta 5)中构建一个大型项目(并且可以在Xcode 11上工作!)以准备iOS 14。该代码库以前是Objective-C,但现在包含Objective-C和Swift,并且还使用了Objective-C和/或Swift的pods。
我已经拉取了支持Xcode 12的新beta版CocoaPods(当前版本为1.10.0.beta 2)。
Pod install成功。当我进行构建时,我会在一个pod framework上得到以下错误:
“building for iOS Simulator, but linking in object file built for iOS, for architecture arm64”
可能还会出现错误:
“Unable to load standard library for target 'arm64-apple-ios11.0'”
当我在framework上运行lipo -info时,它具有:armv7s armv7 i386 x86_64 arm64。
以前,该项目将有效架构设置为:armv7、armv7s和arm64。
在Xcode 12中,根据苹果的文档,该设置消失了。架构设置为$(ARCHS_STANDARD)。我没有在排除的架构中设置任何内容。
这里可能出了什么问题?我还没有能够用更简单的项目重现这个错误。

3
这对我有用:https://dev59.com/I2Af5IYBdhLWcg3wMwQ9#64016147 - Narendar Singh Saini
3
请查看这篇文章:https://milanpanchal24.medium.com/xcode-12-building-for-ios-simulator-but-linking-in-object-file-built-for-ios-file-for-8c0cc28ec832?sk=adfc406c1f4fae81155cd4a49ec7edb4 - MilanPanchal
39
我有一台苹果芯片 M1 的电脑,但仍然遇到了 arm64 错误。为什么会出现这种情况? - Adrienne
4
我也是,使用的是苹果M1芯片,刚开始出现这个问题。我找到的所有解决方案似乎都不起作用...有人有任何想法吗?正在为iOS模拟器构建,但链接了为iOS构建的目标文件,文件'/.............../Pods/GoogleMaps/Maps/Frameworks/GoogleMapsCore.framework/GoogleMapsCore'针对架构arm64。 - martin010
21
TLDR; XCode 13 + Apple M1: (1)使用Rosetta打开Xcode(应用程序->右键单击Xcode->获取信息->勾选使用Rosetta打开)。 (2)将arm64添加到排除的架构中(构建设置)。 (3)清理构建文件夹。 (4)运行应用程序。 - Ryan Cocuzzo
显示剩余10条评论
65个回答

1283

基本上,你需要从你的项目和Pod项目中排除模拟器架构中的arm64

  • 为此,请导航到您的项目的Build Settings并将值为arm64的添加到Excluded Architecture内。

    Enter image description here

或者

  • 如果您正在使用自定义的XCConfig文件,则可以简单地添加此行以排除模拟器架构。

    EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64
    

    然后

    您需要对Pod项目执行同样的操作,直到所有Cocoa Pod供应商都在其Podspec中添加以下内容。

    s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
    s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
    

    您可以在Pod项目的 Build Settings 中手动添加 Excluded Architecture ,但是当您使用 pod install 时,它将被覆盖。

    取而代之的是,您可以在您的 Podfile 中添加此代码片段。每次运行 pod install 时,它都会编写必要的 Build Settings

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

12
这里关于 CocoaPods 的额外细节很不错。请注意,在 EXCLUDED_ARCHS 后面没有 [sdk=iphonesimulator*],当构建实际设备时,XCode 将无法找到你的 pods,因为没有任何一个 pod 会为 arm64 构建。 - mwu
19
对我有用!请注意,由于flipper,在大多数Podfiles中已经存在一个“post_install do |installer|”部分。将内部部分 installer.pods_project.build_configurations.each do |config| config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64" end 粘贴到 flipper_post_install(installer) 行后面。 - Ramon Vermeulen
39
我正在为iOS Simulator构建,但链接了在macOS上构建的目标文件,架构为x86_64。如何修复? - Sazzad Hissain Khan
22
有时这样做可能会起作用,但实际上是错误且有缺陷的。在模拟器上为arm64排除EXCLUDED_ARCHS意味着使用Apple Silicon Mac的人将无法使用您的框架。我实际上解决这个问题的方法是根据https://dev59.com/7lIG5IYBdhLWcg3wnS49#63714000清除VALID_ARCHS。 - Orion Edwards
4
这不是一个答案,而是一个临时解决方案。你需要联系你的依赖供应商,要求他们提供包含arm64模拟器版本的正确的XCFrameworks。如果排除arm64模拟器版本,会严重影响M1设备上的模拟器性能。 - Tony Arnold
显示剩余35条评论

285

TL;DR;

将库/应用程序的“仅构建活动架构(ONLY_ACTIVE_ARCH)”设置为,即使是在发布模式下也要这样做。


在尝试确定问题根本原因时,我意识到关于Xcode 12的一些有趣事实。
  1. Xcode 12实际上是Apple silicon的跳板,但遗憾的是它还没有推出(当此答案编写时)。但是,通过该平台,我们将获得基于arm64的macOS,其中模拟器也将在arm64架构上运行,而不像现在的基于Intel的x86_64架构。
  2. Xcode通常依赖于“运行目标”来构建其库/应用程序。因此,当选择模拟器作为“运行目标”时,它会为可用的模拟器架构构建应用程序,当选择设备作为“运行目标”时,它会为设备支持的架构(arm*)构建。
  3. Xcode 12+构建系统中的xcodebuildarm64视为模拟器支持Apple silicon的有效架构。因此,当选择模拟器作为运行目标时,它可能会尝试编译/链接您的库/应用程序针对arm64基础模拟器,因此会向clang(++)发送一些-target标志,例如arm64-apple-ios13.0-simulator,格式为<architecture>-<os>-<sdk>-<destination>,clang尝试构建/链接针对基于arm64的模拟器,最终在基于Intel的Mac上失败。
  4. 但是,xcodebuild仅尝试此操作以进行发布构建。为什么呢?因为“仅构建活动架构(ONLY_ACTIVE_ARCH)”构建设置通常仅针对“发布”配置设置为“否”。这意味着xcodebuild将尝试为所选运行目标构建库/应用程序的所有架构变体,对于模拟器运行目标,从现在开始它将包括x86_64arm64,因为Xcode 12+中的arm64也是模拟器支持Apple silicon的一种受支持的架构。
简单地说,无论何时Xcode尝试命令行xcodebuild(默认为发布构建,请参见项目设置的常规选项卡)或其他方式,并且尝试构建运行目标支持的所有架构变体,都会导致Xcode无法构建您的应用程序。因此,解决此问题的简单方法是在库/应用程序中将“仅构建活动架构(ONLY_ACTIVE_ARCH)”设置为,即使在发布模式下也是如此。

Enter image description here

Enter image description here

如果库被包含为Pods并且您可以访问.podspec,则可以简单地设置:
spec.pod_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'YES'}
spec.user_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'YES'} #不推荐
个人而言,我不喜欢第二行,因为Pods不应该污染目标项目,并且它可能会在目标设置中被覆盖。因此,由消费者项目通过某种方式覆盖设置是其责任。但是,这可能是podspecs成功进行linting所必需的
然而,如果您无法访问.podspec,则始终可以在安装Pods期间更新设置:
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

我担心的是,当我们实际归档库和应用程序时,会有什么影响。在归档应用程序时,通常采用“发布”配置,并且由于这将创建一个发布版本,只考虑当前运行目标的活动架构,采用这种方法,我们可能会失去目标构建中armv7、armv7s等切片。但是,我注意到文档(附图中突出显示)说,当我们选择“通用iOS设备/任何设备”作为运行目标时,将忽略此设置,因为它不定义任何特定的架构。因此,如果我们选择该运行目标归档应用程序,应该没问题。

7
这真是苹果意料之外的变化,让我花了半天时间才明白。我觉得苹果应该补偿一下 :)。这不是一个已记录的更新(至少据我所知),肯定会影响到所有升级到Xcode 12的人。我只希望每个人在了解基本情况后都能找到自己的方法来解决它。 - Ayan Sengupta
2
如果多个Pod规范使用user_target_xcconfig,并且值不完全匹配,CocoaPods将发出警告,如此[!] Can't merge user_target_xcconfig for pod targets: [... list of pods ...]. Singular build setting EXCLUDED_ARCHS[sdk=<...>] has different values. Podspec语法参考说这个属性是“不推荐使用”的https://guides.cocoapods.org/syntax/podspec.html#user_target_xcconfig。因此,请不要使用`user_target_xcconfig`来避免许多开发人员的麻烦。 - leberwurstsaft
2
没错!我想我已经在我的回答中提到了这一点。 - Ayan Sengupta
3
最终我成功地通过在pod_target_xcconfig中使用“EXCLUDED_ARCHS[sdk=iphonesimulator*]” => “arm64”来解决问题,但仅适用于存在问题的pod(其中包含一个预构建库)和依赖于该问题pod的单个pod。其他所有内容都保持不变。我决定采用这种方法而不是使用active arch solution。 - Airsource Ltd
2
这是在 Xcode >12 上建立模拟器时在基于英特尔的 Mac 上的好的解决方法,提示 Xcode 我们正在为具有 x86_64 架构的模拟器建立。不幸的是,它在 M1 和模拟器上不起作用(在其中,您可以通过 Rosetta 运行 Xcode 并包含 Ayan Sengupta 建议的内容)。正确的答案确实由 Tony Arnold 完成 - 它完全与在您的 Pod 中为模拟器拥有适当的 ARM 片段(和 XCFramework 转换)有关,并且应该由 Pod 的供应商完成。 - Erkki Nokso-Koivisto
显示剩余24条评论

158

14
我正在测试Release模式,所以我也必须将其添加到Release中。 - MujtabaFR
这让我克服了最初的构建失败,但在此之后,有30多个新的明亮红色错误出现在多个包中。 - slothstronaut
7
这对我有用,但只适用于构建arm64;模拟器不起作用。小抱怨一下:xCode太荒谬了,占用12.5 GB空间,拥有大量的pods。与这种经历相比,为Android构建轻而易举。 - tyler.frankenstein
8
这在 M1 Mac 上不起作用。 - atineoSE
2
我只需要这个适用于M1 Mac,它可以正常工作(无需Rosetta; 使用Rosetta我根本没有这个问题)对我来说,答案在我尝试编译的项目中
  1. 架构是标准的
  2. 构建活动为NO
  3. 排除是Debug-> Any iOS Sim SDK-> arm64,但所有其他插槽都为空
希望这也能帮助其他人。
- Dan Rosenstark
显示剩余4条评论

120
提议的答案已经过时/不正确。
你应该首先尝试更新CocoaPods和你的库/应用程序的依赖项,如果这样做不起作用,那么请联系你正在使用的任何依赖项的供应商,看看他们是否正在更新以添加对M1 Mac上的arm64模拟器切片的支持。
这里有很多被标记为正确的答案建议你将arm64从受支持的架构列表中排除。这最多只是一个非常临时的解决方法,最坏的情况是它会将这个问题传播给你库的其他用户。如果你排除了arm64模拟器切片,那么在模拟器中开发的应用程序将会受到性能影响(这反过来可能会导致你在开发惊人的想法时缩短闪亮新M1套件的电池寿命)。

5
没错,排除或包含架构的操作只适用于基于i386的计算机。 - elfenlaid
1
告诉谷歌吧,他们仍然不支持SPM。这可能需要几年时间。 - Beau Nouvelle
4
这个答案应该是正确的被接受的答案。@BeauNouvelle最近谷歌开源了许多他们的SDK(比如GoogleSignIn),现在支持xcframework和arm64模拟器切片;) - Buju
1
我同意,这是正确的答案,但有时你必须处理遗留问题。在英特尔上,我不得不采用@AyanSengupta的答案才能测试我的调试构建。 - Martin Braun
1
这是正确的,但不幸的是对于未维护的项目仍然没有提供可行的替代方案。 - Pranav Kasetti

78

Xcode 12已经移除了“Valid Architectures”构建设置。如果您在此构建设置中有值,则会导致问题,需要将其删除。

我通过将“Valid Architectures”构建设置作为用户定义的构建设置添加回去(不带任何值),运行项目(失败后),然后删除“Valid Architectures”构建设置,从而“清除了”它。之后,我就能在模拟器上运行了。

我的“Architectures”构建设置为“标准架构”。

您可以从“Build Settings”的加号按钮中添加用户定义的设置:

用户定义的设置


15
这应该是被采纳的答案。确保选中应用程序项目而不是目标,否则您将无法从构建设置中删除VALID_ARCHS。 :) - Bionicle
2
@trishcode 即使我已经尝试了这个方法,但我仍然在使用Xcode12 beta4时遇到同样的错误,请问是否有其他解决方案? - Sivakrishna Perla
3
如果您可以在Xcode 11中打开该项目,那么您可以准确地看到使用哪些目标架构。您甚至可以在Xcode 11中清除设置,然后再在Xcode 12中尝试该项目。如果您仍需要解决方法,并且在嵌入式框架上出现错误,则SlashDevSlashGnoll的答案应该有效。如果您需要解决方法,并且在Cocoapod上出现错误,请在Podfile的安装后排除arm64架构。 - trishcode
2
@trishcode 谢谢,将arm64设置为排除架构并删除VALID_ARCHS起了作用。 - Sivakrishna Perla
1
如果我删除VALID_ARCHS并将arm64添加到排除的架构中,我会得到以下错误 -检查依赖项 没有要编译的架构(ARCHS = arm64 x86_64,VALID_ARCHS =,EXCLUDED_ARCHS =( arm64 ))。 - nOOb iOS
显示剩余8条评论

71

所有答案中的隐藏宝石

我已经在主项目的目标中更改了“排除架构”,但未更改PODS项目的设置。这是一个真正的隐藏宝石。我已经困扰这个问题几个星期了。

在PODS项目中排除arm64


1
这会影响某些设备的生产构建吗? - Mohamed Abdou
@MohamedAbdou arm64 用于物理设备,因此我认为在尝试在真实的 iPhone 上模拟它时可能会出现冲突。无论如何,您可以尝试使用它,并且在任何情况下,您都可以将 arm64 作为排除架构进行删除。对于实际的生产和发布,我建议您在物理和虚拟设备上成功模拟它并使用这些设置进行发布。 - Tomas Ward
2
不是完美的答案,但现在你的项目在M1和模拟器上都无法编译,因为所有的pod都被排除了。 - Erkki Nokso-Koivisto
请记得为项目设置排除的架构,而不是目标,以便所有目标都继承了排除的架构设置。 - Pranav Kasetti
实际上,当您在真实设备上测试时,它会在生产中出现错误。它将显示错误消息“此应用程序的开发者需要更新以与此版本的iOS兼容”。这是因为根据苹果公司的规定,“在iOS 11及更高版本中,所有应用程序都使用64位架构”,因此,如果您在主项目中排除arm64,则无法在真实设备上打开该应用程序。因此,要解决此问题,您只需仅在模拟器中排除arm64,它将适用于包括M1或M2在内的所有机器。 - azeem usmani

53

简单解决方法

  1. 右键点击应用程序文件夹中的Xcode
  2. 获取信息
  3. 选择“使用Rosetta打开”

运行。

Xcode获取信息


4
没问题!当我们将 Cordova 项目(包括 Firebase 在内的许多插件)迁移到 M1 Mac 上时,出现了这个错误,这已经足够让我感到困扰了。 - pauloya
6
这是在苹果M1处理器上唯一奏效的答案。 - instanceof
1
这是我在 M1 和 xCode 13 上唯一有效的答案。其他建议的选项在 xCode 13 中甚至不存在。 - Murilo
11
现在情况不太好,你正在使用Rosetta模拟器运行Xcode,这意味着你的东西运行得比较慢。 - Erkki Nokso-Koivisto
4
看起来在Xcode 14.3中不再适用。我目前同时安装了14.2和14.3两个版本。前者有“使用Rosetta打开”的选项,而后者没有。 - Cruinh
显示剩余2条评论

47

Xcode 12.3

我通过将“验证工作区”设置为“是”来解决了这个问题。

输入图片描述


解决了我的问题。最简单的修复方式!我很高兴问题得到解决,但是有人能解释一下这个修复方式是如何解决问题的吗? - njdeveloper
这解决了我在 Xcode 12.5.1 上的 React Native 项目问题。谢谢! - Brian
7
它的作用是什么?它为什么有效?最好更新你的回答。请注意,不要使用“编辑”、“更新”或类似的字样 - 回答应该看起来像今天写的一样。 - Peter Mortensen
5
选项在我的Xcode 14.0.1上没有显示。 - Jalil
@Jalil 或许可以看一下 https://developer.apple.com/documentation/technotes/tn3117-resolving-build-errors-for-apple-silicon - ReinstateMonica3167040
显示剩余3条评论

46
在尝试和搜索不同的解决方案后,我认为最安全的方法是在Podfile的末尾添加以下代码。
post_install do |pi|
   pi.pods_project.targets.each do |t|
       t.build_configurations.each do |bc|
          bc.build_settings['ARCHS[sdk=iphonesimulator*]'] =  `uname -m`
       end
   end
end

这样做只能覆盖iOS模拟器的编译器架构,而不是您当前CPU的架构。与其他方法相比,这种解决方案也适用于搭载Apple Silicon芯片的电脑。


23
很高兴看到有人理解这个问题,而不是只是建议移除iOS模拟器的Apple Silicon支持。 - Camsoft
1
对于苹果芯片,这是唯一可行的选择。 - Szymon Kowaliński

43

前言

当你构建一个应用程序时,你需要为特定的“平台”和“CPU架构”组合进行构建。

iOS平台:

  • iOS设备 "generic/platform=iOS"
  • 模拟器 "generic/platform=iOS Simulator"

注意:还有很多其他平台。为了简洁起见,我只关注iOS平台。其他还有macOS、watchOS、tvOS、visionOS平台。

CPU架构:

  • arm64
  • x86_64

这是因为macOS与iOS以及iOS模拟器使用不同的库。详见在构建iOS设备和模拟器时有什么不同之处?

而不同的CPU架构使用不同的CPU指令。

这意味着构建的二进制文件和运行环境(设备/模拟器)需要匹配。否则,操作系统上可能缺少某些系统库,或者无法处理CPU指令。
你是否总是构建同一组合?
不是的。如果你使用的是“Release”配置,那么你将为“arm64”和“x86_64”架构同时存档你的产品。
在存档过程中(通常在CI/CD中),会选择模拟器架构,导致一些问题。
然而,对于物理设备上的“Debug”构建,不会尝试为不同的平台或架构构建。这是因为它优先考虑“开发速度”而不是“完全正确性”。
默认的Xcode“ONLY_ACTIVE_ARCH”设置如下:

enter image description here

我有一台Intel MacBook。如果我不排除任何架构和平台,会发生什么?
- 如果你正在构建一个调试配置,那么它只会构建目标平台的CPU架构。意思是: - 如果你正在构建到你的iPhone上,你只需要支持ARM64架构。 - 如果你正在构建到模拟器上,你只需要支持X86_64架构。
- 如果你正在构建一个发布配置,那么它将: - 构建适用于两个平台和所有可能的架构。
我有一台M1 MacBook。如果我不排除任何架构和平台,会发生什么?
如果你正在构建一个调试配置,那么它只会构建目标平台的CPU架构。意思是: - 如果你正在构建到你的iPhone上,你只需要支持ARM64。 - 如果你正在构建到模拟器上,你只需要支持ARM64。 - 或者你可以为Xcode启用Rosetta。在这种情况下,如果你正在构建到模拟器上,那么你还需要支持X86_64。
如果你正在构建一个发布配置,那么会: - 构建适用于两个平台和所有可能的架构。
为什么发布构建不同呢?
在积极开发过程中,你希望快速构建项目。没有必要构建你不需要使用的架构。这意味着如果你正在构建到设备上,那么你只想为该平台-架构组合构建。你不想构建其他组合。
然而,如果你要发布给其他人使用,那么因为你不想限制/指导他们如何构建你的应用程序,你就必须为所有可能的组合进行构建,并确保你的框架可以编译所有这些组合。
对于一个应用程序来说,为模拟器平台创建存档可能没有太多意义,但对于一个框架来说,你的消费者是另一个开发者。这个开发者将把你的框架构建到模拟器和真实设备中。因此,你需要支持两个平台和架构。
可可粉是问题的根源吗?
这要看情况。如果某个可可粉排除了某种架构,而你正试图为该架构构建应用程序,那么你必须要求可可粉的所有者不要排除它。
否则,如果你的所有可可粉都支持你要构建的特定平台/架构,那么问题就出在你自己编写的主机应用程序的代码中。
解决方案 更新支持Apple芯片的预编译库 如果错误信息中提到的库来自供应商,请参考更新来自供应商的预编译库。如果您拥有该库的源代码,请重新构建该库,以支持Apple芯片上的模拟器。了解如何构建XCFramework,请参阅创建多平台二进制框架捆绑包更新来自供应商的预编译库 如果产生构建错误的库是来自供应商的预编译库,并且您没有源代码,请联系供应商获取支持Apple芯片的更新XCFramework。如果供应商没有提供更新,可以临时使用EXCLUDED_ARCHS构建设置来排除模拟器SDK的arm64,如下图所示。请勿对其他SDK排除arm64。
来自文档

关于解决方案结果的更多问题:

如果我在“iOS模拟器”平台中排除ARM64会发生什么?

您将无法直接构建到M1模拟器中。您需要在M1上使用带有Rosetta的Xcode。这是一种折中方法,速度稍慢。

如果我在“iOS模拟器”平台中排除X86会发生什么?

您将无法构建到基于Intel的模拟器中。您也无法使用Rosetta构建到模拟器中。

如果我在“iOS”平台中排除ARM64会发生什么?

您将无法构建到物理设备中。也无法为其创建存档。这是一个糟糕的想法!

那么我应该排除架构吗?

努力使您的应用程序(包括所有预编译库)始终构建为由ARCHS构建设置的默认值定义的完整架构集。仅在最终发布的应用程序不在特定架构上使用目标功能的目标上使用EXCLUDED_ARCHS构建设置,例如仅在基于Intel的Mac计算机上支持传统功能的Mac应用程序。不要修改ARCHS构建设置以达到相同的结果。

此外,在大型团队中,一些开发人员可能使用M1芯片,而其他人可能使用较旧的基于Intel的MacBook。你永远不知道,也许将来会有一款M5 MacBook,它将具有独特的架构。因此,在设计项目/产品/框架时,考虑到如何使其与开发人员和库的使用者兼容是很重要的。
我们是否有一台搭载Intel X86_64的iOS设备?
这样的设备并不存在。
如何检查一个二进制文件?
你可以使用lipo、file或dyld_info。 lipo和file只提供架构信息。
dyld_info提供架构、平台信息等更多信息。
在终端应用程序二进制文件上进行简单检查的比较,请参见以下内容:

enter image description here

记住,在XCFramework中通常会有两个或更多的二进制文件。例如,如果我们只是使用lipo -info,我们必须对库的两个二进制文件都执行此操作:
lipo -info <path-to-binary>

在xcframework打包中的arm64目录中,我看到:
Non-fat file: /Users/mfaani/Video.xcframework/ios-arm64/Video.framework/Video is architecture: arm64

对于《模拟人生》游戏,我看到的是:
Architectures in the fat file: /Users/mfaani/Video.xcframework/ios-arm64_x86_64-simulator/Video.framework/Video are: x86_64 arm64 

你可以进入你的Mac的/Applications目录,右键点击任何应用程序,选择“显示包内容”,找到应用程序的相关二进制文件。然后使用lipo命令进行检查。
明确一点,无论是框架还是应用程序都可以使用lipo进行检查。同样,如果你访问模拟器上的构建文件夹,也可以检查二进制文件。
XCFramework和FAT二进制文件有什么区别?
- FAT二进制文件只是一个二进制文件,将两个(或更多)架构合并成一个单一的二进制文件。它之所以被称为FAT,是因为它变得臃肿。它的其他名称是“多架构二进制文件”或“通用二进制文件”。
- XCFramework只是一个结构化的文件夹,一个包装器。没有其他。它具有每个平台的不同文件夹。在每个文件夹中有一个二进制文件。该二进制文件可以是FAT二进制文件或非FAT(单一架构)二进制文件。
另外请注意,FAT二进制文件可以是框架或应用程序的二进制文件。XCFramework只是一个框架,它本身不是应用程序。
我的应用程序会因为其他我不需要的平台和架构组合而变得臃肿吗?
XCFramework不会使应用商店的提交变得臃肿,因为iOS设备的存档只会从与模拟器平台隔离的目录中选择每个框架。
然而,对于FAT二进制文件,由于它只是一个单一的二进制文件,您必须在提交到Apple商店之前对依赖项进行瘦身/切片。否则,您将收到以下错误消息:
不支持的架构。您的可执行文件包含不支持的架构“[x86_64,i386]”。
有关更多信息及其先前的解决方案,请参阅此处
要非常清楚,这是在Xcode 12之前的一个问题。但并不是每个项目设置都会遇到这个问题。只有当您有一些来自供应商的预编译依赖项(他们没有共享源代码,而只是共享了FAT二进制文件,以便您可以为设备和模拟器构建应用程序)时,您才会遇到这个问题。否则,如果您可以访问源代码,那么您的存档将不会包含针对两个体系结构的编译。它只会包含针对目标体系结构的二进制文件。
另请参阅这篇很棒的博客文章,了解更多细节和历史背景。
一个FAT的文件夹结构是什么样的?
它只是一个二进制文件,不是一个文件夹。该二进制文件适用于两个或更多体系结构。
一个xcframework的文件夹结构是什么样的?
ios-arm64
   - binary
ios-arm64_x86_64-simulator
   - (FAT) binary

如果要使XCFramework与Mac Catalyst配合使用,则文件夹结构应如下所示:
ios-arm64
    - binary
ios-arm64_x86_64-simulator
    - (FAT) binary
ios-x86_64-maccatalyst
    - binary

要获取更全面的可能平台列表,请参阅XCFrameworsk: 创建和集成xcframeworks以及它们与静态库和Swift包的合作演示

为什么我的供应商不支持ios-arm64-simulator?

可能有很多原因。

  • 迁移工作:通常情况下,他们编译时没有M1芯片,而且他们已经很久没有编译过了,如果他们重新编译,就需要做一些改变。你要明白,多年来没有需要新的架构-平台组合的需求。所以这是新的,不是每个人都理解。Swift现在与之前的版本ABI兼容,减少了框架所有者需要每次新的Swift发布时重新编译应用程序的需求。所以他们可以多年不需要重新编译...
  • 限制:预编译库依赖于另一个未编译为arm64-sim的预编译库。
  • 框架所有者没有苹果芯片(arm64)的机器。或者了解这些事情的人已经离开了公司。

还有什么要补充的吗?

确保您查看所有项目和目标以及Pod项目和Pod目标的设置。如果其中一个排除了某个架构,那么您无法为该架构构建应用程序。通常,这可能在您的Podfile中。
或者,如果Pod/框架在完全不同的存储库中进行编译,则您在那里设置的设置最为重要。
如果您注意到您收到的错误消息,应该很容易找到不支持的目标。一旦确定了目标,您就必须根据上面两段的注释确定何时/何地进行编译。

这个回答值得更多的赞。我在这里学到了很多。 - Marcel Alves
1
file /path/to/executable 是列出包含的指令集架构(ISA)切片的另一种选择。 - marc-medley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接