iOS M1 晶元 編譯爬坑

来源:https://www.cnblogs.com/lesten/archive/2022/05/20/16293735.html
-Advertisement-
Play Games

今天我們來認識一位接觸 OpenHarmony 不到一年,便帶領團隊成功開發出一款“啟航 KP“智能開發套件的開發者——軟通動力資深項目經理許北林。 ...


主要是兩個錯誤,引起混淆。導致爬了挺久的坑。

1、 In xxxx/proj.ios_mac/xxxx.framework/xxxx(xxxx.a-arm64-master.o), building for iOS Simulator, but linking in object file built for iOS, for architecture arm64.
或者
ld: warning: ignoring file YoupPth/Build/Products/Debug-iphonesimulator/xxxx/xxxx.framework/xxxx, 
building for iOS Simulator-x86_64 but attempting to link with file built for iOS Simulator-arm64
Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_xxxx", referenced from:
      objc-class-ref in xxxx.o
ld: symbol(s) not found for architecture x86_64
    
    
2、 In xxxx/proj.ios_mac/xxxx.xcodeproj The linked framework 'Pods_xxx_iOS.framework' is missing one or more architectures required by this target: x86_64.

看起來好像是差不多,都是由於 項目中的依賴庫 提供的指令集 不完整導致的。

第一個 是說  xxxx.framework  指令集為 iOS 真機 這個庫, 不能 鏈接 為 iOS 模擬器 的 目標文件。 實際上這個問題 應該是一個相容問題,只出現在 M1 晶元的 Mac 上。 因為 M1 晶元的 Mac 本身就是 arm64 架構,它的模擬器也是 arm64 架構的。

首先有一點要明確:

我們在 intel 機型上 創建一個靜態庫文件,編譯後會生成兩個版本。一個是模擬器版, x86_64 架構(如果M1 機型上創建 那麼是 arm64 架構),一個是真機版, arm64 架構。

如果 intel 機型上 生成的靜態庫 需要 給 intel 機型上的 其他工程引入,一般操作是通過 lipo 工具合併成一個 模擬器和真機 通用的 靜態庫,以方便瀏覽器或者真機調試。

鏈接真機的時候 會把真機的指令 鏈接進 目標文件,鏈接模擬器 就把模擬器的指令鏈接進 目標文件

當鏈接的時候: 針對 一般第三方庫, 以前普遍提供的是 包含真機 arm64 指令集 和 模擬器 x86_64 指令集的 通用版本。

在 intel 機型上也就是你的Mac 打包機器為 intel 晶元,  為真機鏈接 arm64 架構 指令,為模擬器鏈接 x86_64 架構 指令沒有什麼問題。

但是 你的Mac 打包機器為 M1 晶元的時候,   為真機鏈接 arm64 架構指令,為模擬器 還是鏈接 x86_64 指令就會有問題。因為 此時 M1 機型 的模擬器架構是 arm64! 只能跑 arm64 指令。

這時候 Xcode 就會報以上類型的錯誤,而不會去為 模擬器 鏈接 該依賴庫 真機的 arm64 指令!!!

驗證很簡單,你在 M1 機型上編譯 真機的 靜態庫  鏈接到 模擬器 的可執行文件  依然不行。即使他們 都是在 arm64 架構下。

那麼如何解決這個問題? 有以下兩種方式。

1、使用 Rosetta 模式 運行Xcode, 重新編譯。

2005年, 蘋果從PowerPC 晶元切換到 因特爾,Rosetta 最初是為 PowerPC 應用轉換到 x86 上,能讓大多數 PowerPC 應用在 x86 Mac 上運行,但是會損失部分性能。 

Rosetta 模式 會使 Xcode 能夠 在鏈接 x86靜態庫 前 將其轉換為 arm64 指令。

通過 Rosetta 模式運行 Xcode, Xcode 是以 x86架構的方式運行(正常是 Apple 也就是 arm64), 靜態庫是 x86 的也能正常鏈接跑。  

在 M1 的 Mac 機型,模擬器 正常是以 arm64 運行的,模擬器 啟動 app 也是以 arm64 的方式運行。

而PC 上 Rosetta 模式啟動 Xcode 讓 App 鏈接 x86(也就是當前Xcode 運行模式)的庫,即使依賴庫既有 arm64 也有 x86 指令集。如果 依賴庫本身只有 arm64 指令集,那麼會報 未定義 符號,無法鏈接。

註意:Rosetta 的方式 雖然 足以支持大多數主流生產力應用程式,但無法相容那些需要與操作系統、硬體或圖形硬體進行直接交互的軟體。

 

