【问题标题】:Build static lib for Apple Silicon mac simulator为 Apple Silicon mac 模拟器构建静态库
【发布时间】:2021-03-14 22:48:33
【问题描述】:

我的静态库是用 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 命令:

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

Excluding 模拟器的 arm64 架构不是一个选项,因为在 Apple Silicon Mac 上具有 arm64 芯片组。

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

【问题讨论】:

    标签: ios static-libraries simulator arm64 silicon


    【解决方案1】:

    这是不可能的。

    您的模拟器二进制文件很可能只是 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)并且可以t 在同一个胖输出文件中

    无论您尝试使用成熟的二进制文件、未链接的目标文件还是静态库,都会发生这种情况。原因仅仅是胖文件格式的一个缺点:每个架构只能有一个切片。您需要 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 2platform 1。内核实际上会忽略这个加载命令,但dyld 不会。而且你也不能在一个二进制文件中有两个这样的加载命令,这也被认为是无效的。

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

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

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

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

    【讨论】:

    • 第四个选择是重新打包 lib 使其成为 xcframework 而不是普通的静态库;那么 xcframework 可以包含一个 ios 版本,其中包含与此相关的任何和所有架构,另一个版本的 ios 模拟器具有所有必要的架构,可能还有其他平台的版本,如 tvOS 和 watchOS,在那里你也会有架构重叠在一个普通的 lipo'd 静态库中。
    猜你喜欢
    • 2021-06-15
    • 1970-01-01
    • 2013-01-26
    • 2017-10-26
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多