从Xcode中的动态库中剥离不需要的架构 Submit to App Store issues: Unsupported Architecture X86_64, i386

从Xcode中的动态库中剥离不需要的架构

自从发布iOS 8以来,开发人员已经能够利用动态库的优势进行iOS开发。

对于一般开发,为所有需要的体系结构提供一个动态库是一件很棒的事,这样您就可以在所有设备和iOS Simulator上运行而无需进行任何更改。

在我的项目及其各种扩展中,我使用了Reactive Cocoa,并将它作为预编译的动态库包含在我的项目中,其中包含Simulator 和设备的i386和x86_64slice 。armv7arm64

但是,这种方法有一个缺点-因为它们是在运行时链接的,所以当动态库单独编译到最终运行的应用程序时,就无法确定实际需要哪种架构。因此,Xcode只会在编译时将整个内容复制到您的应用程序包中。除了浪费磁盘空间之外,从理论上讲,这没有真正的缺点。但是实际上,iTunes Connect不喜欢我们添加未使用的二进制切片:

提交AppStore 提示Unsupported Architectures. Your executable contains unsupported architectures ‘[X86_64, i386]’.

在这里插入图片描述

解决

那么,我们如何解决这个问题?

  1. 我们可以改用静态库。但是,在我的项目中有多个目标和扩展,用相同库的副本膨胀我的所有可执行文件似乎很愚蠢。

  2. 我们可以每次从源代码编译该库,从而生成一个新的动态库,其中仅包含每个构建所需的架构。有两件事让我感到困扰-首先,一直都在重新编译所有不变的代码似乎很浪费,第二是我喜欢保持依赖关系为静态,并且每次都进行新的构建意味着我没有必须再运行稳定的代码,尤其是如果我开始在Xcode Beta中四处乱搞的时候。如果更改编译器导致库中出现奇怪的错误怎么办?这是非常罕见的事情,但是确实发生了,而且我不知道该库的代码库足以调试它。

  3. 如果我们没有开始的源头,那么,我们有点不走运。

  4. 我们可以在构建时弄清楚如何处理它,然后再也不必考虑它。听起来更像!

脚本解决

今天,我整理了一些构建时脚本来处理此问题,因此我不必再在意它了。

在我的项目文件夹中:

$ lipo -info Vendor/RAC/ReactiveCocoa.framework/ReactiveCocoaArchitectures in the fat file: ReactiveCocoa are:
    i386 x86_64 armv7 arm64

按下“ build”后:

$ lipo -info Cascable.app/Frameworks/ReactiveCocoa.framework/ReactiveCocoaArchitectures in the fat file: ReactiveCocoa are:
    armv7 arm64

事不宜迟,这里是脚本。在构建步骤中添加一个“运行脚本”步骤,将其放置在嵌入框架的步骤之后,将其设置为“使用”,/bin/sh然后输入以下脚本:

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
    FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
    echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

    EXTRACTED_ARCHS=()

    for ARCH in $ARCHS
    do
        echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
        lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
        EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
    done

    echo "Merging extracted architectures: ${ARCHS}"
    lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
    rm "${EXTRACTED_ARCHS[@]}"

    echo "Replacing original executable with thinned version"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

done

该脚本将浏览您构建的应用程序的Frameworks文件夹,并确保每个框架中仅存在要构建的体系结构。

在这里插入图片描述

好多了!现在,我可以在项目中添加大量动态库,其中包含我将需要的所有体系结构,并且构建过程将处理在任何给定时刻适合哪些体系结构。

参考

https://stackoverflow.com/questions/30547283/submit-to-app-store-issues-unsupported-architecture-x86

http://ikennd.ac/blog/2015/02/stripping-unwanted-architectures-from-dynamic-libraries-in-xcode/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章