diff options
author | Matt McCormick <matt.mccormick@kitware.com> | 2012-06-08 22:29:34 (GMT) |
---|---|---|
committer | David Cole <david.cole@kitware.com> | 2012-11-03 21:18:14 (GMT) |
commit | d0758290e78046ac0d8cf91e3456369cc4c43999 (patch) | |
tree | f2ec2dd7909ac9b9a817b728a02d2b4758194f4e /Modules | |
parent | d39bd3e6a8dc89637197c305102724c337b7fb0f (diff) | |
download | CMake-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.cmake | 70 |
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) |