【问题标题】:Compile and link .h header files which many .c source programs use编译和链接许多 .c 源程序使用的 .h 头文件
【发布时间】:2013-12-09 15:12:29
【问题描述】:

我在一个团队工作,我们的测试桶有数百个 .c 源程序。 .c 程序相当小,它们都包含相同的 10 个 .h 头文件。这些 .h 文件相当大。

每次我们获得一个新的库文件来链接我们的测试程序以进行测试时,我们都会运行一个脚本来重新编译并运行我们的测试桶。问题是编译需要相当长的时间,特别是如果环境是虚拟的。

有没有办法编译 .h 头文件一次,放入一个单独的目标文件并让那些许多 .c 源文件链接到所述目标文件?我认为这将加快编译时间。我愿意更改/删除 .c 源程序中的所有#include。

非常感谢任何关于加快编译时间的建议。

另外,我应该说一个脚本执行一个makefile PER .c 源测试程序!不告诉 makefile 编译当前目录中的所有程序。每个测试程序都被编译成自己的可执行文件。

【问题讨论】:

  • 头文件未编译。它们被#include 到 .c 文件中,然后编译。在大多数情况下,头文件只包含允许 .c 文件引用函数、结构、数据类型等的声明,而无需在该 .c 文件中定义它们。
  • @master_latch 不幸的是,创建头文件的程序员实际上编写了数千行实现代码。他们没有将其用于声明目的。 .h 文件中的代码是所有 .c 文件测试程序中使用的共享代码......所以,听起来“预编译头文件”可能是一个解决方案。或者可能创建一个包含 .h 头文件的虚拟 .c 文件并从中创建一个对象,然后所有 .c 文件都链接到该文件?
  • 哦,我明白了。我没有意识到预编译的头文件是一回事——但现在我想到了,我记得在 MSVS 中将它视为一个选项。很高兴有人能够回答您的问题!

标签: c gcc hyperlink header compilation


【解决方案1】:

您可以使用预编译的标头功能。见http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html

【讨论】:

  • 阅读超链接中的第一句话。这似乎正是我所需要的!非常感谢。
  • 只是一个更新。我做到了永虎所说的。编译时间从 982 秒变为 287 秒。快 3 倍多一点!
【解决方案2】:

您提出了进一步的建议以加快编译速度。

一种方法是使用ccache。基本上,ccache 会保留到目前为止已编译的目标文件的缓存,并在识别到再次编译相同的源文件时返回它们(而不是一遍又一遍地重新编译)。

使用起来应该很简单

  1. 安装 ccache
  2. 使用 ccache 为 gcc/cc/g++ 命令添加前缀

【讨论】:

  • 谢谢!你以前用过这个程序吗?如果测试程序中的源代码相同,而我们链接的库文件不同,是否还需要重新编译?有时我们没有任何源代码更改,需要针对不同的库文件进行测试。
  • 基本上,只有在代码(.c 或 .h)发生任何变化时才会重新编译。如果您仅将相同的 .o 链接到不同的 .so,它会重复使用缓存中的相同 .o。
【解决方案3】:

重写你的标题。剥离所有定义并留在标题中。剥离所有实现并放入新的.c。编译为库。与解决方案链接。在运行时系统上分发库。

【讨论】:

  • 我希望我能。回归桶的创建者不允许这样做,因为从所花费的时间中获得的收益并不能证明它是合理的。不过,您的建议绝对是正确的做法。谢谢!
  • @user3080362 哇,收获肯定证明了努力。事实证明,创作者不希望你证明他们的做法是错误的...... :) 我的建议,无论如何都要这样做。当您开始轻松地重用代码时,他们将不得不埋头并感到羞耻。另外,关于标头,它们应该没有实现,因为标头仅用于内容声明。实施过多会导致滥用和懒惰。
【解决方案4】:

如果我理解正确,库通常的工作方式是在目标文件(Linux 系统上的 .so ?)中使用预编译代码,同时提供用于项目的头文件( .h )。

当您编译时,#include <library.h> 指令会找到该标头并将其内容粘贴到正在编译的源文件中。然后,一旦源文件被编译,它就会链接到预编译的目标文件。这样,该库可以包含在大量项目中,而无需每次都从源代码编译。链接到库时唯一必须重新编译的部分是头文件中的(相对)少量代码,这实质上使库函数和变量可以访问源代码。

这意味着要大大加快编译速度,最好的办法是从 10 个 .h 文件中取出所有函数,而只在头文件中保留函数原型。在单独的 .c 源文件中拥有所有函数后,您可以将它们编译为目标文件(通常为 -c 标志)。然后,每当您需要针对您通常使用的 10 个头文件编译新程序时,您可以改为包含头文件的精简版本,并链接到预编译对象。由于只需要编译 .c 文件中的新代码,而不是头文件中的所有代码,因此该过程应该快得多。

【讨论】:

    猜你喜欢
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    相关资源
    最近更新 更多