diff options
-rw-r--r-- | Modules/ExternalProject.cmake | 22 | ||||
-rw-r--r-- | Modules/FetchContent.cmake | 16 | ||||
-rw-r--r-- | Modules/FetchContent/CMakeLists.cmake.in | 2 | ||||
-rw-r--r-- | Modules/FindGit.cmake | 44 |
4 files changed, 69 insertions, 15 deletions
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 3307bc6fe1..1e50c6dcd0 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -2630,10 +2630,13 @@ function(_ep_add_download_command name) --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args} ${src_name}) list(APPEND depends ${stamp_dir}/${name}-svninfo.txt) elseif(git_repository) - unset(CMAKE_MODULE_PATH) # Use CMake builtin find module - find_package(Git QUIET) - if(NOT GIT_EXECUTABLE) - message(FATAL_ERROR "error: could not find git for clone of ${name}") + # FetchContent gives us these directly, so don't try to recompute them + if(NOT GIT_EXECUTABLE OR NOT GIT_VERSION_STRING) + unset(CMAKE_MODULE_PATH) # Use CMake builtin find module + find_package(Git QUIET) + if(NOT GIT_EXECUTABLE) + message(FATAL_ERROR "error: could not find git for clone of ${name}") + endif() endif() _ep_get_git_submodules_recurse(git_submodules_recurse) @@ -2951,10 +2954,13 @@ function(_ep_add_update_command name) --non-interactive ${svn_trust_cert_args} ${svn_user_pw_args}) set(always 1) elseif(git_repository) - unset(CMAKE_MODULE_PATH) # Use CMake builtin find module - find_package(Git QUIET) - if(NOT GIT_EXECUTABLE) - message(FATAL_ERROR "error: could not find git for fetch of ${name}") + # FetchContent gives us these directly, so don't try to recompute them + if(NOT GIT_EXECUTABLE OR NOT GIT_VERSION_STRING) + unset(CMAKE_MODULE_PATH) # Use CMake builtin find module + find_package(Git QUIET) + if(NOT GIT_EXECUTABLE) + message(FATAL_ERROR "error: could not find git for fetch of ${name}") + endif() endif() set(work_dir ${source_dir}) set(comment "Performing update step for '${name}'") diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index ba2acfce79..8adef47778 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -964,6 +964,22 @@ ExternalProject_Add_Step(${contentName}-populate copyfile "-DCMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY=${CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY}") endif() + # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings + set(__FETCHCONTENT_CACHED_INFO "") + list(FIND ARG_UNPARSED_ARGUMENTS GIT_REPOSITORY indexResult) + if(indexResult GREATER_EQUAL 0) + find_package(Git QUIET) + set(__FETCHCONTENT_CACHED_INFO +"# Pass through things we've already detected in the main project to avoid +# paying the cost of redetecting them again in ExternalProject_Add() +set(GIT_EXECUTABLE [==[${GIT_EXECUTABLE}]==]) +set(GIT_VERSION_STRING [==[${GIT_VERSION_STRING}]==]) +set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION + [==[${GIT_EXECUTABLE};${GIT_VERSION_STRING}]==] +) +") + endif() + # Create and build a separate CMake project to carry out the population. # If we've already previously done these steps, they will not cause # anything to be updated, so extra rebuilds of the project won't occur. diff --git a/Modules/FetchContent/CMakeLists.cmake.in b/Modules/FetchContent/CMakeLists.cmake.in index 45e4df03ef..5ebb12f1ad 100644 --- a/Modules/FetchContent/CMakeLists.cmake.in +++ b/Modules/FetchContent/CMakeLists.cmake.in @@ -9,6 +9,8 @@ cmake_minimum_required(VERSION ${CMAKE_VERSION}) project(${contentName}-populate NONE) +@__FETCHCONTENT_CACHED_INFO@ + include(ExternalProject) ExternalProject_Add(${contentName}-populate ${ARG_EXTRA} diff --git a/Modules/FindGit.cmake b/Modules/FindGit.cmake index f8346b61d0..83da707b74 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) |