举例说明这个 caveat:
假设你有两个库:libA.lib 和 libB.lib,它们都定义了一些符号,并且 libA.lib 依赖于 libB.lib 中的某些符号。
比如:
-
libA.lib里有一个对象文件A.obj,它用到了foo(),而foo()的实现只在libB.lib里。 -
你用如下顺序链接:
LINK.EXE main.obj libA.lib libB.lib
链接过程:
main.obj先被处理,假设它引用了A.obj里的某个函数。- 链接器处理
libA.lib,发现A.obj需要foo(),但此时foo()还未解析。 - 链接器会在
libA.lib里找foo(),找不到,就继续往后找,在libB.lib里找到了foo(),于是解析成功。
但如果你换个顺序:
LINK.EXE main.obj libB.lib libA.lib
- 处理
main.obj,没有foo()的引用。 - 处理
libB.lib,没有需要解析的符号。 - 处理
libA.lib,发现需要foo(),但链接器只会在libA.lib及其后面的库里找,而libB.lib已经处理过了,不会回头再查找。 - 结果:链接失败,提示
foo()未定义。
结论:
- 库的顺序很重要,依赖的库要放在被依赖库的后面。
- 链接器只会向后查找库,不会回头查找已经处理过的库。