我在C ++中有多个静态库。例如:
lib a 使用 lib c 和 lib c 使用 a 和 b 同时使用。库之间存在循环依赖关系。因为它们是静态库,所以如果它们是圆形的,则输出大小会更大,因为它们都包含在 b 中。 a 包含在 c 和 c 的代码中,代码两次出现在 b 中:((
有人可以解释一下这是怎么回事吗?
如果 a , b 和 c 将链接到 d ,则将是 d 里面也> c 两次?
答案 0 :(得分:2)
[多次链接时]输出大小是否更大?
否,可执行文件的输出大小不会随库的顺序而变化,也不会随您指定库的次数而变化。
有人可以解释一下这是怎么回事吗?
在创建可执行文件(而非库)时::链接程序通常以*.o
文件粒度进行链接,这意味着* .o文件是否包含在可执行文件中。但是每个*.o
文件仅在可执行文件中包含一次。这就是为什么即使您链接lib 3次,大小也没有差异的原因。
如果a,b和c将链接到d,则将是d中c的代码 也是两次吗?
静态库通常不链接在一起。它们只是重新打包在一起,成为一个新的ar
存档。而且,与可执行文件情况一样,每个* .o文件仅在新库(新的ar
档案)中保留一次,因此即使直接或间接添加两次库,大小也不会变大。
减小可执行文件的大小:如果您担心可执行文件的大小并且使用的是gcc或LLVM,则有一种不错的方法可以减小它:
告诉gcc将每个单独的函数放到一个单独的部分中:-ffunction-sections
然后告诉链接器以垃圾筒夹(丢弃)未使用的段:-Wl,--gc-sections
令人惊讶的是,这不是默认设置。如果没有这些选项,则如果引用了该*.o
文件中的至少一项内容,则整个*.o
文件将始终存在于可执行文件中。未使用的*.o
文件也总是会被丢弃(除非提供了特定的选项),但不会在功能级别上。
在UNIX系统上,链接动态库(共享对象,DSO,无论您想调用它们什么)都是另一回事,而且更加复杂。
答案 1 :(得分:1)
库之间不会静态链接;它们会静态链接到可执行文件。
因此,什么库相互引用都没有关系- lib a 绝不会包含 lib c 的副本(除了代码内联的可能性)。
您的链接器在构建可执行文件时,也只会拉入每个依赖库一次。
但是,所说的可执行文件将比如果您动态地链接这些库时的可执行文件大,并且使用相同库制作的其他所有可执行文件也将拥有它们自己的副本。这是要在这里考虑的层。