C/C++ 编译器通常会删除重复的库吗?

Do C/C++ compilers typically remove duplicate libraries?

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

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

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

GCC 编译器是否会意识到这一点,并且 eliminate/relink 库只需要一个 libJPEG 副本?

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

In a perfect world I would hope that libTIFF would enable the libJPEG functions by realizing it has access to libJPEG because I included it in my compilation of PoDoFo, but sadly I think enabling/disabling functions is decided when I first compiled libTIFF.

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

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

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

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

在几乎所有情况下,每个库只有一个副本 link 与最终应用程序一起编辑 - 一个例外是如果您混合使用静态库和动态库,但那是一个全新的蠕虫病毒。