GCC链接顺序发生了变化?

时间:2011-12-27 02:24:18

标签: gcc linker

我正在尝试使用GCC链接C ++模块,基本上是这样的:

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++

我知道这个问题在这里被多次询问过,但我有一个特殊的要求。我不直接打电话给海湾合作委员会。我正在为不同的编程语言(Mercury)使用构建系统,它代表我调用GCC,我不能轻易修改它调用GCC的方式(尽管我可以使用LDFLAGS环境变量指定其他库)。所以我还有两个要求:

  • 我无法使用g++链接(仅gcc) - 这就是我在上面执行-lstdc++诀窍而不是简单地与g++进行关联的原因。 / LI>
  • 我认为我无法控制链接器命令的顺序 - Mercury会在任何库之后将.o文件放在命令行上。

我理解订单重要的基本原因,但令我困惑的是为什么现在打破?我刚刚更新到Ubuntu 11.10 / GCC 4.6.1。我已经使用上述技术(首先放置-lstdc++)成功编译了这个程序多年。只是现在才出现这个错误。我使用-lgl打开一个与OpenGL无关的程序,当我升级并且我不得不将-lgl移动到命令行的末尾时,它也破坏了。我可能会发现我的几十个程序不再编译。为什么这会改变?我的新系统有问题还是现在的样子?请注意,这些是普通的共享库,而不是静态链接。

我能做些什么让GCC回归旧方式,图书馆的顺序无关紧要?有没有其他方法可以说服GCC正确链接libstdc++而不在命令行上的.o文件后移动它?

1 个答案:

答案 0 :(得分:12)

如果Mercury将目标文件放在库之后,Mercury就会被破坏。库属于目标文件 - 总是如此。您有时可能会违反相反的顺序,但不可靠。 (静态库必须跟在静态库中引用符号的目标文件之后。有时,链接器会记录共享库定义的符号,即使没有使用任何符号;有时,链接器只会记录共享库符号如果共享库提供至少一个符号。)