单个源代码与多个文件 + 库

Posted

技术标签:

【中文标题】单个源代码与多个文件 + 库【英文标题】:Single Source Code vs Multiple Files + Libraries 【发布时间】:2011-06-07 04:07:37 【问题描述】:

拥有多个文件或编译库与将所有内容 (>10,000 LOC) 放入一个源对最终二进制文件有多大影响?例如,我没有单独链接 Boost 库,而是将其代码连同我的原始源代码粘贴到一个巨大的文件中进行编译。在同一行中,不要将多个文件输入gcc,而是将它们全部粘贴在一起,然后只提供一个文件。

我对优化差异感兴趣,而不是维护一个庞大比例的单一源文件会带来的问题(恐怖)。

当然,只能有链接时优化(我可能错了),但是优化可能性之间有很大区别吗?

【问题讨论】:

我不确定我是否理解这个问题 - 您是根据您是否拥有一个巨大的源文件还是多个源文件来询问输出程序之间的区别? @Carl 我认为他的意思是链接预编译单元而不是同时将所有内容提供给编译器。你能澄清一下吗,亚历克斯? 我已经改写了这个问题。希望对您有所帮助。 【参考方案1】:

如果编译器可以看到所有源代码,那么如果你的编译器打开了某种Interprocedural Optimization (IPO) 选项,它可以更好地优化。 IPO 不同于其他编译器优化,因为它分析整个程序;其他优化只关注单个函数,甚至单个代码块

这里有一些可以做的过程间优化,see here for more:

内联 不断传播 mod/ref 分析 别名分析 正向替换 常规键属性传播 部分死呼叫消除 符号表数据提升 死函数消除 整个程序分析

GCC supports this kind of optimization.

这种过程间优化可以用来分析和优化被调用的函数。

如果编译器看不到库函数的源代码,就不能做这样的优化。

【讨论】:

这是否意味着通过分别编译两个源文件,两个文件之间的函数调用不会获得这样的优化?例如,在gcc a.o b.o之前调用gcc -c a.c然后gcc -c b.c 一些编译器在链接步骤中提供了对所有目标文件执行优化的标志,因此不仅限于编译命令的源文件。使用此标志编译的目标文件中嵌入了分析信息,可以跨源文件和预编译文件进行过程间分析。这是在最后的链接步骤中完成的,因此源文件的编译不需要全部在单个编译中进行,可以在多个单独的编译中进行。但当然,这种单独的编译可能会阻止某些过程间优化。【参考方案2】:

请注意,一些现代编译器(clang/LLVM、icc 和最近的 gcc)现在支持链接时间优化 (LTO),以最大限度地减少单独编译的影响。因此,您可以获得单独编译(维护、更快编译等)和整个程序分析的好处。

顺便说一句,gcc 似乎从 4.1 版开始就支持 -fwhole-program 和 --combine 了。不过,您必须将所有源文件一起传递。

最后,由于 BOOST主要是#included 的头文件(模板),因此您无法通过将这些添加到源代码中获得任何好处。

【讨论】:

以上是关于单个源代码与多个文件 + 库的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GitHub 中管理单个存储库下的多个存储库

如何在Doctrine2中为单个实体使用多个存储库?

常用动态链接库的DLL都有哪些?

Dll文件是啥?

高手解释一下.dll是啥?

单个 .jks 文件包含多个 SAML 应用程序的密钥库