我試圖鏈接使用GCC一個C++模塊,基本上是這樣的:GCC鏈接順序改變了嗎?
gcc -c hello.c
g++ -c world.cpp
gcc -ohello -lstdc++ hello.o world.o
請注意,我用-lstdc++
在C++模塊鏈接,這樣我就可以使用gcc
而不是g++
。問題是,我得到的錯誤:
undefined reference to `operator new(unsigned long)'
(假設world.cpp
包含至少一個呼叫new
)
如果我把-lstdc++
在連接線的末端此錯誤是固定的,像這樣:
gcc -ohello hello.o world.o -lstdc++
我知道這個問題在這裏已經被問過很多次了,但是我有一個特殊的要求。我不是直接調用GCC。我正在使用不同的編程語言(Mercury)的構建系統,它以我的名義調用GCC,並且我無法輕鬆修改它調用GCC的方式(儘管我可以使用LDFLAGS環境變量指定其他庫)。所以,我有兩個附加條件:
- 我不能用
g++
鏈接(只gcc
) - 這就是爲什麼我做了-lstdc++
伎倆以上,而不是簡單地用g++
連接)。 - 我不認爲我可以控制鏈接器命令的順序 - 水星將把任何庫中的.o文件放在命令行後。
我理解的根本原因的順序很重要,但什麼是莫名其妙我現在爲什麼這樣做休息?我剛更新到Ubuntu 11.10/GCC 4.6.1。我已經使用上述技術成功地編譯了這個程序多年(首先將-lstdc++
放入)。現在只有這個錯誤出現了。一個與我的OpenGL無關的程序,使用-lgl
,當我升級時我的程序也崩潰了,我必須將-lgl
移動到命令行的末尾。我可能會發現我的幾十個程序不再編譯。爲什麼這個改變?我的新系統有什麼問題,或者是現在的方式?請注意,這些是普通的共享庫,不是靜態鏈接的。
有沒有什麼我可以做GCC回到舊的方式,圖書館的順序並不重要?有沒有其他方法可以說服GCC正確鏈接libstdc++
,而不必在命令行上的.o
文件之後移動它?
所以基本上這個「迴歸」就是對於我整個開發生涯來說,我一直依賴於它「意外工作」而現在已停止工作的事實?看起來像一個非常重大的變化 - 我已經在目標文件之前在十年的較好時間內部署庫,因爲我不知道這是一個問題:(感謝您的建議。看起來問題不是Mercury在庫之後放置對象,而是在我的LDFLAGS命令中存在更復雜的依賴關係。我正在取得進展,所以我會給你打個招呼。謝謝。 – mgiuca 2011-12-27 02:41:23
未經證實的假設:'ld'可能會影響到你。目標可能是避免加載未使用的共享庫。如果你使用靜態庫,你只會得到你需要的東西。過去的情況是,如果您在鏈接行上列出了共享庫,它將在運行時加載,即使庫沒有提供任何符號。只有在滿足至少一個符號的情況下加載庫才能減少程序的啓動時間。但這也意味着,如果掃描庫時唯一出現的符號是'main()',那麼庫將不會被加載。 – 2011-12-27 02:55:03
在[NEWS](http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/ld/NEWS?)上查看'ld'版本2.20的'--as-needed'的註釋? rev = 1.121&content-type = text/plain&cvsroot = src&only_with_tag = binutils-binutils-2_22)文件。另請參閱[手冊](http://sourceware.org/binutils/docs-2.22/ld/Options.html#Options)以及'--copy-dt-needed-entries'和'--no-copy- dt-needed-entries'選項。我相信,先前的未證實的假設至少在某種程度上得到了證實。 – 2011-12-27 03:17:11