2、編譯鏈接 app 工程的時候  排除 arm64 架構。 具體 在 Build Settings 里 設置 Excluded Architectures 選項,在 Debug 模式下 添加 arm64 。真機不會出現這個問題,所以 Release 不需要。

所以先 檢查工程以及子工程 編譯設置 排除 arm64 架構的編譯產物。 但是如果需要 編譯依賴庫文件 提供給第三方 使用 那麼你的生成產物又不能排除 arm64.  你可能就需要針對不同 的架構打不同的版本。下麵有更好的解決辦法。

檢查 Build Settings 裡面的 Excluded Architectures 添加  arm64。  clean 重編。 

最終跑起來  會發現  排除了 arm64 指令集後 模擬器也是以 x86 的方式啟動 App 了。 

查看 活動監視器 裡面  進程的 種類 就可以清晰的知道。 

模擬器與 模擬器啟動的 App 運行指令集不同,通過 XPC 方式進行通信,理論上沒有啥問題,但是 XPC 通信 相對同步時間比較長, 對於 時間敏感的邏輯可能會出問題。

比如 滑動手勢 或者 列表的慣性滾動。 

 

對於通過 cocoapods 維護依賴庫的方式來說, 如果手動更改後,重新  pod update 會導致又要重新修改,所以excluded Architectures  需要寫進 Podfile

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = "arm64"
    end
  end
end

 

為瞭解決 M1 晶元機型 封裝庫文件的問題, 2019年 的 WWDC 大會  Apple 提供了 XCFrameworks 的方式,這就可以理解成 新的 xcodebuild 命令替換以前  lipo 命令,將不同指令集 的庫文件合併成 通用二進位文件。

只不過 XCFrameworks 還可以包含其他第三方的庫。 這裡就不展開說 XCFrameworks 了。

 

第二個 是說 鏈接 Pods_xxxx_iOS.framework 這個framework 中 缺失了 x86_64 架構 的某個庫。

所以檢查 編譯 生成 Pods_xxxx_iOS.framework 的 所有依賴庫的工程 或者 prebuilt 的庫,是否存在 x86_64 架構。

1、針對子工程,如果 Xcode 13, 檢查工程的 User-Defined 裡面的  VALID_ARCHS 值 是否存在  x86_64,沒有則需要添加。 如果是 Xcode 12 則在  Architectures 裡面檢查 是否存在 x86_64。其他架構也是同樣

2、針對 預編譯庫, 可以使用 lipo 工具查看包含一些什麼 指令集。是否缺失 x86_64。   例如:lipo -i xxx.a

主要是 Xcode12 預設不再對 x86_64 架構 進行支持了,打通用包的時候  需要手動添加。

 

lipo 工具 可以對  庫文件的架構進行修改

nm 工具 用來現實一個 程式包的符號表

strip 用來刪除一個 程式包里的符號表

ar 工具 可以獲取 庫文件 鏈接前的  .o 文件  

libtool -static -o  xxx.a  *.o   又可以合併 *.o 文件 為 xxx.a。 或者 直接用 ld。

 

參考:

