为什么在GCC中,库的链接顺序有时会导致错误?


当前回答

如果你在链接器标记中添加-Wl,——start-group,它不会关心它们的顺序,也不会关心是否存在循环依赖关系。

在Qt上,这意味着添加:

QMAKE_LFLAGS += -Wl,--start-group

节省了大量的时间,而且它似乎并没有降低链接的速度(无论如何,这比编译要少得多)。

其他回答

另一种方法是两次指定库列表:

gcc prog.o libA.a libB.a libA.a libB.a -o prog.x

这样做,您不必为正确的序列而烦恼,因为引用将在第二个块中解析。

一个让我绊倒的小技巧:如果你以“gcc”或“g++”来调用链接器,那么使用“——start-group”和“——end-group”不会将这些选项传递给链接器——也不会标记错误。如果你的库顺序是错误的,它将失败的链接与未定义的符号。

你需要把它们写成"-Wl,——start-group"等来告诉GCC将参数传递给链接器。

链接顺序确实很重要,至少在某些平台上是如此。我曾见过应用程序以错误的顺序与库链接而导致崩溃(错误意味着A在B之前链接,但B取决于A)。

如果你在链接器标记中添加-Wl,——start-group,它不会关心它们的顺序,也不会关心是否存在循环依赖关系。

在Qt上,这意味着添加:

QMAKE_LFLAGS += -Wl,--start-group

节省了大量的时间,而且它似乎并没有降低链接的速度(无论如何,这比编译要少得多)。

GNU ld链接器是所谓的智能链接器。它将跟踪之前静态库使用的函数,永久地从它的查找表中丢弃那些没有使用的函数。结果是,如果您过早地链接一个静态库,那么该库中的函数将不再对链接线上的静态库可用。

典型的UNIX链接器从左到右工作,因此将所有依赖的库放在左边,而满足这些依赖关系的库放在链接行的右边。您可能会发现一些库依赖于其他库,而同时其他库也依赖于它们。这就是事情变得复杂的地方。当涉及到循环引用时,修复您的代码!