代码之家  ›  专栏  ›  技术社区  ›  Raed Addala

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

  •  0
  • Raed Addala  · 技术社区  · 2 年前

    当构建我的C++项目时,我会使用一个bash文件,其中包含所需的所有指令。 这并没有什么问题,因为我做的所有项目都相对较小。

    在我的上一个项目中,构建时间大约需要4-6分钟,所以我换成了CMake。 第一次构建很慢,但接下来的所有构建都相对较快。

    我的问题是: 只编译更改后的文件是CMake为缩短构建时间而进行的唯一优化吗? 此外: CMake如何跟踪文件中的更改?它如何决定是否重新编译文件?

    我想也许它可以节省上次构建的时间,所以可以检查文件的上次修改时间,并将其与节省的时间进行比较。然而,我想知道它的确切答案。

    1 回复  |  直到 2 年前
        1
  •  2
  •   starball Martin Jorgensen    2 年前

    我已经谈到这个了 here 在“CMake是否跟踪标头依赖项?”下。

    CMake是一个构建系统 generator 跟踪需要重新生成的更改通常是(生成的)构建系统的工作。据我所知,CMake曾经做过一些这方面的工作,但在后来的版本中,它开始更多地依赖构建系统和编译器来完成这项工作。请参见示例 the CMAKE_DEPENDS_USE_COMPILER variable ,在版本3.20中添加。CMake的平台/编译器内置部分中有一些相关的未记录变量 DEPFILE “以他们的名义 the Modules code

    如果您想了解CMake支持的特定构建系统,请参阅该构建系统的文档,其中可能包含也可能不包含此类信息。例如 the Ninja docs have a section on header dependencies ,其中声明:

    为了获得C/C++标头依赖项(或以类似方式工作的任何其他构建依赖项),正确的Ninja有一些额外的功能。

    头的问题是,给定源文件所依赖的文件的完整列表只能由编译器发现:不同的预处理器定义和包含路径会导致使用不同的文件。一些编译器可以在构建时发出这些信息,而Ninja可以利用这些信息来完善其依赖关系。

    关于这些编译器机制,例如,请参见 the GCC flags that start with -M .示例。

    -M :不输出预处理的结果,而是输出一个适合make的规则来描述主源文件的依赖关系。预处理器输出一个make规则,其中包含源文件的对象文件名、冒号和所有包含文件的名称,包括来自-include或-imacros命令行选项的文件名。

    至于构建系统如何知道文件何时发生了更改,通常构建系统会查看文件系统的时间戳。Ex。 from the Ninja docs :

    Ninja在精神和功能上最接近Make,依赖于文件时间戳之间的简单依赖关系。

    但这并不是说他们可以在技术上使用其他机制,比如内容哈希。

    CMake 跟踪编译器不适合或无法跟踪的其他类型的依赖项,例如 add_custom_command add_custom_target Craig Scott(CMake的维护者之一)有一篇相关的博客文章 here 如果你想要一些额外的相关阅读资料。CMake还负责处理一些事情,比如如果项目配置或 the CMake cache 已经改变。我非常确信它是通过在生成的构建系统中生成自定义规则来处理这些事情的。

        2
  •  2
  •   Pete Becker    2 年前

    Cmake是一个位于 make 公用事业 制作 比较文件日期和时间。如果对象文件比创建它的源文件和头文件更新 制作 什么也不做;如果对象文件较旧,则源文件或标头自上次编译以来已被修改,需要重新编译源文件。没有火箭科学。

    推荐文章