summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorDavid Cole <david.cole@kitware.com>2012-05-01 18:09:34 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2012-05-01 18:09:34 (GMT)
commit99f6055fe4f047be10ea137e5787418a982596b8 (patch)
tree08ea019387b379ca3882eb6822e86d56d7b70b7b /Modules
parent28de11291a257428685eb5739298dfe20b30f795 (diff)
parent08db81e00807c1dfc6846e9b3228c54dfe37a67f (diff)
downloadCMake-99f6055fe4f047be10ea137e5787418a982596b8.zip
CMake-99f6055fe4f047be10ea137e5787418a982596b8.tar.gz
CMake-99f6055fe4f047be10ea137e5787418a982596b8.tar.bz2
Merge topic 'fix-12564-avoid-git-re-clones'
08db81e ExternalProject: Avoid repeated git clone operations (#12564) d14c024 ExternalProject: Refactor repeated code into function (#12564) 987c017 ExternalProject: Avoid unnecessary git clones (#12564)
Diffstat (limited to 'Modules')
-rw-r--r--Modules/ExternalProject.cmake101
1 files changed, 72 insertions, 29 deletions
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 301d1fc..0353e45 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -252,12 +252,23 @@ define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED
)
-function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag src_name work_dir)
+function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag src_name work_dir gitclone_infofile gitclone_stampfile)
file(WRITE ${script_filename}
"if(\"${git_tag}\" STREQUAL \"\")
message(FATAL_ERROR \"Tag for git checkout should not be empty.\")
endif()
+set(run 0)
+
+if(\"${gitclone_infofile}\" IS_NEWER_THAN \"${gitclone_stampfile}\")
+ set(run 1)
+endif()
+
+if(NOT run)
+ message(STATUS \"Avoiding repeated git clone, stamp file is up to date: '${gitclone_stampfile}'\")
+ return()
+endif()
+
execute_process(
COMMAND \${CMAKE_COMMAND} -E remove_directory \"${source_dir}\"
RESULT_VARIABLE error_code
@@ -302,6 +313,19 @@ if(error_code)
message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\")
endif()
+# Complete success, update the script-last-run stamp file:
+#
+execute_process(
+ COMMAND \${CMAKE_COMMAND} -E copy
+ \"${gitclone_infofile}\"
+ \"${gitclone_stampfile}\"
+ WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+ RESULT_VARIABLE error_code
+ )
+if(error_code)
+ message(FATAL_ERROR \"Failed to copy script-last-run stamp file: '${gitclone_stampfile}'\")
+endif()
+
"
)
@@ -824,15 +848,23 @@ function(_ep_get_configuration_subdir_suffix suffix_var)
endfunction(_ep_get_configuration_subdir_suffix)
-function(ExternalProject_Add_StepTargets name)
- set(steps ${ARGN})
+function(_ep_get_step_stampfile name step stampfile_var)
+ ExternalProject_Get_Property(${name} stamp_dir)
_ep_get_configuration_subdir_suffix(cfgdir)
- ExternalProject_Get_Property(${name} stamp_dir)
+ set(stampfile "${stamp_dir}${cfgdir}/${name}-${step}")
+
+ set(${stampfile_var} "${stampfile}" PARENT_SCOPE)
+endfunction()
+
+
+function(ExternalProject_Add_StepTargets name)
+ set(steps ${ARGN})
foreach(step ${steps})
+ _ep_get_step_stampfile(${name} ${step} stamp_file)
add_custom_target(${name}-${step}
- DEPENDS ${stamp_dir}${cfgdir}/${name}-${step})
+ DEPENDS ${stamp_file})
# Depend on other external projects (target-level).
get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
@@ -845,23 +877,26 @@ endfunction(ExternalProject_Add_StepTargets)
function(ExternalProject_Add_Step name step)
set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
- ExternalProject_Get_Property(${name} stamp_dir)
-
_ep_get_configuration_subdir_suffix(cfgdir)
+ set(complete_stamp_file "${cmf_dir}${cfgdir}/${name}-complete")
+ _ep_get_step_stampfile(${name} ${step} stamp_file)
+
add_custom_command(APPEND
- OUTPUT ${cmf_dir}${cfgdir}/${name}-complete
- DEPENDS ${stamp_dir}${cfgdir}/${name}-${step}
+ OUTPUT ${complete_stamp_file}
+ DEPENDS ${stamp_file}
)
+
_ep_parse_arguments(ExternalProject_Add_Step
- ${name} _EP_${step}_ "${ARGN}")
+ ${name} _EP_${step}_ "${ARGN}")
# Steps depending on this step.
get_property(dependers TARGET ${name} PROPERTY _EP_${step}_DEPENDERS)
foreach(depender IN LISTS dependers)
+ _ep_get_step_stampfile(${name} ${depender} depender_stamp_file)
add_custom_command(APPEND
- OUTPUT ${stamp_dir}${cfgdir}/${name}-${depender}
- DEPENDS ${stamp_dir}${cfgdir}/${name}-${step}
+ OUTPUT ${depender_stamp_file}
+ DEPENDS ${stamp_file}
)
endforeach()
@@ -871,7 +906,8 @@ function(ExternalProject_Add_Step name step)
# Dependencies on steps.
get_property(dependees TARGET ${name} PROPERTY _EP_${step}_DEPENDEES)
foreach(dependee IN LISTS dependees)
- list(APPEND depends ${stamp_dir}${cfgdir}/${name}-${dependee})
+ _ep_get_step_stampfile(${name} ${dependee} dependee_stamp_file)
+ list(APPEND depends ${dependee_stamp_file})
endforeach()
# The command to run.
@@ -901,10 +937,10 @@ function(ExternalProject_Add_Step name step)
# Run every time?
get_property(always TARGET ${name} PROPERTY _EP_${step}_ALWAYS)
if(always)
- set_property(SOURCE ${stamp_dir}${cfgdir}/${name}-${step} PROPERTY SYMBOLIC 1)
+ set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1)
set(touch)
else()
- set(touch ${CMAKE_COMMAND} -E touch ${stamp_dir}${cfgdir}/${name}-${step})
+ set(touch ${CMAKE_COMMAND} -E touch ${stamp_file})
endif()
# Wrap with log script?
@@ -914,7 +950,7 @@ function(ExternalProject_Add_Step name step)
endif()
add_custom_command(
- OUTPUT ${stamp_dir}${cfgdir}/${name}-${step}
+ OUTPUT ${stamp_file}
COMMENT ${comment}
COMMAND ${command}
COMMAND ${touch}
@@ -1079,9 +1115,15 @@ function(_ep_add_download_command name)
set(git_tag "master")
endif()
+ # For the download step, and the git clone operation, only the repository
+ # should be recorded in a configured RepositoryInfo file. If the repo
+ # changes, the clone script should be run again. But if only the tag
+ # changes, avoid running the clone script again. Let the 'always' running
+ # update step checkout the new tag.
+ #
set(repository ${git_repository})
set(module)
- set(tag ${git_tag})
+ set(tag)
configure_file(
"${CMAKE_ROOT}/Modules/RepositoryInfo.txt.in"
"${stamp_dir}/${name}-gitinfo.txt"
@@ -1097,6 +1139,7 @@ function(_ep_add_download_command name)
#
_ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir}
${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${src_name} ${work_dir}
+ ${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt
)
set(comment "Performing download step (git clone) for '${name}'")
set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitclone.cmake)
@@ -1277,14 +1320,12 @@ endfunction(_ep_add_patch_command)
function(_ep_add_configure_command name)
ExternalProject_Get_Property(${name} source_dir binary_dir tmp_dir)
- _ep_get_configuration_subdir_suffix(cfgdir)
-
# Depend on other external projects (file-level).
set(file_deps)
get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
foreach(dep IN LISTS deps)
- get_property(dep_stamp_dir TARGET ${dep} PROPERTY _EP_STAMP_DIR)
- list(APPEND file_deps ${dep_stamp_dir}${cfgdir}/${dep}-done)
+ _ep_get_step_stampfile(${dep} "done" done_stamp_file)
+ list(APPEND file_deps ${done_stamp_file})
endforeach()
get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET)
@@ -1447,11 +1488,14 @@ function(ExternalProject_Add name)
# Add a custom target for the external project.
set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
- add_custom_target(${name} ALL DEPENDS ${cmf_dir}${cfgdir}/${name}-complete)
+ set(complete_stamp_file "${cmf_dir}${cfgdir}/${name}-complete")
+
+ add_custom_target(${name} ALL DEPENDS ${complete_stamp_file})
set_property(TARGET ${name} PROPERTY _EP_IS_EXTERNAL_PROJECT 1)
_ep_parse_arguments(ExternalProject_Add ${name} _EP_ "${ARGN}")
_ep_set_directories(${name})
- ExternalProject_Get_Property(${name} stamp_dir)
+ _ep_get_step_stampfile(${name} "done" done_stamp_file)
+ _ep_get_step_stampfile(${name} "install" install_stamp_file)
# The 'complete' step depends on all other steps and creates a
# 'done' mark. A dependent external project's 'configure' step
@@ -1462,19 +1506,18 @@ function(ExternalProject_Add name)
# parallel builds. However, the Ninja generator needs to see the entire
# dependency graph, and can cope with custom commands belonging to
# multiple targets, so we add the 'done' mark as an output for Ninja only.
- set(complete_outputs ${cmf_dir}${cfgdir}/${name}-complete)
+ set(complete_outputs ${complete_stamp_file})
if(${CMAKE_GENERATOR} MATCHES "Ninja")
- set(complete_outputs
- ${complete_outputs} ${stamp_dir}${cfgdir}/${name}-done)
+ set(complete_outputs ${complete_outputs} ${done_stamp_file})
endif()
add_custom_command(
OUTPUT ${complete_outputs}
COMMENT "Completed '${name}'"
COMMAND ${CMAKE_COMMAND} -E make_directory ${cmf_dir}${cfgdir}
- COMMAND ${CMAKE_COMMAND} -E touch ${cmf_dir}${cfgdir}/${name}-complete
- COMMAND ${CMAKE_COMMAND} -E touch ${stamp_dir}${cfgdir}/${name}-done
- DEPENDS ${stamp_dir}${cfgdir}/${name}-install
+ COMMAND ${CMAKE_COMMAND} -E touch ${complete_stamp_file}
+ COMMAND ${CMAKE_COMMAND} -E touch ${done_stamp_file}
+ DEPENDS ${install_stamp_file}
VERBATIM
)