https://juejin.cn/post/7037037120158269448


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • awk linux命令_sed AWK 是一種處理文本文件的語言,是一個強大的文本分析工具。 之所以叫 AWK 是因為其取了三位創始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字元。 學習具體使用前,先來看下 aw ...
  • 本文例子參考《STM32單片機開發實例——基於Proteus虛擬模擬與HAL/LL庫》 源代碼:https://github.com/LanLinnet/STM33F103R6 項目要求 單片機每隔1s以“YYYY-MM-DD HH:MM:SS”的格式自動向串口輸出日期和時間信息(“ASCII格式” ...
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 一,VMware配置。 因為要裝kali,所以要用到Debian。 這裡的處理器配置要根據自己的電腦硬體決定。 查找電腦處理器信息: 控制面板——設備管理器——處理器 這裡也是看著給,有條件的多給點,沒有就預設。 如果有人真的要問,最低推薦不就可 ...
  • Issue 升級 PostgreSQL 9.1 的一個集群,由於該集群用到了 PostGIS,在升級 PostgreSQL 時也需要升級一下 PostGIS。PostGIS 相關軟體安裝好後,在 PostgreSQL 11 中創建 postgis extension 時失敗,如下: alvindb= ...
  • 一、概述 Hue是一個開源的Apache Hadoop UI系統,最早是由Cloudera Desktop演化而來,由Cloudera貢獻給開源社區,它是基於Python Web框架Django實現的。通過使用Hue我們可以在瀏覽器端的Web控制臺上與Hadoop集群進行交互來分析處理數據,例如操作 ...
  • 一、安裝mysql8.0 ##下載mysql安裝包 http://mirrors.sohu.com/mysql/MySQL-8.0/ wget http://mirrors.sohu.com/mysql/MySQL-8.0/mysql-community-client-8.0.18-1.el7.x8 ...
  • 分享嘉賓:王懷遠 阿裡雲 表格存儲架構師 編輯整理:李瑤 DataFun 出品平臺:DataFunTalk 導讀: 大家好,我是王懷遠,我2015年加入阿裡雲,一直從事表格存儲的研發和架構相關工作,目前擔任表格存儲的架構師。我在存儲和資料庫領域有一些研發和架構方面的經驗。 本次分享的主題是一站式物聯 ...
  • 一、概述 Impala 直接針對存儲在 HDFS、HBase或 Amazon Simple Storage Service (S3)中的 Apache Hadoop 數據提供快速的互動式 SQL 查詢。Impala是一個基於Hive、分散式、大規模並行處理(MPP:Massively Paralle ...
一周排行
    -Advertisement-
    Play Games
  • JWT(JSON Web Token)是一種用於在網路應用之間傳遞信息的開放標準(RFC 7519)。它使用 JSON 對象在安全可靠的方式下傳遞信息,通常用於身份驗證和信息交換。 在Web API中,JWT通常用於對用戶進行身份驗證和授權。當用戶登錄成功後,伺服器會生成一個Token並返回給客戶端 ...
  • 老周在幾個世紀前曾寫過樹莓派相關的 iOT 水文,之所以沒寫 Nano Framework 相關的內容,是因為那時候這貨還不成熟,可玩性不高。不過,這貨現在已經相對完善,老周都把它用在項目上了——第一個是自製的智能插座,這個某寶上50多塊可以買到,搜“esp32 插座”就能找到。一種是 86 型盒子 ...
  • 引言 上一篇我們創建了一個Sample.Api項目和Sample.Repository,並且帶大家熟悉了一下Moq的概念,這一章我們來實戰一下在xUnit項目使用依賴註入。 Xunit.DependencyInjection Xunit.DependencyInjection 是一個用於 xUnit ...
  • 在 Avalonia 中,樣式是定義控制項外觀的一種方式,而控制項主題則是一組樣式和資源,用於定義應用程式的整體外觀和感覺。本文將深入探討這些概念,並提供示例代碼以幫助您更好地理解它們。 樣式是什麼? 樣式是一組屬性,用於定義控制項的外觀。它們可以包括背景色、邊框、字體樣式等。在 Avalonia 中,樣 ...
  • 在處理大型Excel工作簿時,有時候我們需要在工作表中凍結窗格,這樣可以在滾動查看數據的同時保持某些行或列固定不動。凍結窗格可以幫助我們更容易地導航和理解複雜的數據集。相反,當你不需要凍結窗格時,你可能需要解凍它們以獲得完整的視野。 下麵將介紹如何使用免費.NET庫通過C#實現凍結Excel視窗以鎖 ...
  • .NET 部署 IIS 的簡單步驟一: 下載 dotnet-hosting-x.y.z-win.exe ,下載地址:.NET Downloads (Linux, macOS, and Windows) (microsoft.com) .NET 部署 IIS 的簡單步驟二: 選擇對應的版本,點擊進入詳 ...
  • 拓展閱讀 資料庫設計工具-08-概覽 資料庫設計工具-08-powerdesigner 資料庫設計工具-09-mysql workbench 資料庫設計工具-10-dbdesign 資料庫設計工具-11-dbeaver 資料庫設計工具-12-pgmodeler 資料庫設計工具-13-erdplus ...
  • 初識STL STL,(Standard Template Library),即"標準模板庫",由惠普實驗室開發,STL中提供了非常多對信息學奧賽很有用的東西。 vector vetor是STL中的一個容器,可以看作一個不定長的數組,其基本形式為: vector<數據類型> 名字; 如: vector ...
  • 前言 最近自己做了個 Falsk 小項目,在部署上伺服器的時候,發現雖然不乏相關教程,但大多都是將自己項目代碼複製出來,不講核心邏輯,不太簡潔,於是將自己部署的經驗寫成內容分享出來。 uWSGI 簡介 uWSGI: 一種實現了多種協議(包括 uwsgi、http)並能提供伺服器搭建功能的 Pytho ...
  • 1 文本Embedding 將整個文本轉化為實數向量的技術。 Embedding優點是可將離散的詞語或句子轉化為連續的向量,就可用數學方法來處理詞語或句子,捕捉到文本的語義信息,文本和文本的關係信息。 ◉ 優質的Embedding通常會讓語義相似的文本在空間中彼此接近 ◉ 優質的Embedding相 ...