Jan*_*roň 8 c c++ mingw compilation
几年前,我问了一个如何减少可执行文件大小的问题.使用MinGW编译器,剥离符号(-s选项)有助于减少50%+的大小.
为什么剥离不是默认的 - 有什么理由不在某些情况下剥离符号呢?我想更深入地理解它:今天,我只是模糊地知道链接库中涉及符号.它们是否需要可执行文件,它们是否会影响执行速度?
MinGW是"Minimalist GNU for Windows"的首字母缩写; 因此,编译器套件是GCC ...... GNU编译器集合.当然,这个编译器套件倾向于遵守GNU编码标准,它要求每个构建都应该是"调试版本"......即它应包括调试符号和链接所需的符号.(这是合乎逻辑的,因为"调试版本"对于应用程序开发人员而言比对所谓的"版本构建"更有用.此外,区分"调试构建"和"发布构建"模式的构建系统比仅关注"调试构建"的构建系统更复杂 - 可能更加复杂.
在GNU构建模型中,无论如何都不需要"发布版本".在构建时不会创建"发布"; 它是在安装时创建的 - 通常作为"分阶段"安装,从中创建发布包.GNU工具链包括一个strip命令和一个install命令,它可以动态地剥离"调试版本",当创建一个分段安装作为发布包装时(或者如果你愿意的话,就到位),所以真的不需要使用"发布版本"细节使构建系统混乱; 只需在前面创建一个"调试版本",然后在事件之后将其删除,以便在需要时将其转换为有效的"版本构建".
由于你的MinGW工具链基本上是一个GNU工具链,它完全支持这个GNU构建模型.
我无法想象他们影响了执行速度在任何明显的方式虽然,在理论上,你可以有一个微小的高速缓存未命中的过程映像中的量.
您希望在调试时将符号保留在文件中,以便您可以查看您所在的函数,检查变量的值等等.
但符号使文件较大:可能,一个很多大.因此,您不希望将二进制文件中的符号放在小型嵌入式设备上.(我说的是一个真正的嵌入式设备,而不是21世纪的Raspberry Pi,拥有9,000GB的存储空间!)
我通常剥离所有发布版本,不剥离任何调试版本.这使得来自客户的核心转储变得不那么有用,但是您可以随时保留未经剥离的发布版本的副本,并针对此调试您的核心.
我确实听说过一家公司,即使在发布版本中也有从不剥离符号的策略,因此他们可以将核心直接加载到调试器中.这看起来像是一个抽象泄漏给我,但无论如何.他们的电话.
当然,如果你真的想要,你可以在没有它们的情况下自己分析装配.但那太疯狂了......
没有充分的理由去掉符号。例如,通过剥离符号,您将消除收集进程堆栈的可能性-一种非常有用的功能。
编辑。这里的一些人似乎对调试符号和“通用”符号之间的区别感到困惑。只有在为编译器提供-g(或类似选项)选项时才生成第一个,并且通常仅在调试版本中使用(尽管也可以与优化版本一起使用)。常规符号是诸如函数名之类的东西,它们是由编译器生成的,以便可以链接目标文件或加载.so文件。有几种非常有用的非侵入性工具,可用于非调试运行的可执行文件,这取决于未剥离的符号。