4

我的静态库是用 xcodebuild 构建的,然后从模拟器和设备构建结果创建一个胖库。这是我的 xcodebuild 命令:

xcodebuild OTHER_CFLAGS="-fembed-bitcode" -configuration "iphoneos" -target "${LIB_NAME}Common" -sdk iphoneos

xcodebuild OTHER_CFLAGS="-fembed-bitcode" -configuration "iphonesimulator" -target "${LIB_NAME}Common" -sdk iphonesimulator

脂命令:

lipo -create "${DEVICE_DIR}/lib${LIB_NAME}Common.a" "${SIMULATOR_DIR}/lib${LIB_NAME}Common.a" -output "${INSTALL_DIR}/include/${LIB_NAME}/lib${LIB_NAME}Common.a"

在检查了 fat lib 中的架构后,我得到了:

$ lipo -info MyLibCommon.a 
Architectures in the fat file: MyLibCommon.a are: armv7 i386 x86_64 arm64

但是,当我通过 cocoapods 将 lib 添加到项目中并在模拟器上的 Apple 新 Silicon(带有 arm64 芯片组)上运行该项目时,出现以下编译错误:

building for iOS Simulator, but linking in object file built for iOS, file 'MyLibCommon.a' for architecture arm64

排除模拟器的 arm64 架构不是一种选择,因为在 Apple Silicon Mac 上具有 arm64 芯片组。

知道如何为 Apple Silicon Simulator 构建静态库吗?

4

1 回答 1

5

这是不可能的。

您的模拟器二进制文件很可能只是 i386 和 x86_64。如果你真的有 arm64 iOS 二进制文件和 arm64 macOS 二进制文件,lipo你会出错:

致命错误:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo:test.a.ios 和 test.a.macos 具有相同的架构(arm64)并且不能在相同的胖输出文件

无论您尝试使用成熟的二进制文件、未链接的目标文件还是静态库,都会发生这种情况。原因只是胖文件格式的一个缺点:每个架构只能有一个切片。你想要 arm64 iOS 和 Apple Silicon 模拟器,但那将是 2x arm64。

您可能很想尝试构建一个适用于 iOS 和 macOS 的单一瘦 arm64 二进制文件,但这也是不可能的。二进制文件是平台锁定的:

% otool -l test.o.ios | fgrep -B1 -A5 LC_BUILD_VERSION
Load command 1
       cmd LC_BUILD_VERSION
   cmdsize 24
  platform 2
       sdk 14.2
     minos 14.2
    ntools 0
% otool -l test.o.macos | fgrep -B1 -A5 LC_BUILD_VERSION
Load command 1
       cmd LC_BUILD_VERSION
   cmdsize 24
  platform 1
       sdk 11.0
     minos 11.0
    ntools 0

注意platform 2vs platform 1。内核实际上会忽略这个加载命令,但dyld不会。而且你也不能在一个二进制文件中有两个这样的加载命令,这也被认为是无效的。

您可能还记得Apple 的公告中提到过“Universal 2”文件格式或引用该格式的内容 - 但他们撒了谎。没有“通用 2”,它与十年前的文件格式完全相同。当他们说“通用 2”时,他们的意思是“将 arm64 切片添加到您的 macOS 二进制文件中”。

在我看来,你有三个选择:

  1. 您构建单独的库并保持名称分开。
  2. 您永远不会同时构建两种架构。
  3. 您为 x86_64 构建模拟器目标并在 Rosetta 下运行它。

后两者都在互联网上被广泛推荐,第 2 个是“仅为活动架构构建”,第 3 个是“排除 arm64”。鉴于预计 Rosetta 最终会消失,从长远来看,第三种选择似乎不可行。

于 2020-12-03T02:10:10.383 回答