最近在玩靜態(tài)庫打包,時不時遇到如下這種報錯,可能是Xcode升級的緣故,之前是沒有遇到過,故此總結(jié)了一波...
Building for iOS Simulator, but the linked library 'libxxx.a' was built for iOS.
這個問題是因為模擬器編譯的那個.a
沒有合并,只是打了真機的.a
,運行到模擬器而模擬器是x86_64
的架構(gòu),如果不需要模擬器調(diào)試,直接真機的即可
另: 模擬器打包與真機的包無法合并,出現(xiàn)arm64重復,無法合并為fat的問題
Build settings->Excluded Architectures
里忽略當前SDK
不支持的架構(gòu)
模擬器SDK下可以忽略真機的架構(gòu)arm64
,arm64e
,其實不適配5s以下的話直接把i386也去掉也是可以的,同樣真機也可去掉armv7和armv7s,這樣做的好處是可以減小包體積
現(xiàn)在新iPhone X以上iPhone 11 iPhone12等支持新架構(gòu)得加一個arm64e
,在Architectures
里的other
里手動添加即可
所以目前解決辦法就是打多個版本的靜態(tài)庫
比如:
- 全量包 i386,x86_64,armv7,armv7s,arm64,arm64e
- 拆分包
- 真機和模擬器的拆分
- 模擬器 i386,x86_64
- 真機 armv7,armv7s,arm64,arm64e
- 每一種架構(gòu)單獨拎出來,lipo命令自己按需合并
- 真機和模擬器的拆分
一般來說,開發(fā)調(diào)試的話就用全量包,發(fā)布上線用真機包
講道理,一些舊設備都被系統(tǒng)所淘汰了,iOS10起步支持iPhone 5s以上,那就大可不必支持i386和armv7,直接arm64和x86_64即可,上線打包可以剔除x86_64,這樣才是最優(yōu)解
編譯.a的腳本如下(采用手動編譯+腳本合成):
ps: 自動編譯在Xcode12.3不知道出了什么鬼,xcodebuild一直死循環(huán)就是編譯不過,無奈之下采取半自動了,不過配合say語音提示也是可以的
prismjs language
#! /bin/sh
# 先在工程根目錄創(chuàng)建好SDK文件夾
mkdir -p ${PROJECT_NAME}_SDK
cd ${PROJECT_NAME}_SDK
mkdir -p ${PROJECT_NAME}
cd ${PROJECT_NAME}
mkdir -p include
mkdir -p lib
#回到工程目錄
cd ./../../
#真機build生成的.a文件路徑
DEVICE_DIR_A=${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a
#模擬器build生成的.a文件路徑
SIMULATOR_DIR_A=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a
if [[ -f "${DEVICE_DIR_A}" ]]; then
say "真機編譯完成"
fi
if [[ -f "${SIMULATOR_DIR_A}" ]]; then
say "模擬器編譯完成"
fi
if [[ -f "${DEVICE_DIR_A}" ]] ; then
if [[ -f "${SIMULATOR_DIR_A}" ]]; then
lipo -create ${DEVICE_DIR_A} ${SIMULATOR_DIR_A} -output ./${PROJECT_NAME}_SDK/${PROJECT_NAME}/lib/lib${PROJECT_NAME}.a
#頭文件轉(zhuǎn)移大法
HEADER_FOLDER="${BUILD_DIR}/${CONFIGURATION}-iphoneos/include/${PROJECT_NAME}"
cp -a ${HEADER_FOLDER}/. ./${PROJECT_NAME}_SDK/${PROJECT_NAME}/include
open ./
say "靜態(tài)庫合并成功"
fi
fi
編譯framework與.a類似
prismjs language
#! /bin/sh
#創(chuàng)建存放目錄
mkdir -p ${PROJECT_NAME}.framework
INSTALL_DIR=./${PROJECT_NAME}.framework
#真機編譯產(chǎn)物
DEVICE_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework
#模擬器編譯產(chǎn)物
SIMULATOR_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework
#.framework是目錄是文件夾 所以用-d判斷 文件用-f
if [[ -d "$DEVICE_DIR" ]]; then
say "真機編譯完成"
fi
if [[ -d "$SIMULATOR_DIR" ]]; then
say "模擬器編譯完成"
fi
if [[ -d "${DEVICE_DIR}" ]] ; then
if [[ -d "${SIMULATOR_DIR}" ]]; then
cp -R ${DEVICE_DIR}/ ${INSTALL_DIR}/
lipo -create "${DEVICE_DIR}/${PROJECT_NAME}" "${SIMULATOR_DIR}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}"
open ./
say "靜態(tài)庫合并成功"
fi
fi
更新于2020-01-11
有時候模擬器編譯失敗而報錯
The linked library 'xxxx.a/Framework' is missing one or more architectures required by this target: armv7/或者是x86_64
真機SDK編譯模擬器或者是模擬器SDK編譯真機,lipo -info xxx
查看架構(gòu)排除原因
① 如果是沒有合并,則需要合并
② 如果已合并,則需要差異化排除
在TARGETS ——> Build Settings-Excluded Architectures 添加如下代碼:
prismjs language
EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8 EXCLUDED_ARCHS=$(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT))
選擇模擬器SDK編譯的時候,排除真機架構(gòu),同理,編譯真機SDK時,排除模擬器的架構(gòu),Excluded
是排除的意思. 拷貝上面這句代碼往上一粘就完事了
-all_load , -force_load , -ObjC 的區(qū)別和妙用
-
-all_load
鏈接器把目標文件都加載進來,不能草率使用這個,項目很大或者依賴的庫很多可能會出現(xiàn)沖突,提示重復依賴之類的錯誤,在知道各個庫使用情況之下,最好是使用-force_load
一個個指定庫文件去加載. -
-force_load
與-all_load
用法類似,指定目標文件加載 -
-ObjC
用于加載分類category,類和分類同時存在于靜態(tài)庫時使用-ObjC
沒毛病,但是如果沒有包含類對象,僅僅只是category是加載不進去的,如果什么都不加,靜態(tài)庫中的category在外部調(diào)用的時候會直接報錯: unrecognized selector xxx , 一般情況都是配合-all_load
和-force_load
一起使用.
一些相關(guān)文章
解決-Xcode-11-4-以來模擬器編譯報錯-Building-for-iOS-Simulator-but-the-linked-library-was-built-for-iOS-的正確姿勢
Xcode 12 - Architecture相關(guān)問題
iOS CPU架構(gòu)(ARM指令集)
iOS 打包移除 i386 和 x86_64 平臺動態(tài)庫
Python小工具: 去除iOS靜態(tài)庫(.a或.framework)模擬器架構(gòu)代碼
Xcode升級12編譯報錯The linked library is missing one or more architectures required by this target
未經(jīng)作者授權(quán),禁止轉(zhuǎn)載
本文來自博客園远舅,作者:CoderWGB激才,轉(zhuǎn)載請注明原文鏈接:https://www.cnblogs.com/wgb1234/p/14258036.html