2012-01-25 35 views
8

我一直在試圖建立一個使用數學函數的一些代碼(例如pow)。gcc和math.h的奇怪行爲?

math.h被包括,並且標誌-lm在構建期間使用。

當編譯這樣調用(-lm標誌在命令的開頭),它失敗了,說是有一個未定義的參考pow

gcc -lm -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder 
main.o: In function `get_sn_motif_id': 
main.c:(.text+0x28d): undefined reference to `pow' 

而當-lm標誌被放置在命令的結尾,它的作品!

gcc -O3 main.o clustering.o grassberger.o hash.o list.o mat.o metropolis.o motif_ids.o output.o permutation.o prob.o random.o results.o role.o stubs.o switches.o -o mfinder -lm 

這是正常的嗎?

+0

哎呀。沒有注意到這是一個古老的問題。 – AnT

回答

18

是的,這是正常的。對於許多連接器,您指定對象文件和庫的順序很重要。

引述"An Introduction to GCC - for the GNU compilers gcc and g++"

接頭的傳統行爲是尋找外部函數從左至右在命令行上指定的庫。這意味着包含函數定義的庫應該出現在任何使用它的源文件或目標文件之後。這包括與短切-l選項指定的庫,如圖以下命令:

$ gcc -Wall calc.c -lm -o calc (correct order)

這種現象是常見的,但絕不是普遍的。如有疑問,最好查閱你的鏈接手冊。例如,我的Ubuntu系統上man ld指出:

-l namespec 
    --library=namespec 

     ... 

     The linker will search an archive only once, at the location where 
     it is specified on the command line. If the archive defines a 
     symbol which was undefined in some object which appeared before the 
     archive on the command line, the linker will include the 
     appropriate file(s) from the archive. However, an undefined symbol 
     in an object appearing later on the command line will not cause the 
     linker to search the archive again. 

換句話說,這個鏈接程序在gcc書中描述的方式表現。

+0

儘管應該提到這不適用於共享庫(至少使用gcc),它們可能出現在命令行的任何地方。所以人們做到了。然而,最近這種情況已經發生了變化,gcc現在在許多平臺上將「--as-needed」標誌應用於鏈接器,所以共享庫的效果也是如此。 – nos

4

An Introduction to GCC - for the GNU compilers gcc and g++

提到接頭的傳統行爲是搜索外部函數由左到右在命令行上指定的庫。這意味着包含函數定義的庫應該出現在任何使用它的源文件或目標文件之後。

我認爲你看到了同樣的行爲。

注意,這也進一步指出,

大多數現代鏈接搜索所有圖書館,無論秩序,但最好是遵循訂購庫由左到右的慣例。