rpavlik/cmake-modules

`get_git_head_revision` forces full project recompile on every different commit

bwrsandman opened this issue · 9 comments

Description

Issue present in 77982ba

  • cmake version 3.22.2
  • Linux (Arch Distro)
  • MakeFile Generator

We're using get_git_head_revision in the following way:

# Include git hash in source
include(CMakeModules/GetGitRevisionDescription.cmake)
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
message(STATUS "Building ${CMAKE_PROJECT_NAME} GIT SHA1: ${GIT_SHA1}")

set_property(
  SOURCE ${CMAKE_CURRENT_LIST_DIR}/GitSHA1.cpp
  PROPERTY COMPILE_DEFINITIONS
    "GIT_SHA1=\"${GIT_SHA1}\""
)

It seems like for every different commit, instead of only recompiling changes + GitSHA1.cpp, our entire project is recompiled.

This makes it very annoying when doing things such as git bisect or rebases, or simply making new commits. It also wastes a lot of cycles.

How to reproduce

  1. Any project making use of get_git_head_revision in a way similar to the above snippet
  2. Compile the project once
  3. Compile it again: there should be nothing new to compile
  4. git commit --allow-empy -m "New SHA, no changes"

Current behaviour

Project reconfigures and will recompile every source file in project

Expected behaviour

Compiling the project once more should be like 3. above, except for only the files related to the SHA define recompiling

nmlt commented

I think the author explains here how to circumvent this problem: https://stackoverflow.com/a/4318642/15282333

Although I haven't been able to get it to work with my setup yet.

I'm not sure why that's happening, but I haven't added a definition in that way before. I typically use it to generate a source file instead, which does successfully avoid a full recompile on every build.

The stack overflow option uses a configure file command which would only be run at configuration time. This is undesirable because it would not update GitSHA1.cpp at build time like it does in my example. You would have to reconfigure your project every time you make a commit which is even worse.

well, any of the options using this module re-configure every time, that's more or less the key feature of this module? (that it triggers a re-configure on commit) If you just want to have it at build time, I guess you could call some of the functions from an add_custom_command()

Fair enough, however this is just a way to do the same without using template files. It should also be constrained to that one file thus not cause any other files to require rebuilding.

set_property(
  SOURCE ${CMAKE_CURRENT_LIST_DIR}/GitSHA1.cpp
  PROPERTY COMPILE_DEFINITIONS
    "GIT_SHA1=\"${GIT_SHA1}\""
)

I'm pretty sure this is not an issue with this module, but something with how you're using CMake. I agree that doesn't look like it should cause other rebuilds (though it will require and trigger reconfig), but it's not a use pattern I'm familiar with.

I'd happily review a suggested change to fix this, if it is in fact an issue with the module.

I'll come up with a repro case with both ways. If it is indeed my usage I'll close.

Really looks like it's related to set_property(SOURCE ... PROPERTY COMPILE_DEFINITIONS)
It's really disappointing that cmake forces a whole recompile if a compile definition changes on a single cpp file.

Yeah that sounds like it's probably a cmake bug, recommend reporting