2012-03-31 324 views
21

为什么一些静态库(lib * .a)可以像链接共享库(lib * .so)一样进行链接(ld -l switch),但有些不能?我总是被教导说,所有的库,静态或不是,都可以链接到-l ...,但是我到目前为止已经遇到了一个库(GLFW),它除了发送“未定义的引用”外什么都不做,链接错误,如果我尝试以这种方式链接它。使用GCC链接静态库的正确方法

根据对this question的响应,链接静态库的“正确”方式是将它们与我自己的目标文件一起直接包含进来,而不是使用-l。而且,就GLFW图书馆而言,这当然可以解决这个问题。但是,我使用的其他静态库在与-l链接时工作得很好。

所以:

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

回答

25

感谢您的回复!原来问题是由于链接顺序。显然,如果你使用一个库,而这个库又有其他的库依赖关系,那么这些其他的依赖关系必须在库后列出,而不是像我一直在做的那样。学到了新东西!

5

你有没有关心你的图书馆路径(使用-L)?通过仅使用-l,GCC将只能链接标准目录中可用的库。

-L[path] -l[lib] 
+0

是的,在相应的-l标志之前,使用-L提供每个库的路径。 GCC可以找到该库,但会在库中提供大量未定义的参考错误。 – Nairou 2012-03-31 01:40:33

1

原因是历史的。 “ar”工具原来是PDP11 unix上的文件归档工具,尽管后来它完全由“tar”替代。它将文件(在这种情况下为对象文件)存储在包中。还有一个单独的扩展包含链接器使用的符号表。如果您手动管理归档中的文件,符号表可能会过时,则可能会出现这种情况。

简短的回答是,您可以在任何归档中使用“ranlib”工具来重新创建符号表。试试看。更广泛地说,试图找出腐败的图书馆来自哪里并解决问题。

+2

我认为OP意味着链接*库,而不是创建一个库。 – ams 2012-03-31 12:54:08

5

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

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