Re: [CMake] Putting the git commit hash in a cmake variable
Ah, that's a good tip Elvis. The CONFIGURE_DEPENDS on the .git/index would do the trick. I can set that up for now. In the long run, its not that ideal because it forces a reconfigure on every commit (which is annoying for developers at their desk). My example above is actually a little more complex in real life. I just simplified it for this e-mail. We only append the git hash to our version string if we are on certain branches. So our version string doesn't change on feature branches. For now I think we'll bite the bullet and re-configure on every commit. I'll keep mulling over the how to set this up. Thanks for the idea! -Matt On Thu, Oct 11, 2018 at 12:26 PM Chuck Atkins wrote: > > >> COMMAND "${GIT_EXECUTABLE}" describe --always HEAD > > > git describe is nice way to do it since you can get a monotonic-ish > increasing version number > > >> >> string(REGEX REPLACE "^.*-(.*)-g.*$" "\\1" MYAPP_VERSION_MICRO >> "${MYAPP_VERSION}") >> ... >> set(MYAPP_VERSION_MICRO "0") > > > Only tangentially related, CMake commands and functions that deal with > version information refer to the 4th component as _TWEAK. > > - Chuck > -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: https://cmake.org/mailman/listinfo/cmake
Re: [CMake] Putting the git commit hash in a cmake variable
Thanks Isaiah and Michael. Both solutions work great if you just want to generate a header file that contains the git commit hash. I have seen these solutions before. I'd like to go a little farther and have the current commit hash available in a CMake variable. This means CMake must re-configure if the commit hash changes. That's what I have setup in my example above, but it only works with cmake 3.12 and ninja 1.8.2. I was curious if anyone else has tried to store the results of an command line tool in a variable and make sure its always up to date by forcing cmake to reconfigure if the output of the command no longer matches what is stored in that variable. On Thu, Oct 11, 2018 at 5:55 AM Michael Jackson wrote: > > You could use a custom_target() instead, where that target is a simple > shell/batch file that runs the needed git command and creates a simple header > file. Then your main executable/library targets are dependent on that > custom_target() so that it is run every time. We do something similar in our > project. I added some "smarts" to it to at least compare the new output with > the old output and only over write if they are different. > > -- > Michael Jackson | Owner, President > BlueQuartz Software > [e] mike.jack...@bluequartz.net > [w] www.bluequartz.net <http://www.bluequartz.net> > > On 10/10/18, 5:05 PM, "CMake on behalf of Matt Schulte" > wrote: > > Hi all, > > 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. > > ```cmake > execute_process( > COMMAND > git rev-parse --short HEAD > RESULT_VARIABLE > SHORT_HASH_RESULT > OUTPUT_VARIABLE > SHORT_HASH) > > # If running in script mode (this runs on every build) > if (CMAKE_SCRIPT_MODE_FILE) > if (EXISTS "${SHORT_HASH_FILE}") > file(READ ${SHORT_HASH_FILE} READ_IN_SHORT_HASH) > else() > set(READ_IN_SHORT_HASH "") > endif() > > if (NOT ("${READ_IN_SHORT_HASH}" STREQUAL "${SHORT_HASH}")) > message(STATUS "Short hash is out of date") > # This will update short_hash.txt, causing cmake to reconfigure > file(WRITE ${SHORT_HASH_FILE} ${SHORT_HASH}) > endif() > > # Else running as part of cmake configure > else() > set(SHORT_HASH_FILE ${CMAKE_CURRENT_BINARY_DIR}/short_hash.txt) > file(WRITE ${SHORT_HASH_FILE} ${SHORT_HASH}) > > # The trick here is to make sure short_hash.txt is listed as a > byproduct > add_custom_target( > git_short_hash > BYPRODUCTS > ${SHORT_HASH_FILE} > COMMAND > ${CMAKE_COMMAND} > "-DSHORT_HASH_FILE=${SHORT_HASH_FILE}" > "-P" "${CMAKE_CURRENT_LIST_FILE}" > COMMENT > "Re-checking short hash..." > VERBATIM > USES_TERMINAL) > > # This configure_file makes cmake reconfigure dependent on > short_hash.txt > configure_file(${SHORT_HASH_FILE} ${SHORT_HASH_FILE}.junk COPYONLY) > > message(STATUS "Short Hash: ${SHORT_HASH}") > endif() > ``` > > This works great with cmake 3.12 and ninja 1.8.2! (I was really happy > with how well it worked. I tip my hat to
[CMake] Putting the git commit hash in a cmake variable
Hi all, 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. ```cmake execute_process( COMMAND git rev-parse --short HEAD RESULT_VARIABLE SHORT_HASH_RESULT OUTPUT_VARIABLE SHORT_HASH) # If running in script mode (this runs on every build) if (CMAKE_SCRIPT_MODE_FILE) if (EXISTS "${SHORT_HASH_FILE}") file(READ ${SHORT_HASH_FILE} READ_IN_SHORT_HASH) else() set(READ_IN_SHORT_HASH "") endif() if (NOT ("${READ_IN_SHORT_HASH}" STREQUAL "${SHORT_HASH}")) message(STATUS "Short hash is out of date") # This will update short_hash.txt, causing cmake to reconfigure file(WRITE ${SHORT_HASH_FILE} ${SHORT_HASH}) endif() # Else running as part of cmake configure else() set(SHORT_HASH_FILE ${CMAKE_CURRENT_BINARY_DIR}/short_hash.txt) file(WRITE ${SHORT_HASH_FILE} ${SHORT_HASH}) # The trick here is to make sure short_hash.txt is listed as a byproduct add_custom_target( git_short_hash BYPRODUCTS ${SHORT_HASH_FILE} COMMAND ${CMAKE_COMMAND} "-DSHORT_HASH_FILE=${SHORT_HASH_FILE}" "-P" "${CMAKE_CURRENT_LIST_FILE}" COMMENT "Re-checking short hash..." VERBATIM USES_TERMINAL) # This configure_file makes cmake reconfigure dependent on short_hash.txt configure_file(${SHORT_HASH_FILE} ${SHORT_HASH_FILE}.junk COPYONLY) message(STATUS "Short Hash: ${SHORT_HASH}") endif() ``` This works great with cmake 3.12 and ninja 1.8.2! (I was really happy with how well it worked. I tip my hat to the cmake developers for this). However, it doesn't work with Makefiles, and causes ninja 1.7.2 to get stuck in an infinite loop. On CMake 3.10 this will cause ninja 1.8.2 to generate a warning about a loop. Has anyone run into this issue before and have a better solution? Or is trying to execute a command before cmake checks if it should reconfigure a hack that should never be done? Thanks for the help! Matt -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: https://cmake.org/mailman/listinfo/cmake