2011-04-11 64 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