從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/

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