23

为什么有些静态库(lib*.a)可以像链接共享库(lib*.so)一样链接(ld -l 开关),但有些不能?

我一直被教导说所有库,无论是否静态,都可以用 -l... 链接,但是到目前为止我已经遇到了一个库(GLFW),它除了会喷出“未定义的引用”链接错误之外什么也没做尝试以这种方式链接它。

根据对这个问题的回答,链接静态库的“正确”方法是将它们与我自己的目标文件一起直接包含,而不是使用 -l。而且,在 GLFW 库的情况下,这当然可以解决问题。但是我使用的所有其他静态库在与 -l 链接时都可以正常工作。

所以:

  • 是什么导致这个库在链接而不是直接包含时无法工作?如果我知道原因,也许我可以编辑并重新编译库来解决问题。
  • 您是否不应该像链接共享库一样链接静态库?(如果没有,为什么不呢?)
  • 当以这种方式直接包含库时,链接器是否仍然能够从输出可执行文件中消除未使用的库函数?
4

4 回答 4

25

感谢您的回复!原来问题是由于链接顺序。显然,如果您使用的库又具有其他库依赖项,则这些其他依赖项必须列库之后,而不是像我之前所做的那样。学到了新东西!

于 2012-04-01T21:26:00.353 回答
6

您是否愿意向 GCC 指明您的库的路径(使用 -L)?通过单独使用 -l,GCC 将只能链接标准目录中可用的库。

-L[path] -l[lib]
于 2012-03-31T01:29:05.927 回答
6

链接静态库的正确方法是使用 -l,但只有在可以在搜索路径上找到库时才有效。如果不是,那么您可以使用 -L 将目录添加到列表中,或者按名称命名文件,如您所说。

实际上,共享库也是如此,尽管它们更有可能被发现。

于 2012-03-31T13:02:59.500 回答
1

原因是历史的。“ar”工具最初是 PDP11 unix 上的文件归档工具,但后来为了这个目的它被完全替换为“tar”。它将文件(在本例中为目标文件)存储在一个包中。还有一个单独的扩展,其中包含供链接器使用的符号表。如果您手动管理存档中的文件,则符号表可能会过时。

简短的回答是您可以在任何存档上使用“ranlib”工具来重新创建符号表。试试看。更广泛地说,尝试找出损坏的库的来源并修复它。

于 2012-03-31T04:34:59.043 回答