#!/usr/bin/cmake -P # UpdateRevision.cmake # # Public domain. This program uses git commands command to get # various bits of repository status for a particular directory # and writes it into a header file so that it can be used for a # project's versioning. # Boilerplate to return a variable from a function. macro(ret_var VAR) set(${VAR} "${${VAR}}" PARENT_SCOPE) endmacro() # Populate variables "Hash", "Tag", and "Timestamp" with relevant information # from source repository. If anything goes wrong return something in "Error." function(query_repo_info) execute_process( COMMAND git describe --tags RESULT_VARIABLE Error OUTPUT_VARIABLE Tag ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT "${Error}" STREQUAL "0") ret_var(Error) return() endif() execute_process( COMMAND git log -1 "--format=%ai;%H" RESULT_VARIABLE Error OUTPUT_VARIABLE CommitInfo ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT "${Error}" STREQUAL "0") ret_var(Error) return() endif() list(GET CommitInfo 0 Timestamp) list(GET CommitInfo 1 Hash) ret_var(Tag) ret_var(Timestamp) ret_var(Hash) endfunction() # Although configure_file doesn't overwrite the file if the contents are the # same we can't easily observe that to change the status message. This # function parses the existing file (if it exists) and puts the hash in # variable "OldHash" function(get_existing_hash File) if(EXISTS "${File}") file(STRINGS "${File}" OldHash LIMIT_COUNT 1) if(OldHash) string(SUBSTRING "${OldHash}" 3 -1 OldHash) ret_var(OldHash) endif() endif() endfunction() function(main) if(NOT CMAKE_ARGC EQUAL 4) # cmake -P UpdateRevision.cmake message("Usage: ${CMAKE_ARGV2} ") return() endif() set(OutputFile "${CMAKE_ARGV3}") get_filename_component(ScriptDir "${CMAKE_SCRIPT_MODE_FILE}" DIRECTORY) query_repo_info() if(NOT Hash) message("Failed to get commit info: ${Error}") set(Hash "0") set(Tag "") set(Timestamp "") endif() get_existing_hash("${OutputFile}") if(Hash STREQUAL OldHash) message("${OutputFile} is up to date at commit ${Tag}.") return() endif() configure_file("${ScriptDir}/gitinfo.h.in" "${OutputFile}") message("${OutputFile} updated to commit ${Tag}.") endfunction() main()