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

发布于 2024-10-19 22:06:41 字数 748 浏览 1 评论 0原文

例如在Boost中。我将 MSVC++2010 中的 include 目录设置为 Boost 根目录,并在源代码中添加 #include 。我将 library 目录设置为 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 的文件似乎与不带 1_46 的相应文件相同,我可以安全地删除这两个文件之一吗?

For example in Boost. I set an include directory in MSVC++2010 to the Boost root directory and have an #include <boost/regex.hpp> in my source code. I set a library directory to boost\stage\lib but there are hundreds of files in there – several for each Boost library and these for 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

How does MSVC know which of all lib files is the right one? If it scans all of them for the right function signatures, does that mean that 2 different lib's compiled from two different sources (not linked to each other) which happen to define functions with identical names and parameters cannot be in one lib folder?

And how does it know which is right among all those different regex .lib's? And then, each file with 1_46 in its filename seems to be identical to the respective file without, can I safely delete one of the two?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

把时间冻结 2024-10-26 22:06:41

boost 库使用一些黑魔法来从标头和编译器选项中选择要链接的库。我真的不知道所有的细节,但是您可以查看 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")

The boost libraries use some dark magic to select the libraries to link from the headers and compiler options. I don't really know all the gory details, but you can take a look at the boost/config/auto_link.hpp header for extra information.

In particular, this seems to be an important piece of the puzzle:

#  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")
灯下孤影 2024-10-26 22:06:41

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

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

搜索顺序取决于链接器的制造商。对此没有标准或要求。链接器可以按命令行上指定的先来先服务进行搜索; 最后指定的库或其他方法。检查文档中的标准。

还可以在网络上搜索名称修改。这是编译器用来解决符号命名冲突的技术。

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

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

Most lib files have a Table Of Contents. The linker searches this table when it is looking for a symbol. If the symbol is not found it moves on to the next library, and so on, until all libraries have been searched.

Some linkers may decide to build a table of contents from all the libraries. This table would contain the symbol name and the library it is associated with. This speeds up the searches for symbols.

The search order depends on the manufacturer of the linker. There is no standard nor requirements for this. A linker may search by first come, first served as specified on the command line; last library specified or some other method. Check the documentation for the criteria.

Also search the web for name mangling. This is a technique that compilers use to resolve symbol naming conflicts.

Lastly, linkers may include all the functions in a library even if only one is used. Some linkers only include the code for the function. Depends on the manufacturer of the Linker. For example, does the linker include the entire I/O library when resolving puts or does it just include the necessary functions? Including the whole library speeds up build time but makes the executable huge. Including only necessary code slows the build process but shrinks the executable size.

In general, the Linking Phase is one of the faster parts of the translation process. If you are worried about build times, start the build at the end of the day or go for a walk after the build is started. ;-)

隐诗 2024-10-26 22:06:41

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

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

Two libraries containing identical functions isn't a problem. The linker only looks at the libraries that it's told to look at. If two of them contain identical functions, it'll give an error message (this is actually fairly common, usually due to conflict between static and dynamic linking with the standard library).

You can tell the linker which libraries to look at in a number of ways -- on the linker command line (possibly as generated by the IDE) and via #pragma comment(lib, "libname.lib") are the two most common though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文