iOS開發引入靜态庫時, 經常遇到類似錯誤
Undefined symbols for architecture x86_64: "_xxxx", referenced from: ...
。此時,可以進入到靜态庫所在目錄下,使用
nm
指令檢視該架構下是否存在該符号:
nm mySDK -arch x86_64 | grep '_xxxx'
功能
nm指令可以列出一個函數庫檔案(.o .a .so)中的符号表。所謂符号,通常指定義出的函數,全局變量等等。它對于靜态的函數庫和共享的函數庫都起作用。nm指令顯示的資訊用于調試庫和可執行檔案,對于一個給定的函數庫,nm指令可以列出函數庫中定義的所有符号,包括每個符号的值和類型。還可以給出在原程式中這個函數(符号)是在多少行定義的,不過這必須要求編譯該函數庫的時候加“-l”選項。
使用
nm [選項] [檔案清單(庫檔案/目标檔案/可執行檔案)]
有用的options:
在每個符号資訊的前面列印所在對象檔案名稱;
-A
全局非初始化資料段(BBS段)的符号,其值表示該符号在bss段中的偏移;
-B
全局static的符号;
-b
輸出demangle過了的符号名稱;
-C
列印動态符号,隻顯示動态符号,當使用動态庫時很有用;
-D
隻顯示全局符号的相關資訊;
-g
使用對象檔案中的調試資訊,為每一個符号查找和顯示所在源檔案及行号;
-l
debug用的符号;
-N
按照位址/符号值來排序;
-n
const型隻讀的變量(readonly);
-r
位于代碼區的符号,比如函數main;
-T
位于代碼區的符号,一般是static函數;
-t
列印出那些未定義的符号,即位于目标子產品的外部符号,比如系統的printf()函數;
-u
給出更多警告資訊;
-w
nm指令版本号;
-V
常見的符号類型:
該符号的值在今後的連結中将不再改變;
A
該符号放在BSS段中,通常是那些未初始化的全局變量;
B
該符号放在普通的資料段中,通常是那些已經初始化的全局變量;
D
該符号放在代碼段中,通常是那些全局非靜态函數;
T
該符号未定義過,需要自其他對象檔案中連結進來;
U
未明确指定的弱連結符号;同連結的其他對象檔案中有它的定義就用上,否則就用一個系統特别指定的預設值。
W
舉例
更詳細的内容見man page。這裡舉例說明:
nm -u hello.o
顯示hello.o 中的未定義符号,需要和其他對象檔案進行連結。
nm -A /usr/lib/* 2>/dev/null | grep "T memset"
在 /usr/lib/ 目錄下找出哪個庫檔案定義了memset函數。
nm AlipaySDK -arch arm64 | grep '_RSA_ver'
在這個framework中,查找
AlipaySDK
架構下的
arm64
符号。
_RSA_ver