The open source OpenXR runtime
at main 297 lines 10 kB view raw
1# - Returns a version string from Git 2# 3# These functions force a re-configure on each git commit so that you can 4# trust the values of the variables in your build system. 5# 6# get_git_head_revision(<refspecvar> <hashvar> [ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR]) 7# 8# Returns the refspec and sha hash of the current head revision 9# 10# git_describe(<var> [<additional arguments to git describe> ...]) 11# 12# Returns the results of git describe on the source tree, and adjusting 13# the output so that it tests false if an error occurs. 14# 15# git_describe_working_tree(<var> [<additional arguments to git describe> ...]) 16# 17# Returns the results of git describe on the working tree (--dirty option), 18# and adjusting the output so that it tests false if an error occurs. 19# 20# git_get_exact_tag(<var> [<additional arguments to git describe> ...]) 21# 22# Returns the results of git describe --exact-match on the source tree, 23# and adjusting the output so that it tests false if there was no exact 24# matching tag. 25# 26# git_local_changes(<var>) 27# 28# Returns either "CLEAN" or "DIRTY" with respect to uncommitted changes. 29# Uses the return code of "git diff-index --quiet HEAD --". 30# Does not regard untracked files. 31# 32# Requires CMake 2.6 or newer (uses the 'function' command) 33# 34# Original Author: 35# 2009-2020 Rylie Pavlik <rylie@ryliepavlik.com> 36# https://ryliepavlik.com/ 37# 38# Copyright 2009-2013, Iowa State University. 39# Copyright 2013-2020, Rylie Pavlik 40# Copyright 2013-2020, Contributors 41# 42# SPDX-License-Identifier: BSL-1.0 43# 44# Distributed under the Boost Software License, Version 1.0. 45# (See accompanying file LICENSE_1_0.txt or copy at 46# http://www.boost.org/LICENSE_1_0.txt) 47 48if(__get_git_revision_description) 49 return() 50endif() 51set(__get_git_revision_description YES) 52 53# We must run the following at "include" time, not at function call time, 54# to find the path to this module rather than the path to a calling list file 55get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) 56 57# Function _git_find_closest_git_dir finds the next closest .git directory 58# that is part of any directory in the path defined by _start_dir. 59# The result is returned in the parent scope variable whose name is passed 60# as variable _git_dir_var. If no .git directory can be found, the 61# function returns an empty string via _git_dir_var. 62# 63# Example: Given a path C:/bla/foo/bar and assuming C:/bla/.git exists and 64# neither foo nor bar contain a file/directory .git. This wil return 65# C:/bla/.git 66# 67function(_git_find_closest_git_dir _start_dir _git_dir_var) 68 set(cur_dir "${_start_dir}") 69 set(git_dir "${_start_dir}/.git") 70 while(NOT EXISTS "${git_dir}") 71 # .git dir not found, search parent directories 72 set(git_previous_parent "${cur_dir}") 73 get_filename_component(cur_dir "${cur_dir}" DIRECTORY) 74 if(cur_dir STREQUAL git_previous_parent) 75 # We have reached the root directory, we are not in git 76 set(${_git_dir_var} 77 "" 78 PARENT_SCOPE) 79 return() 80 endif() 81 set(git_dir "${cur_dir}/.git") 82 endwhile() 83 set(${_git_dir_var} 84 "${git_dir}" 85 PARENT_SCOPE) 86endfunction() 87 88function(get_git_head_revision _refspecvar _hashvar) 89 _git_find_closest_git_dir("${CMAKE_CURRENT_SOURCE_DIR}" GIT_DIR) 90 91 if("${ARGN}" STREQUAL "ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR") 92 set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR TRUE) 93 else() 94 set(ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR FALSE) 95 endif() 96 if(NOT "${GIT_DIR}" STREQUAL "") 97 file(RELATIVE_PATH _relative_to_source_dir "${CMAKE_SOURCE_DIR}" 98 "${GIT_DIR}") 99 if("${_relative_to_source_dir}" MATCHES "[.][.]" 100 AND NOT ALLOW_LOOKING_ABOVE_CMAKE_SOURCE_DIR) 101 # We've gone above the CMake root dir. 102 set(GIT_DIR "") 103 endif() 104 endif() 105 if("${GIT_DIR}" STREQUAL "") 106 set(${_refspecvar} 107 "GITDIR-NOTFOUND" 108 PARENT_SCOPE) 109 set(${_hashvar} 110 "GITDIR-NOTFOUND" 111 PARENT_SCOPE) 112 return() 113 endif() 114 115 # Check if the current source dir is a git submodule or a worktree. 116 # In both cases .git is a file instead of a directory. 117 # 118 if(NOT IS_DIRECTORY ${GIT_DIR}) 119 # The following git command will return a non empty string that 120 # points to the super project working tree if the current 121 # source dir is inside a git submodule. 122 # Otherwise the command will return an empty string. 123 # 124 execute_process( 125 COMMAND "${GIT_EXECUTABLE}" rev-parse 126 --show-superproject-working-tree 127 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 128 OUTPUT_VARIABLE out 129 ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) 130 if(NOT "${out}" STREQUAL "") 131 # If out is empty, GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a submodule 132 file(READ ${GIT_DIR} submodule) 133 string(REGEX REPLACE "gitdir: (.*)$" "\\1" GIT_DIR_RELATIVE 134 ${submodule}) 135 string(STRIP ${GIT_DIR_RELATIVE} GIT_DIR_RELATIVE) 136 get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) 137 get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} 138 ABSOLUTE) 139 set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") 140 else() 141 # GIT_DIR/CMAKE_CURRENT_SOURCE_DIR is in a worktree 142 file(READ ${GIT_DIR} worktree_ref) 143 # The .git directory contains a path to the worktree information directory 144 # inside the parent git repo of the worktree. 145 # 146 string(REGEX REPLACE "gitdir: (.*)$" "\\1" git_worktree_dir 147 ${worktree_ref}) 148 string(STRIP ${git_worktree_dir} git_worktree_dir) 149 # When running in an msys environment, the git_worktree_dir has to be 150 # converted to windows format, by adding the windows prefix of the 151 # msys root dir. 152 if(MINGW) 153 execute_process( 154 COMMAND bash -c "cygpath.exe -m /" 155 OUTPUT_VARIABLE real_root 156 OUTPUT_STRIP_TRAILING_WHITESPACE) 157 set(git_worktree_dir "${real_root}${git_worktree_dir}") 158 endif() 159 _git_find_closest_git_dir("${git_worktree_dir}" GIT_DIR) 160 set(HEAD_SOURCE_FILE "${git_worktree_dir}/HEAD") 161 endif() 162 else() 163 set(HEAD_SOURCE_FILE "${GIT_DIR}/HEAD") 164 endif() 165 set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") 166 if(NOT EXISTS "${GIT_DATA}") 167 file(MAKE_DIRECTORY "${GIT_DATA}") 168 endif() 169 170 if(NOT EXISTS "${HEAD_SOURCE_FILE}") 171 return() 172 endif() 173 set(HEAD_FILE "${GIT_DATA}/HEAD") 174 configure_file("${HEAD_SOURCE_FILE}" "${HEAD_FILE}" COPYONLY) 175 176 configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" 177 "${GIT_DATA}/grabRef.cmake" @ONLY) 178 include("${GIT_DATA}/grabRef.cmake") 179 180 set(${_refspecvar} 181 "${HEAD_REF}" 182 PARENT_SCOPE) 183 set(${_hashvar} 184 "${HEAD_HASH}" 185 PARENT_SCOPE) 186endfunction() 187 188function(git_describe _var) 189 if(NOT GIT_FOUND) 190 find_package(Git QUIET) 191 endif() 192 get_git_head_revision(refspec hash) 193 if(NOT GIT_FOUND) 194 set(${_var} 195 "GIT-NOTFOUND" 196 PARENT_SCOPE) 197 return() 198 endif() 199 if(NOT hash) 200 set(${_var} 201 "HEAD-HASH-NOTFOUND" 202 PARENT_SCOPE) 203 return() 204 endif() 205 206 # TODO sanitize 207 #if((${ARGN}" MATCHES "&&") OR 208 # (ARGN MATCHES "||") OR 209 # (ARGN MATCHES "\\;")) 210 # message("Please report the following error to the project!") 211 # message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") 212 #endif() 213 214 #message(STATUS "Arguments to execute_process: ${ARGN}") 215 216 execute_process( 217 COMMAND "${GIT_EXECUTABLE}" describe --tags --always ${hash} ${ARGN} 218 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 219 RESULT_VARIABLE res 220 OUTPUT_VARIABLE out 221 ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) 222 if(NOT res EQUAL 0) 223 set(out "${out}-${res}-NOTFOUND") 224 endif() 225 226 set(${_var} 227 "${out}" 228 PARENT_SCOPE) 229endfunction() 230 231function(git_describe_working_tree _var) 232 if(NOT GIT_FOUND) 233 find_package(Git QUIET) 234 endif() 235 if(NOT GIT_FOUND) 236 set(${_var} 237 "GIT-NOTFOUND" 238 PARENT_SCOPE) 239 return() 240 endif() 241 242 execute_process( 243 COMMAND "${GIT_EXECUTABLE}" describe --dirty ${ARGN} 244 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 245 RESULT_VARIABLE res 246 OUTPUT_VARIABLE out 247 ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) 248 if(NOT res EQUAL 0) 249 set(out "${out}-${res}-NOTFOUND") 250 endif() 251 252 set(${_var} 253 "${out}" 254 PARENT_SCOPE) 255endfunction() 256 257function(git_get_exact_tag _var) 258 git_describe(out --exact-match ${ARGN}) 259 set(${_var} 260 "${out}" 261 PARENT_SCOPE) 262endfunction() 263 264function(git_local_changes _var) 265 if(NOT GIT_FOUND) 266 find_package(Git QUIET) 267 endif() 268 get_git_head_revision(refspec hash) 269 if(NOT GIT_FOUND) 270 set(${_var} 271 "GIT-NOTFOUND" 272 PARENT_SCOPE) 273 return() 274 endif() 275 if(NOT hash) 276 set(${_var} 277 "HEAD-HASH-NOTFOUND" 278 PARENT_SCOPE) 279 return() 280 endif() 281 282 execute_process( 283 COMMAND "${GIT_EXECUTABLE}" diff-index --quiet HEAD -- 284 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 285 RESULT_VARIABLE res 286 OUTPUT_VARIABLE out 287 ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) 288 if(res EQUAL 0) 289 set(${_var} 290 "CLEAN" 291 PARENT_SCOPE) 292 else() 293 set(${_var} 294 "DIRTY" 295 PARENT_SCOPE) 296 endif() 297endfunction()