C ++链接器如何知道哪个.lib包含哪些函数?

时间:2011-03-03 18:26:52

标签: c++ boost linker

例如在Boost中。我在MSVC ++ 2010中将 include 目录设置为Boost根目录,并在源代码中有#include <boost/regex.hpp>。我将目录设置为boost\stage\lib,但其中有数百个文件 - 每个Boost库有几个文件,这些文件用于boost :: regex:

libboost_regex-vc100-s-1_46.lib
libboost_regex-vc100-mt-gd-1_46.lib
libboost_regex-vc100-mt-1_46.lib
libboost_regex-vc100-mt-s-1_46.lib
libboost_regex-vc100-mt-s.lib
libboost_regex-vc100-s.lib
libboost_regex-vc100-mt.lib
libboost_regex-vc100-mt-gd.lib

MSVC如何知道哪个lib文件是正确的?如果它扫描所有这些函数以获得正确的函数签名,那是否意味着从两个不同的源(彼此没有链接)编译的2个不同的lib碰巧定义了具有相同名称和参数的函数,不能在一个lib文件夹中?

它是如何知道在所有不同的正则表达式.lib中哪个是正确的?然后,文件名中1_46的每个文件似乎与相应的文件相同,我可以安全地删除其中一个吗?

3 个答案:

答案 0 :(得分:17)

boost库使用一些 dark magic 来选择要从头文件和编译器选项链接的库。我真的不知道所有的血腥细节,但您可以查看boost / config / auto_link.hpp标题以获取更多信息。

特别是,这似乎是一个重要的难题:

#  pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib")

答案 1 :(得分:4)

大多数lib个文件都有一个目录。链接器在查找符号时搜索此表。如果未找到符号,则会移动到下一个库,依此类推,直到搜索完所有库。

某些链接器可能决定从所有库中构建目录。该表将包含符号名称及其关联的库。这加快了符号的搜索速度。

搜索顺序取决于链接器的制造商。对此没有标准或要求。链接器可以按照命令行中指定的先到先得进行搜索; 指定的最后一个库或其他一些方法。查看文档以获取标准。

还在网上搜索name mangling。这是编译器用于解决符号命名冲突的技术。

最后,链接器可能包含库中的所有函数,即使只使用了一个函数。一些链接器仅包含该函数的代码。取决于Linker的制造商。例如,链接器在解析puts时是否包含整个I / O库,还是只包含必要的函数?包括整个库可以加快构建时间,但会使可执行文件变得庞大。仅包含必要的代码会减慢构建过程,但会缩小可执行文件的大小。

通常,链接阶段是翻译过程中较快的部分之一。如果您担心构建时间,请在一天结束时开始构建,或者在构建开始后去散步。 ; - )

答案 2 :(得分:2)

两个包含相同功能的库不是问题。链接器只查看它被告知要查看的库。如果其中两个它们包含相同的函数,它将给出一条错误消息(这实际上相当常见,通常是由于与标准库的静态和动态链接之间的冲突)。

您可以告诉链接器以多种方式查看哪些库 - 在链接器命令行上(可能由IDE生成)和通过#pragma comment(lib, "libname.lib")是最常见的两种方式。