diff options
author | Craig Scott <craig.scott@crascit.com> | 2021-01-19 23:15:45 (GMT) |
---|---|---|
committer | Craig Scott <craig.scott@crascit.com> | 2021-01-19 23:16:21 (GMT) |
commit | 315a200f0c45415e8ab0da058aab9bbfa39c3c05 (patch) | |
tree | 6feb6f39b8dacadc4a6509c0404f48a2f7d1c4cc /Modules/FindGit.cmake | |
parent | ddd9545895326e45bee798ae0b5a5d2bf8dae239 (diff) | |
download | CMake-315a200f0c45415e8ab0da058aab9bbfa39c3c05.zip CMake-315a200f0c45415e8ab0da058aab9bbfa39c3c05.tar.gz CMake-315a200f0c45415e8ab0da058aab9bbfa39c3c05.tar.bz2 |
FindGit: Cache the GIT_EXECUTABLE version for the current run
The git version should not change while CMake is running. When
using FetchContent with many dependencies, the repeated calls
to get the git version every time ExternalProject is used can be
measurable on some platforms. This commit queries that version
only once and then caches it in a global property for the rest of that
run. The git version can still safely change between runs because it
is not cached, only the GIT_EXECUTABLE location is cached.
Relates: #21703
Diffstat (limited to 'Modules/FindGit.cmake')
-rw-r--r-- | Modules/FindGit.cmake | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake index f8346b6..83da707 100644 --- a/Modules/FindGit.cmake +++ b/Modules/FindGit.cmake @@ -77,14 +77,44 @@ unset(git_names) unset(_git_sourcetree_path) if(GIT_EXECUTABLE) - execute_process(COMMAND ${GIT_EXECUTABLE} --version - OUTPUT_VARIABLE git_version - ERROR_QUIET - OUTPUT_STRIP_TRAILING_WHITESPACE) - if (git_version MATCHES "^git version [0-9]") - string(REPLACE "git version " "" GIT_VERSION_STRING "${git_version}") + # Avoid querying the version if we've already done that this run. For + # projects that use things like ExternalProject or FetchContent heavily, + # this saving can be measurable on some platforms. + set(__doGitVersionCheck YES) + if(DEFINED GIT_VERSION_STRING) + # This is an internal property, projects must not try to use it. + # We don't want this stored in the cache because it might still change + # between CMake runs, but it shouldn't change during a run. + get_property(__gitVersionProp GLOBAL + PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION + ) + if(__gitVersionProp) + list(GET __gitVersionProp 0 __gitExe) + list(GET __gitVersionProp 1 __gitVersion) + if("${__gitExe}" STREQUAL "${GIT_EXECUTABLE}" AND + "${__gitVersion}" STREQUAL "${GIT_VERSION_STRING}") + set(__doGitVersionCheck NO) + endif() + endif() + unset(__gitVersionProp) + unset(__gitExe) + unset(__gitVersion) + endif() + + if(__doGitVersionCheck) + execute_process(COMMAND ${GIT_EXECUTABLE} --version + OUTPUT_VARIABLE git_version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (git_version MATCHES "^git version [0-9]") + string(REPLACE "git version " "" GIT_VERSION_STRING "${git_version}") + set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION + "${GIT_EXECUTABLE};${GIT_VERSION_STRING}" + ) + endif() + unset(git_version) endif() - unset(git_version) + unset(__doGitVersionCheck) get_property(_findgit_role GLOBAL PROPERTY CMAKE_ROLE) if(_findgit_role STREQUAL "PROJECT" AND NOT TARGET Git::Git) |