[CMake] Putting the git commit hash in a cmake variable
Ben Boeckel
ben.boeckel at kitware.com
Fri Oct 12 11:33:27 EDT 2018
Sorry if this shows up oddly on the list; I was forwarded the original
in order to reply. As such, please keep me in Cc.
> I'd like to set a CMake variable to the current git commit short hash.
> This variable will be used as part of the version string for my
> project (ex: "1.0.1+git.${SHORT_HASH}"). I can get at this short hash
> by using execute_process and setting the resulting output to a
> variable.
>
> ```cmake
> execute_process(
> COMMAND
> git rev-parse --short HEAD
> RESULT_VARIABLE
> SHORT_HASH_RESULT
> OUTPUT_VARIABLE
> SHORT_HASH)
> ```
>
> My issue is that cmake will only run execute_process once, during the
> configure step. I need cmake to run this execute_process on every
> build and, if the output has changed, reconfigure to make sure
> SHORT_HASH is up to date.
>
> I came up with one solution to this issue: During the configure step,
> I can write the current short hash to a file named short_hash.txt. On
> every build, I'll re-compute the short hash and verify that the
> computed short hash is the same as what is in short_hash.txt. If its
> not, I'll write the new short hash to short_hash.txt. I then make
> short_hash.txt an input to configure_file. This will cause cmake to
> validate SHORT_HASH is properly set, and re-configure if its not.
I solved this a few years ago :) . Here are all the relevant files:
https://github.com/Kitware/sprokit/blob/master/src/sprokit/version.h.in
https://github.com/Kitware/sprokit/blob/master/src/sprokit/.gitattributes
https://github.com/Kitware/sprokit/blob/master/src/sprokit/CMakeLists.txt
https://github.com/Kitware/sprokit/blob/master/conf/sprokit-macro-configure.cmake
Basically the solution follows:
- If we're in an archive (.gitattributes' export-subst), use the
information from it. Detect this in CMake by checking if Git
replaced substitutions for us:
if ("$Format:$" STREQUAL "")
If we are, just use that information (gathered using other
`$Format:$` expansions).
- If not, we set up some code to run at build time to extract the
information.
- The variables (or code) from above is injected via
`sprokit_configure_file_always` which basically is just a
`configure_file` done at build time. The list of variables to export
to the script are listed as arguments. The `_always` bit just adds
an extra output file named `${output}.noexist` which causes tools to
always run the associated custom command (which is then attached to
a custom target via its output file).
The file is only updated if the contents change (via `configure_file`),
so rebuilding should be minimal.
--Ben
More information about the CMake
mailing list