引用一些三方庫后迷帜,如果是模擬器運(yùn)行在編譯過程中可能會遇找不到對應(yīng)指令集文件的錯誤,以創(chuàng)藍(lán)閃驗的SDK為例:
先說解決方案,再說這個錯誤的原因
如果想繼續(xù)用模擬器跑項目椭蹄,就需要用Rosetta版本的模擬運(yùn)行,打開Rosetta模擬器顯示:
模擬器選擇Rosetta版本:
這個時候就能成功編譯并運(yùn)行項目了净赴。
但是剛開始運(yùn)行绳矩,除了列表滑動沒有慣性交互外沒什么大問題,但修改幾行代碼或者過段時間Command + R玖翅,模擬器就會卡死并黑屏翼馆,XCode也一直轉(zhuǎn)圈,最終只能重新啟動模擬器金度。
造成這個現(xiàn)象的原因是因為XCode和模擬器運(yùn)行在不同的指令集下应媚,兩者之間通信通過Rosetta轉(zhuǎn)義。
接著再說說上面編譯報錯的原因猜极,在M系Mac之前中姜,由于用的Intel芯片,模擬器是x86架構(gòu)跟伏,所以在制作靜態(tài)庫時丢胚,會編譯x86和arm兩個指令集版本的二進(jìn)制文件,并用lipo命令合并成.a或.framework文件酬姆。通過lipo -info或file命令查看上述SDK的mach-O文件信息如下:
說明這個SDK同時包含arm64和x86_64兩個架構(gòu)的指令集嗜桌,這在Intel芯片下跑模擬器是沒問題的,但是M系Mac本身是arm架構(gòu)辞色,所以模擬器版本的SDK就會編譯報錯(理論上既然包含arm64的文件骨宠,M1芯片下的xcode直接去找arm64的文件應(yīng)該是可以的浮定,所以猜測真機(jī)下的arm64跟模擬器下的arm64是不是有區(qū)別)
我通過新建一個framework項目,并編譯模擬器的靜態(tài)庫:
然后再Products目錄下查看framwork文件夾下的二進(jìn)制文件結(jié)構(gòu)信息如下:
這里看到的信息是跟上面SDK的信息是一樣的层亿。
開始動歪腦筋:是不是可以將SDK的arm架構(gòu)單獨(dú)抽出一個framework桦卒,將arm的framework和包含arm和x86的famework同時打成一個xcframework,就能解決最初的問題匿又?答案是行不通方灾。
由于用lipo命令查看SDK的二進(jìn)制文件和我測試生成的靜態(tài)庫的二進(jìn)制文件信息一樣,于是嘗試直接將SDK打成xcframework碌更,卻得到一個錯誤:
意思二進(jìn)制文件不能包含多個平臺裕偿,我自己編譯的x86、arm64的二進(jìn)制是針對模擬器平臺痛单,SDK的x86嘿棘、arm64是模擬器和真機(jī)平臺的
我用測試靜態(tài)庫生成xcframework,再將測試靜態(tài)庫的二進(jìn)制文件的arm64抽離成單獨(dú)的framework旭绒,同時生成xcframework鸟妙,兩個文件夾的目錄結(jié)構(gòu)分別如下:
生成的文件夾都包含了simulator關(guān)鍵字
而將SDK的二進(jìn)制的arm64抽離成單獨(dú)的framework并生成xcframework,文件夾的目錄如下:
說明真機(jī)和模擬器的arm64架構(gòu)還不一樣挥吵?所以想讓只支持x86_64模擬器的靜態(tài)庫通過xcframework去兼容M系模擬器想法破滅了=重父。=
總結(jié):要想靜態(tài)庫支持M系模擬器,必須在靜態(tài)庫出廠的時候編譯好所有架構(gòu)模擬器的靜態(tài)庫忽匈,要不然接入方就只能真機(jī)調(diào)試房午,或者用Rosetta版本的模擬器(忍受性能損耗和兩個架構(gòu)系統(tǒng)之間通信的bug)。
感謝以下文章的幫助:
M1設(shè)備的Xcode編譯問題深究
iOS開發(fā) XCFramework
iOS開發(fā)之--Architectures詳解