summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorMatt McCormick <matt.mccormick@kitware.com>2012-06-08 22:29:34 (GMT)
committerDavid Cole <david.cole@kitware.com>2012-11-03 21:18:14 (GMT)
commitd0758290e78046ac0d8cf91e3456369cc4c43999 (patch)
treef2ec2dd7909ac9b9a817b728a02d2b4758194f4e /Modules
parentd39bd3e6a8dc89637197c305102724c337b7fb0f (diff)
downloadCMake-d0758290e78046ac0d8cf91e3456369cc4c43999.zip
CMake-d0758290e78046ac0d8cf91e3456369cc4c43999.tar.gz
CMake-d0758290e78046ac0d8cf91e3456369cc4c43999.tar.bz2
ExternalProject: Only run 'git fetch' when required.
In the current default update step for Git under the ExternalProject_Add command, a 'git fetch' is always performed, followed by a 'git checkout' and 'git submodule update --recursive'. However, a 'git fetch' can be time consuming and requires a network connection. To save time, we look at the current checked out hash, and only perform the fetch if required. This is performed in a CMake script so we can handle the conditional logic in a cross platform manner.
Diffstat (limited to 'Modules')
-rw-r--r--Modules/ExternalProject.cmake70
1 files changed, 65 insertions, 5 deletions
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 8d57860..7a8aa5f 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -402,6 +402,66 @@ endif()
endfunction()
+function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_repository work_dir)
+ file(WRITE ${script_filename}
+"if(\"${git_tag}\" STREQUAL \"\")
+ message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
+endif()
+
+execute_process(
+ COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 HEAD
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ OUTPUT_VARIABLE head_sha
+ )
+if(error_code)
+ message(FATAL_ERROR \"Failed to get the hash for HEAD\")
+endif()
+
+# This will fail if the tag does not exist (it probably has not been fetched
+# yet).
+execute_process(
+ COMMAND \"${git_EXECUTABLE}\" rev-list --max-count=1 ${git_tag}
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ OUTPUT_VARIABLE tag_sha
+ )
+
+# Is the hash checkout out that we want?
+if(error_code OR NOT (\"\${tag_sha}\" STREQUAL \"\${head_sha}\"))
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" fetch
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ message(FATAL_ERROR \"Failed to fetch repository '${git_repository}'\")
+ endif()
+
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" checkout ${git_tag}
+ WORKING_DIRECTORY \"${work_dir}\"
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\")
+ endif()
+
+ execute_process(
+ COMMAND \"${git_EXECUTABLE}\" submodule update --recursive
+ WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+ RESULT_VARIABLE error_code
+ )
+ if(error_code)
+ message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\")
+ endif()
+endif()
+
+"
+)
+
+endfunction(_ep_write_gitupdate_script)
+
function(_ep_write_downloadfile_script script_filename remote local timeout hash tls_verify tls_cainfo)
if(timeout)
set(timeout_args TIMEOUT ${timeout})
@@ -1354,7 +1414,7 @@ endfunction()
function(_ep_add_update_command name)
- ExternalProject_Get_Property(${name} source_dir)
+ ExternalProject_Get_Property(${name} source_dir tmp_dir)
get_property(cmd_set TARGET ${name} PROPERTY _EP_UPDATE_COMMAND SET)
get_property(cmd TARGET ${name} PROPERTY _EP_UPDATE_COMMAND)
@@ -1406,15 +1466,15 @@ function(_ep_add_update_command name)
message(FATAL_ERROR "error: could not find git for fetch of ${name}")
endif()
set(work_dir ${source_dir})
- set(comment "Performing update step (git fetch) for '${name}'")
+ set(comment "Performing update step for '${name}'")
get_property(git_tag TARGET ${name} PROPERTY _EP_GIT_TAG)
if(NOT git_tag)
set(git_tag "master")
endif()
- set(cmd ${GIT_EXECUTABLE} fetch
- COMMAND ${GIT_EXECUTABLE} checkout ${git_tag}
- COMMAND ${GIT_EXECUTABLE} submodule update --recursive
+ _ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake
+ ${GIT_EXECUTABLE} ${git_tag} ${git_repository} ${work_dir}
)
+ set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake)
set(always 1)
elseif(hg_repository)
if(NOT HG_EXECUTABLE)