Javatpoint标志
Javatpoint标志

c++中的静态库链接

介绍

静态库可以在编译时链接到程序中,它是c++中合并为单个文件的一组目标文件。在静态库中声明的所有变量和函数都包含在程序链接到静态库时生成的可执行文件中。我将在本文中深入探讨c++的静态库链接是如何工作的。

静态库:创建

静态库必须先构建,然后才能链接到程序。我们打算包含在库中的每个源文件都必须先编译,然后才能从中创建静态库。然后使用“ar命令”使用目标文件生成存档文件。在类unix系统上,归档文件的扩展名是"。,而在Windows系统上,它是。lib。

考虑这样一个场景:我们希望在一个名为libfoobar.a的静态库中包含两个源文件foo.cpp和bar.cpp。每个源文件首先被编译成一个目标文件:

然后可以使用"ar"命令创建存档文件:

因此,对象文件foo。0和1。这些文件被合并到一个名为libfoobar.a的归档文件中。

静态库链接

静态库的位置必须指定给编译器,然后才能将程序链接到它。使用-L选项和库所在的目录来完成此操作。库的名称也必须使用-l选项指定,但不带lib前缀或.a扩展名。

考虑一个名为main.cpp的程序,它使用libfoobar。以库为例。程序将按以下方式进行组装和连接:

这指示编译器将程序链接到libfoobar。一个库,并在当前目录中搜索它(-L。(-lfoobar)。

在静态库中声明的所有函数和变量都包含在最终的可执行文件中,当程序与它相链接时。这意味着如果库很大,可执行文件的大小可能会急剧增加。

符号的引用

当将程序链接到静态库时,链接器必须解析对静态库中声明的符号的任何引用。这是通过在库的目标文件中查找符号定义来完成的。

如果该符号有定义,则链接器将其包含在程序中,并在找到定义时更改符号表以引用该定义。如果链接器无法找到该符号的定义,则报告未定义符号错误。

例如,假设程序的main函数调用库libfoobar.a中定义的函数foo。当我们将应用程序链接到foo时,链接器会在库的目标文件中查找foo的定义。如果是,它将该定义添加到程序中,并修改符号表以包含对该定义的引用。如果无法找到定义,则报告一个未定义的符号错误。

链接顺序(链接顺序)

链接过程可能会受到在链接器命令行上给出目标文件和库的顺序的影响。目标文件和库通常应按独立性升序指定。

考虑一下程序main.cpp调用libfoo。A和图书馆。一个库。如果在库中描述的符号。libfoo使用的库。一个库,我们必须按适当的顺序识别库:

尽管main.cpp从两个库中调用函数,libfoo. cpp仍然可以调用libfoo. cpp。在这个例子中,库是在库之前提到的。一个图书馆。链接图书馆是必要的。首先要确保符号在使用之前被定义,因为libfoo。A依赖于libbar.a中定义的符号。

链接时间优化

一些链接器和编译器(LTO)支持链接时间优化。在链接阶段,LTO跨目标文件和库进行优化,这可以提高速度,减少代码。

为了启用LTO,我们必须首先使用-flto选项编译启用LTO的源文件:

使用-flto选项,我们可以链接启用了LTO的程序:

LTO可以极大地提高我们代码的性能,但它也会使链接花费更长时间并使用更多内存。此外,并非所有的链接器和编译器都支持LTO。

结论

我们已经讨论了c++的静态库链接是如何在这个响应中起作用的。我们已经看到了如何构建一个静态库,根据它链接一个程序,链接器如何处理符号引用,以及目标文件和库的排列如何影响链接。我们还讨论了链接时间优化,这可以使我们的程序运行得更快。


下一个话题 c++中的Constexpr





Youtube 视频加入我们的Youtube频道:现在加入

反馈


帮助别人,请分享

脸谱网 推特 pinterest

学习最新教程


准备


热门的技术


b .技术/马华






Baidu
map