【问题标题】:why does cmake compiles everything after git commit为什么cmake在git commit之后编译所有内容
【发布时间】:2015-11-30 13:22:59
【问题描述】:

假设我有一段时间在 linux 上使用 cmake 2.8 编译代码。

我更改了一个文件“my_changed_file”,运行 cmake,只构建了这个文件。到目前为止一切顺利。

现在我想提交这个:

git add my_changed_file
git commit

如果我再次运行 cmake,我预计不会发生任何事情。但是我所有的文件都被重新编译了,尽管我什么都没碰!当我执行 ls -l 时,时间戳似乎没有受到影响。

我确实有以下几行:

execute_process(
  COMMAND git describe --abbrev=8 --dirty --always --tags
  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
  OUTPUT_VARIABLE GIT_CODE_VERSION
  OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions("-DCODE_VERSION=${GIT_CODE_VERSION}")

但它只影响文件main.cpp

发生了什么?

谢谢

【问题讨论】:

    标签: git compilation cmake


    【解决方案1】:

    CMake 不跟踪,哪个源文件会受到特定编译定义的影响。当编译定义更改时,CMake 假定所有源都应该重新构建

    更好的方法是使用配置的头文件。因此,当此文件的内容发生更改时,只会重新编译包含此文件的那些源(直接或间接):

    version.h.in

    #define CODE_VERSION @GIT_CODE_VERSION@
    

    ma​​in.cpp

    #include "version.h"
    ...
    

    CMakeLists.txt

    # Calculate value of variable GIT_CODE_VERSION
    ...
    configure_file("version.h.in" "version.h")
    

    configure_file 的好处是,如果它的 content 不会改变,它不会更新结果文件的时间戳。所以,如果你在没有git commit 的情况下重新运行cmake,那么在下一次构建时不会重新编译任何内容。只有在 git commit 之后重新运行 cmake 才会强制 main.cpp 文件(并且只有它)在下一次构建时重新编译。


    另一种方法是在特定源文件上使用COMPILE_DEFINITIONS 属性,而不是目标范围的属性(受add_definition() 调用影响):

    set_property(SOURCE main.cpp APPEND
        PROPERTY COMPILE_DEFINITIONS "-DCODE_VERSION=${GIT_CODE_VERSION}")
    

    构建系统会检测到通过cmake调用更改此属性,因此下一次构建将重新编译main.cpp,并且只有它。

    不幸的是,这种方法在生成文件生成器的情况下无法按预期工作:即使针对特定源更改了编译定义,所有源(针对同一目标)也将重新构建。这是known limitation

    【讨论】:

    • 嗨。我尝试用 set_property 添加或替换我的 add_definition,但它似乎并没有做太多。有什么不同的吗?应该放在某个地方吗?如果我没有指定 COMPILE_DEFINITIONS_$CONFIG,那么它适用于每个配置,对吗?谢谢
    • 我发现每个源的 COMPILE_DEFINITIONS 与 makefile 生成器(您使用的)无法按预期工作。但是有更好的方法使用配置头文件。我已经更新了我对那个案例的回答。
    • 为了进一步减少重新构建的内容,而不是每次 git 提交详细信息更改时重新生成标头,将@GIT_CODE_VERSION@ 放入一个实现文件(例如version.cpp.in)中一个简单的函数并复制该文件带有configure_file。然后,标头仅包含函数原型并且永远不会更改。结果将只是需要重新构建一个实现文件,而不是每个包含version.h 的文件。
    • @CraigScott:很好的提示。除非版本字符串只需要作为一个宏(例如,用于构造静态常量字符串),否则配置额外的源文件而不是头文件可以显着减少编译时间。
    猜你喜欢
    • 2011-07-07
    • 2015-09-19
    • 2019-05-14
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2021-08-10
    • 2011-02-14
    相关资源
    最近更新 更多