2

我正在编译一个静态(阅读评论后添加静态)C++ 库 PoDoFo,它的一些依赖项是可选的,例如 libJPEG、libTiff 和 libPNG。但是,许多库也可以选择相互依赖。例如,您可以通过使用 libJPEG 编译 libTIFF 在 libTiff 中启用 JPEG 支持。

在一个完美的世界中,我希望 libTIFF 能够通过实现 libJPEG 访问来启用 libJPEG 功能,因为我将它包含在我的 PoDoFo 编译中。可悲的是,我认为启用/禁用功能是在我第一次编译 libTIFF 时决定的。

那么这意味着我的 PoDoFo 库将包含 libJPEG 多次,如果我使用同一个库,甚至可能是相同的副本。

GCC 编译器会意识到这一点并将库消除/重新链接到 libJPEG 的一个副本吗?

4

2 回答 2

2

基本上是的,它只会包含一份副本。

您正在更改的编译开关实际上并未将一个库包含到另一个库中,它们只是启用需要这些库的功能,例如,如果您启用 libJPEG 支持,libTIFF 可能包含在 jpeg 和 tiff 格式之间转换的功能,但允许您编译其余的如果您不想要,则可以使用没有该功能的库。

当您将最终应用程序与 PoDoFo 链接时,您还必须链接您启用的所有可选依赖项。对于动态库,这可以是自动的,但依赖项在运行时都是必需的。

在几乎所有情况下,每个库都只有一个与最终应用程序链接的副本 - 一个例外是如果您混合使用静态库和动态库,但这是一个全新的蠕虫罐。

于 2020-07-16T08:38:29.697 回答
0

假设所有库都是动态链接的,运行时链接器只会加载每个依赖库的单个副本(因此将加载 libJPEG 的单个副本)。

在一个完美的世界中,我希望 libTIFF 能够通过实现 libJPEG 访问来启用 libJPEG 功能,因为我将它包含在我的 PoDoFo 编译中,但遗憾的是,我认为启用/禁用功能是在我第一次编译 libTIFF 时决定的。

您描述的功能称为延迟加载,在 Windows 中受支持,但在 Linux 上不受支持(至少默认情况下不支持,请参阅Implib.so工具)。

于 2020-07-16T05:38:21.820 回答