C++构建系统如何跟踪源文件中的更改?

o8x7eapl  于 2023-08-03  发布在  其他
关注(0)|答案(2)|浏览(135)

在构建我的C++项目时,我会使用一个bash文件,其中包含所需的所有指令。这并不是什么问题,因为我做的所有项目都相对较小。
在我的上一个项目中,构建时间大约需要4-6分钟,所以我切换到了CMake。第一个版本很慢,但接下来的版本相对较快。
我的问题是:**CMake是否只对修改过的文件进行编译,这是它唯一的优化,以缩短构建时间?**另外:CMake如何跟踪文件中的更改?它如何决定是否重新编译一个文件?
我想也许它节省了上次构建的时间,所以检查文件的最后修改时间并将其与保存的时间进行比较。但是我想知道它的确切答案。

brgchamk

brgchamk1#

我已经在“CMake是否跟踪头依赖关系?”下面提到了这个here。“.
CMake是一个构建系统generator。跟踪需要重建的更改通常是(生成的)构建系统的工作。据我所知,CMake曾经做过一些这样的工作,但在后来的版本中开始更多地依赖于构建系统和编译器来做这件事。例如the CMAKE_DEPENDS_USE_COMPILER variable,它是在3.20版本中添加的。在CMake的平台/编译器内置部分中有一些相关的未记录变量,如果您想通过the Modules code进行探索,它们的名称中包含“DEPFILE”。
如果你想了解CMake支持的特定构建系统,请查阅该构建系统的文档,其中可能包含也可能不包含此类信息。例如,Ninja文档中有一节是关于头依赖性的,其中指出:
要获得C/C++头文件依赖项(或任何其他以类似方式工作的构建依赖项),Ninja有一些额外的功能。
头文件的问题在于,给定源文件所依赖的完整文件列表只能由编译器发现:不同的预处理器定义和包含路径导致使用不同的文件。一些编译器可以在构建时发出这些信息,Ninja可以使用这些信息来完善其依赖关系。
至于那些编译器机制,例如,参见the GCC flags that start with -M。前任
-M:不输出预处理的结果,而是输出一个适合make的规则,描述主源文件的依赖关系。预处理器输出一个make规则,其中包含源文件的对象文件名、冒号和所有包含文件的名称,包括来自-include或-imacros命令行选项的文件。
至于构建系统如何知道文件何时发生更改,通常构建系统会查看文件系统时间戳。关于Ninja Docs:
Ninja在精神和功能上最接近Make,依赖于文件时间戳之间的简单依赖关系。
但这并不是说他们可以在技术上使用其他机制,如内容哈希。
CMake * 确实 * 跟踪编译器不适合或无法跟踪的其他类型的依赖项,例如add_custom_commandadd_custom_target中的依赖项。克雷格Scott(CMake维护者之一)有一个相关的博客here,如果你想要一些额外的相关阅读。CMake还负责一些事情,比如如果项目配置或the CMake cache发生了更改,则知道何时进行重建。我很确定它是通过在生成的构建系统中生成自定义规则来处理这些事情的。

qni6mghb

qni6mghb2#

Cmake是位于make实用程序之上的shell。make比较文件日期和时间。如果目标文件比源文件新,则从make创建的头文件不执行任何操作;如果目标文件较旧,则源文件或头文件自上次编译以来已被修改,并且源文件需要再次编译。没有火箭科学。

相关问题