为什么在GCC中,库的链接顺序有时会导致错误?
当前回答
如果你在链接器标记中添加-Wl,——start-group,它不会关心它们的顺序,也不会关心是否存在循环依赖关系。
在Qt上,这意味着添加:
QMAKE_LFLAGS += -Wl,--start-group
节省了大量的时间,而且它似乎并没有降低链接的速度(无论如何,这比编译要少得多)。
其他回答
下面是一个示例,可以清楚地说明涉及静态库时GCC是如何工作的。让我们假设我们有以下场景:
myprog。包含O的main()函数,依赖于libmysqlclient Libmysqlclient -静态的,对于这个例子来说(当然,你更喜欢共享库,因为Libmysqlclient非常大);在/usr/local/lib;并且依赖于来自libz的东西 libz(动态)
我们如何把它们联系起来?(注:使用gcc 4.3.4在Cygwin上编译的示例)
gcc -L/usr/local/lib -lmysqlclient myprog.o
# undefined reference to `_mysql_init'
# myprog depends on libmysqlclient
# so myprog has to come earlier on the command line
gcc myprog.o -L/usr/local/lib -lmysqlclient
# undefined reference to `_uncompress'
# we have to link with libz, too
gcc myprog.o -lz -L/usr/local/lib -lmysqlclient
# undefined reference to `_uncompress'
# libz is needed by libmysqlclient
# so it has to appear *after* it on the command line
gcc myprog.o -L/usr/local/lib -lmysqlclient -lz
# this works
链接顺序确实很重要,至少在某些平台上是如此。我曾见过应用程序以错误的顺序与库链接而导致崩溃(错误意味着A在B之前链接,但B取决于A)。
一个让我绊倒的小技巧:如果你以“gcc”或“g++”来调用链接器,那么使用“——start-group”和“——end-group”不会将这些选项传递给链接器——也不会标记错误。如果你的库顺序是错误的,它将失败的链接与未定义的符号。
你需要把它们写成"-Wl,——start-group"等来告诉GCC将参数传递给链接器。
另一种方法是两次指定库列表:
gcc prog.o libA.a libB.a libA.a libB.a -o prog.x
这样做,您不必为正确的序列而烦恼,因为引用将在第二个块中解析。
你可以使用-Xlinker选项。
g++ -o foobar -Xlinker -start-group -Xlinker libA.a -Xlinker libB.a -Xlinker libC.a -Xlinker -end-group
几乎等于
g++ -o foobar -Xlinker -start-group -Xlinker libC.a -Xlinker libB.a -Xlinker libA.a -Xlinker -end-group
小心!
团队内部的顺序很重要! 这里有一个例子:调试库有一个调试例程,但是非调试例程 库有一个相同的弱版本。必须放置调试库 组中的FIRST,否则将解析为非调试版本。 您需要在组列表中的每个库之前加上-Xlinker