最近工作中要編譯一個第三方的C庫用於iOS端使用,我直接在Mac OS的終端中./configure & make & make install常規走下來,卻無法在真機iOS上使用,提示“Symbol(s) not found for architecture arm64”!
通過命令file *.a或者lipo -info *.a,可以看到生成的靜態庫文件時x86_64架構的。
編譯器粗略分為詞法分析,語法分析,類型檢查,中間代碼生成,代碼優化,目標代碼生成,目標代碼優化。把中間代碼生成及之前階段划分問編譯器的前端,那么后端與前端是獨立的。
前端主要指與源語言有關但與目標機無關的部分,包括詞法分析、語法分析、語義分析與中間表示生成。
后端主要指與目標機有關的部分,包括代碼優化和目標代碼生成等。
iOS 中的 armv7,armv7s,arm64,i386,x86_64 都是什么?
arm64:iPhone6s | iphone6s plus|iPhone6| iPhone6 plus|iPhone5S | iPad Air| iPad mini2(iPad mini with Retina Display)
armv7s:iPhone5|iPhone5C|iPad4(iPad with Retina Display)
armv7:iPhone4|iPhone4S|iPad|iPad2|iPad3(The New iPad)|iPad mini|iPod Touch 3G|iPod Touch4
armv6 設備: iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch(一般不需要去支持)
i386是針對intel通用微處理器32位處理器
x86_64是針對x86架構的64位處理器
模擬器32位處理器測試需要i386架構,
模擬器64位處理器測試需要x86_64架構,
真機32位處理器需要armv7或者armv7s架構,
真機64位處理器需要arm64架構。
可見,編譯出來的庫要想在iOS設備上使用,需要該庫符合設備所支持的架構才行。而我們一般的庫編譯構建工作時在PC機上進行的,要想編譯出移動端能使用的庫,就需要交叉編譯(Cross-compilation)了,關於Clang的交叉編譯可以參考下官方文檔http://clang.llvm.org/docs/CrossCompilation.html。
下面在Mac OS X10.14上以hello world c文件為例,認識一下使用Clang進行交叉編譯的過程:
打開終端,vim hello.c,輸入以下代碼保存,很簡單的代碼:
1
2 3 4 5 6 7 |
#include
<stdio.h> int main() { printf( "hello world!\n" ); return 0 ; } |
使用clang進行交叉編譯
1
2 3 4 5 6 7 8 9 10 |
// -arch 表示要編譯的架構 這里為arm64. // -isysroot 指定頭文件的根路徑 $ clang -arch arm64 -o hello hello.c –isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS12. 4 .sdk //也可以使用xcrun,xcrun -sdk 會使用最新的sdk去編譯 $ xcrun -sdk iphoneos clang -arch arm64 -o hello hello.c // 使用file命令或者lipo –info查看編譯出來的文件是什么架構 $ file hello 或 lipo –info hello |
運行截圖
Mach-O為Mach Object文件格式的縮寫,它是一種用於可執行文件,目標代碼,動態庫,內核轉儲的文件格式,是iOS 或 OS X 中的一個可執行文件格式。