2011-04-11 95 views
4

我用gcc 4.3.4和ld 51年2月20日在Cygwin的這是我的問題的一個簡化版本:GCC/LD:在Windows 7未定義引用未使用的功能

  • foo.o包含功能foo_bar()這在文件bar.o調用bar()
  • bar.o包含功能bar()
  • main.c通話功能foo.o,但foo_bar()是不是在調用鏈

如果我嘗試編譯main.c並將其鏈接到foo.o,我從ld得到undefined reference to _foo_bar錯誤。正如你可以從我的Makefile中看到的,除了下面的內容,我已經嘗試過使用標誌將每個函數放在它自己的部分中,並讓鏈接器放棄未使用的部分。

COMPILE_CYGWIN = gcc -iquote$(INCDIR) 
COMPILE = $(COMPILE_CYGWIN) -g -MMD -MP -Wall -ffunction-sections -Wl,-gc-sections $(DEFINE) 
main_OBJECTS = main.o foo.o 
main.exe : $(main_OBJECTS) 
    $(COMPILE) -o main.exe $(main_OBJECTS) 

功能foo_bar()是短函數,其提供在協議棧中2網絡層之間的連接。某些程序不需要它,因此它們不會鏈接到與堆棧上層相關的其他目標文件。這是一個小功能,似乎不適合將它放到它自己的.o文件中。

我不明白爲什麼ld會拋出錯誤 - 什麼都不是叫foo_bar(),所以沒有必要在最終的可執行文件中包含bar()。一位同事告訴我,ld不是一個「智能鏈接器」,所以也許我想要做的事情是不可能的?

+0

編譯'foo'時需要'-ffunction-sections'。連接「bar」還有什麼特別的問題嗎? – rlibby 2011-04-11 18:01:17

+0

在這種情況下,在'bar.o'中鏈接需要至少15個以上的目標文件來填充它的依賴關係。我想我已經達到了需要將目標文件鏈接到一個庫中並讓我的程序引用該目錄的點。 – tomlogic 2011-04-11 18:27:49

+0

除非你有其他限制,否則它並不像聽起來那麼糟糕。這有點前期的痛苦,但它不會有任何顯着的運行時間成本。我不知道Windows上的動態鏈接程序是如何工作的,但假設它有一半體面,那麼無論如何不會加載無關的代碼。 – rlibby 2011-04-11 18:34:07

回答

7

除非鏈接器是從Cyberdyne Systems它無法確切地知道哪些函數將被實際調用。它只知道哪些是參考。即使Skynet's鏈接器也無法預測將執行哪些運行時決策,或者如果您在運行時動態加載模塊並開始調用各種全局函數將會發生什麼情況。

所以,如果模塊鏈接,它引用函數˚F,你將需要與任何模塊˚F鏈接。


1.這個問題是關係到Halting Problem並已被證明undecidable