库的大小和可执行文件

时间:2008-12-16 05:51:46

标签: static-libraries static-linking

我在Windows上使用MSVC创建了一个静态库* .lib。图书馆的大小是70KB。然后我有一个链接这个库的应用程序。但是现在最终可执行文件(* .exe)的大小是29KB,小于库。我想知道的是:

  1. 由于库是静态链接的,我认为它应该直接添加到可执行文件大小,最终的exe大小应该大于那个? Windows exe格式是否也对二进制数据进行了一些压缩?

  2. 对于linux系统来说,linux上的库(* .a / * .la文件)的大小与linux可执行文件(* .out)的大小有什么关系?

  3. -AD

7 个答案:

答案 0 :(得分:12)

Windows和Unix上的静态库是.obj / .o文件的集合。链接器查看每个目标文件,并确定程序是否需要链接。如果不需要,则目标文件不会包含在最终的可执行文件中。这可能会导致可执行文件比库小。

编辑:正如MSalters所指出的,在Windows上,VC ++编译器现在支持生成启用功能级链接的目标文件,例如,请参阅here。事实上,编辑和继续需要这样,因为编辑和继续需要能够替换可执行文件的最小可能部分。

答案 1 :(得分:5)

最终可执行文件不需要.lib文件中的其他簿记信息。此信息有助于链接器找到实际链接的代码。此外,调试信息可能存储在.lib文件中,但不存储在.exe文件中(我不记得在lib文件中为objs存储调试信息的位置,它可能在其他地方)。

答案 2 :(得分:4)

静态库可能包含几个从未使用过的函数。当链接器将库与主可执行文件链接时,它会发现某些函数从未使用过(并且它们的地址永远不会被捕获并存储在函数指针中),它只是抛弃了代码。它也可以递归地执行此操作:如果从不调用函数A(),并且A()调用B(),但从不调用B(),它可以删除A()和B()的代码。在Linux上,同样的事情发生了。

答案 3 :(得分:0)

免责声明:自从我处理静态链接以来已经很长时间了,所以我的回答很简单。

您写道:我认为它应该直接添加到可执行文件大小,最终的exe大小应该超过那个?

朴素的连接器就是这样工作的 - 当我为CP / M系统进行业余爱好开发时(很久以前),这是一个真正的问题。

然而,现代链接器更智能 - 它们只链接原始代码引用的函数,或者根据需要链接。

答案 4 :(得分:0)

除了当前的答案之外,如果链接器具有相同的目标代码,则允许它们删除函数定义 - 这有助于减少模板化代码的膨胀效应。

答案 5 :(得分:0)

静态库必须包含在其源代码中定义的每个符号,因为可能链接到只需要该特定符号的可执行文件。但是一旦它被链接到一个可执行文件中,我们就知道哪些符号最终被使用,哪些符号不被使用。因此,链接器可以轻松删除未使用的代码,大量修改文件大小。类似地,任何重复的符号(在静态库中定义的任何内容以及它链接到的可执行文件都会合并到一个实例中。

答案 6 :(得分:0)

@All:感谢指点。 @Greg Hewgill - 你的回答很好。感谢。

我发现的答案如下:

1.)在库构建期间发生的情况是,如果MSVC(或类似的东西)中的“保持程序调试数据库”选项为ON,则库将使此调试信息膨胀其大小。  但是当我静态地包含该库并创建一个可执行文件时,链接器会在对exe进行geenrating之前从库中删除所有调试信息,因此exe的大小小于库的大小。

2。)当我禁用“保存程序调试数据库”选项时,我得到了一个大小小于最终可执行文件的库,这是我认为在大多数情况下都是nromal。

-AD