如何创建库?

新手上路,请多包涵

假设我有 10 个 *.hpp 和 *.cpp 文件需要编译代码。我知道对于许多不同的代码,我需要这些相同的文件。我可以用那些允许我简单地编写的文件创建一个“包”:

 #include <mypackage>

代替:

 #include "file1.hpp"
#include "file2.hpp"
...
#include "file10.hpp"

每次我需要这个“包”时,我都不需要编写一个makefile。

更准确地说,我使用 Linux。

原文由 PinkFloyd 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 723
2 个回答

一组 CPP 源(H 文件和 CPP 文件)可以一起编译到一个“库”中,然后可以在其他程序和库中使用。如何做到这一点的细节是平台和工具链特定的,所以我留给你去发现细节。但是,我将提供几个链接,您可以阅读:

使用 gnu 编译器 [gcc] 创建一个共享的静态库

演练:创建和使用动态链接库 (C++)

库可以分为两种类型:源代码库和二进制库。也可以是这两种类型的混合体——一个库既可以是源库,也可以是二进制库。源代码库就是:作为源代码分发的代码集合;通常是头文件。大多数 Boost 库都属于这种类型。二进制库被编译成一个包,可由客户端程序运行时加载。

即使在二进制库的情况下(显然在源库的情况下),也必须向库的用户提供一个头文件(或多个头文件)。这告诉客户端程序的编译器要在库中查找哪些函数等。库编写者经常做的是一个单一的主头文件,它由库导出的所有内容的声明组成,客户端将 #include 该头文件。稍后,在二进制库的情况下,客户端程序将“链接”到该库,这会将标头中提到的所有名称解析为可执行地址。

编写客户端头文件时,请牢记复杂性。在很多情况下,您的一些客户只想使用您图书馆的一些部分。如果您编写一个包含库中所有内容的主头文件,您的客户端编译时间将不必要地增加。

处理此问题的常用方法是为库的相关部分提供单独的头文件。如果您将所有 Boost 视为一个库,那么 Boost 就是一个例子。 Boost 是一个庞大的库,但如果您想要的只是正则表达式功能,您只能 #include 与正则表达式相关的标头来获得该功能。如果你想要的只是正则表达式的东西,你不必包括 所有 的 Boost。

在 Windows 和 Linux 下,二进制库可以进一步细分为两种类型:动态和静态。在静态库的情况下,库的代码实际上被“导入”(因为没有更好的术语)到客户端程序的可执行文件中。静态库由您分发,但仅在编译步骤期间客户端需要。当您不想强迫您的客户必须使用他们的程序分发其他文件时,这很方便。它还有助于避免 依赖地狱。另一方面,动态库不是直接“导入”到客户端程序中,而是在客户端程序执行时动态加载。在多个程序使用同一个动态库的情况下,这既减少了客户端程序的大小,也可能减少了磁盘占用空间,但库二进制文件必须与客户端程序一起分发和安装。

原文由 John Dibling 发布,翻译遵循 CC BY-SA 3.0 许可协议

是和不是。

您可以编写一个包含所有标头,以便 #include "myLib.h" 就足够了,因为您通过单个标头包含所有这些标头。但是,这并不意味着单个包含足以将 10 个“.cpp”文件的内容自动链接到您的项目。您必须将它们编译成一个库并将该单个库(而不是所有目标文件)链接到使用“myLib.h”的项目。 Library binaries come as static and dynamic libraries, the files are typically named .lib and .dll (windows) and .a and .so (linux ) 分别用于静态和动态库。

如何构建和链接此类库取决于您的构建系统,您可能想在网上查找这些术语。

一种替代方法是通过在头文件中定义所有函数来摆脱 .cpp 文件。这样您就不必链接额外的库,但它的代价是增加了构建时间,因为每次您将标头直接或间接包含到您的翻译单元之一时,编译器都必须处理所有这些函数。

原文由 Arne Mertz 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题