Den tors 11 okt. 2018 kl 18:28 skrev Matt Schulte <schultetw...@gmail.com>: > > 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.
We have something like this in MyAppVersion.cmake: find_package(Git QUIET REQUIRED) execute_process( COMMAND "${GIT_EXECUTABLE}" describe --always HEAD WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE res OUTPUT_VARIABLE MYAPP_VERSION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) set_property(GLOBAL APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/.git/index") string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+).*$" "\\1;\\2;\\3" _ver_parts "${MYAPP_VERSION}") list(GET _ver_parts 0 MYAPP_VERSION_MAJOR) list(GET _ver_parts 1 MYAPP_VERSION_MINOR) list(GET _ver_parts 2 MYAPP_VERSION_PATCH) if("${MYAPP_VERSION}" MATCHES "^.*-(.*)-g.*$") string(REGEX REPLACE "^.*-(.*)-g.*$" "\\1" MYAPP_VERSION_MICRO "${MYAPP_VERSION}") else() set(MYAPP_VERSION_MICRO "0") endif() and include it in our CMakeLists.txt. That makes the output of `git describe` availabe in the MYAPP_VERSION CMake variable. The trick to make it always current is to append to CMAKE_CONFIGURE_DEPENDS the .git/index file, so that the project is re-configured if the Git index file is touched. Can't remember where I found this trick, but it has worked fine for us ever since. Elvis > On Thu, Oct 11, 2018 at 5:55 AM Michael Jackson > <mike.jack...@bluequartz.net> 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" > > <cmake-boun...@cmake.org on behalf of schultetw...@gmail.com> 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 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 > > > > > > > -- > > 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 -- 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