为什么在GCC中,库的链接顺序有时会导致错误?
当前回答
我已经见过很多次了,我们的一些模块链接了超过100个我们的代码库加上系统和第三方库。
根据HP/Intel/GCC/SUN/SGI/IBM/等不同的连接器,你可以得到未解析的函数/变量等,在某些平台上,你必须列出库两次。
在大多数情况下,我们使用库、核心、平台、不同抽象层的结构化层次结构,但对于某些系统,您仍然必须使用link命令中的顺序。
一旦你找到了一个解决方案,那么下一个开发人员就不必再做了。
我以前的老师常说,“高内聚低耦合”,今天依然如此。
其他回答
GNU ld链接器是所谓的智能链接器。它将跟踪之前静态库使用的函数,永久地从它的查找表中丢弃那些没有使用的函数。结果是,如果您过早地链接一个静态库,那么该库中的函数将不再对链接线上的静态库可用。
典型的UNIX链接器从左到右工作,因此将所有依赖的库放在左边,而满足这些依赖关系的库放在链接行的右边。您可能会发现一些库依赖于其他库,而同时其他库也依赖于它们。这就是事情变得复杂的地方。当涉及到循环引用时,修复您的代码!
我已经见过很多次了,我们的一些模块链接了超过100个我们的代码库加上系统和第三方库。
根据HP/Intel/GCC/SUN/SGI/IBM/等不同的连接器,你可以得到未解析的函数/变量等,在某些平台上,你必须列出库两次。
在大多数情况下,我们使用库、核心、平台、不同抽象层的结构化层次结构,但对于某些系统,您仍然必须使用link命令中的顺序。
一旦你找到了一个解决方案,那么下一个开发人员就不必再做了。
我以前的老师常说,“高内聚低耦合”,今天依然如此。
你可以使用-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
如果你在链接器标记中添加-Wl,——start-group,它不会关心它们的顺序,也不会关心是否存在循环依赖关系。
在Qt上,这意味着添加:
QMAKE_LFLAGS += -Wl,--start-group
节省了大量的时间,而且它似乎并没有降低链接的速度(无论如何,这比编译要少得多)。
另一种方法是两次指定库列表:
gcc prog.o libA.a libB.a libA.a libB.a -o prog.x
这样做,您不必为正确的序列而烦恼,因为引用将在第二个块中解析。
推荐文章
- Typedef定长数组
- 如何在C中抑制“未使用的参数”警告?
- libpthread.so。0:添加符号错误:命令行中缺少DSO
- 为什么GCC在实现整数除法时使用奇数乘法?
- g++对typeinfo的未定义引用
- 不能在Lion下安装Ruby与RVM - GCC问题
- 对负数的模运算
- 解决LNK4098: defaultlib 'MSVCRT'冲突
- “静态链接”和“动态链接”是什么意思?
- 什么是makeinfo,如何获取它?
- Clang vs GCC——哪个生成更快的二进制文件?
- 构造函数初始化列表求值顺序
- GCC转储预处理器定义
- 如何在Mac OS X 10.8 / Xcode 4.4上使用/安装gcc
- 如何禁用几行代码的GCC警告