做循环静态链接的LIB会导致更大的输出尺寸

Do circularly static linked libs result in a bigger output size?

本文关键字:输出 静态 循环 链接 LIB      更新时间:2023-10-16

我在C 中有多个静态库。例如:

  • lib a
  • lib b
  • lib c

lib a 使用 lib c lib c 使用 a b 两者都使用。我们在LIB之间具有循环依赖性。因为它们是静态液体的,如果它们是圆形的,则它们的输出尺寸更大,因为它们都包含在 b 中。 a 包含在 c c 中,代码在 b 中两次:(

有人可以向我解释这是如何工作的吗?

,如果 a b c 将链接到 d 将是 c 内部 d 也两次?

输出尺寸是否更大[链接多次时]?

no,可执行文件的输出大小不会随您的libs的顺序而变化,也不会随您指定libs的次数。

有人可以向我解释这是如何工作的吗?

创建可执行文件(而不是库)时:链接器通常在*.o文件粒度上链接,这意味着A *.o文件是否包含在可执行文件中。但是每个*.o文件仅包含在可执行文件中一次。这就是为什么大小没有差异的原因,即使您将lib链接了三遍。

,如果a,b和c将链接到d 也两次?

静态库通常不会连接在一起。它们只是作为新的ar存档一起重新包装。而且,与可执行的情况一样,每个 *.o文件仅存在新库(新的ar存档)中,因此即使您直接或间接添加了两次库,大小也不会变大。

降低可执行文件的大小:如果您担心可执行文件的大小并且正在使用GCC或LLVM,则有一种很好的方法可以减少它:

  • 告诉GCC将每个单独的功能都放入一个单独的部分:-ffunction-sections

  • 然后告诉链接到垃圾夹(丢弃)未使用的部分:-Wl,--gc-sections

令人惊讶的是,这不是默认值。如果没有这些选项,则在该*.o文件中的至少一件事中引用了整个*.o文件。未使用的*.o文件也始终被丢弃(除非提供了特定的选项),否则在功能级别上没有。

链接动态库(共享对象,DSO,无论您想称呼它们)再次是Unix系统上的另一件事,更复杂。

库在彼此之间不会静态链接;他们静态地链接到可执行文件。

因此,库彼此指的是什么都没关系。 lib a 永远不会包含 lib c 的副本(除了代码内部的可能性)。

构建可执行文件时,您的链接器也将仅拉一次。

但是,所述可执行文件将比您动态地链接这些库,而您使用相同库的所有其他可执行文件也将拥有自己的副本。那是在这里考虑的层。