CMake会将包含的标头中的所有内容编译为可执行文件,还是仅将其编译为主类中使用的部分?

时间:2018-12-28 08:53:23

标签: c executable compiler-optimization filesize

我正在编写一个C程序,其中可执行文件大小的每一点都很重要。

例如,如果在我的程序中仅需要来自stdlib.h的printf(),那么包含标头实际上会导致该库中的所有内容都复制到CMake编译的可执行文件中吗?

2 个答案:

答案 0 :(得分:2)

CMake只是构建系统生成器。最终进入最终可执行文件的内容由链接器以及与之一起使用的选项决定。典型的链接器只会将它们可以确定的必要内容链接到可执行文件中,除非您要求它们链接所有内容。但是,它们可以减少占用的空间有一些限制。

经验法则是,如果您使用foo.o中的函数,则整个foo.o都将链接在一起;因此,如果大小优化是您的目标,则最好为每个函数提供自己的编译单元。

您使用的标题没有任何作用,因为标题是在编译时而不是在链接时处理的。

最后但并非最不重要:在标准库的大多数实现中,printf函数家族属于最重量级的函数,因此,如果您要进行beancounting,请不要使用它们。

答案 1 :(得分:0)

原则上,标头应为幂等,也就是说,如果不使用声明,则标头不应影响可执行文件。 stdlib.h仅应具有原型,预处理器宏定义和结构定义之类的内容,不应包含可执行代码或变量声明。

链接器根据需要包含

标准库 code 。但是,C运行时库库(RTL)可能将此代码包含在DLL或共享对象中,具体取决于您的平台。使用DLL(或等效文件)不会影响可执行文件的大小,但是当然会影响所使用的内存。由于DLL代码在进程之间共享,因此C RTL保留在内存中并不少见,但是,假设进行动态链接,则无论运行的C进程数量如何,都只有一个副本。大多数C RTL将为每个进程分配一些内存,但是多少取决于编译器/平台。