2009-10-14 64 views
2

如果您使用GCC編譯共享庫並傳遞「-z defs」標誌(我認爲它只是盲目地傳遞給ld),那麼您會得到一個很好的未定義符號的報告,並且ld失敗(不。所以創建文件)。另一方面,如果你沒有指定「-z defs」或者明確指定「-z nodefs」(缺省值),那麼即使符號丟失,也會產生一個.so,但是你沒有得到什麼符號的報告如果有的話失蹤。如何讓gcc或ld報告未定義的符號但不失敗?

我想都!我想要創建.so,但我還想要報告任何缺少的符號。到目前爲止我所知道的唯一方法是運行兩次,一次使用「-z defs」,一次沒有。這意味着可能的長鏈接階段會執行兩次,這會使編譯/測試周期變得更糟。

如果您想知道我的最終目標 - 編譯庫時,本地對象文件中的未定義符號表示未指定應該在我的構建環境中的依賴項,而如果符號在一個你鏈接的庫,這不是一個錯誤(-l標誌只給出立即依賴關係,而不是依賴關係,在這個系統下)。我需要報告中列出「在文件中引用」的部分,以便我可以查看符號是由本地對象還是正在鏈接的庫引用的。 --allow-shlib-undefined選項幾乎可以解決這個問題,但在與靜態庫鏈接時不起作用。

首選可與GNU和Solaris連接器兼容的解決方案。

回答

4

從GNU LD 2.15 NEWS文件的問題:

  • 改進的鏈接器處理未解析的符號。交換機 --unresolved-symbols =已被添加以告知鏈接器何時它應該報告它們,並且交換機--warn-unresolved-symbols已被添加到 使得報告被髮布爲警告消息而不是錯誤。
6

而不是讓ld在鏈接過程中報告未定義的符號,您可以在生成的.so文件上使用nm。例如:

nm --dynamic --undefined-only foo.so 

編輯:雖然我猜並不會給你哪些源文件的符號用於。對不起,我錯過了你的問題的那一部分。

你仍然可以使用納米的近似解,使用grep一起:

for sym in `nm --dynamic --undefined-only foo.so |cut -d' ' -f11 |c++filt -p` ; do 
    grep -o -e "\\<$sym\\>" *.cpp *.c *.h 
done 

這可能具有相同名字的局部符號等

+0

您可以使用C++ filt來取消名稱 – fbrereto 2009-10-14 20:51:35

+0

好的建議,fbrereto;我已將其整合到我的答案中。 – wdebeaum 2009-10-14 21:22:11

+0

我將答案標記爲解決方案,但應該指出,對於不使用GNU鏈接器的用戶,您的答案仍然正確。 – 2011-08-18 20:33:31

相關問題