summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Help/release/dev/fetchcontent-performance.rst6
-rw-r--r--Modules/ExternalProject.cmake226
-rw-r--r--Modules/ExternalProject/captured_process_setup.cmake55
-rw-r--r--Modules/ExternalProject/customcommand.cmake.in8
-rw-r--r--Modules/ExternalProject/customcommand_preamble.cmake.in8
-rw-r--r--Modules/ExternalProject/download.cmake.in46
-rw-r--r--Modules/ExternalProject/extractfile.cmake.in32
-rw-r--r--Modules/ExternalProject/gitclone.cmake.in77
-rw-r--r--Modules/ExternalProject/gitupdate.cmake.in92
-rw-r--r--Modules/ExternalProject/hgclone.cmake.in47
-rw-r--r--Modules/ExternalProject/hgupdate.cmake.in12
-rw-r--r--Modules/ExternalProject/verify.cmake.in22
-rw-r--r--Modules/FetchContent.cmake131
-rw-r--r--Modules/FetchContent/CMakeLists.cmake.in27
-rw-r--r--Tests/RunCMake/FetchContent/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/FetchContent/SameGenerator.cmake17
16 files changed, 481 insertions, 326 deletions
diff --git a/Help/release/dev/fetchcontent-performance.rst b/Help/release/dev/fetchcontent-performance.rst
index 361c2b4645..fcb68a1835 100644
--- a/Help/release/dev/fetchcontent-performance.rst
+++ b/Help/release/dev/fetchcontent-performance.rst
@@ -5,3 +5,9 @@ fetchcontent-performance
significantly refactored. The patch step gained support for
using the terminal with a new ``USES_TERMINAL_PATCH`` keyword
as a by-product of that work.
+* The :module:`FetchContent` module no longer creates a separate
+ sub-build to implement the content population. It now invokes
+ the step scripts directly from within the main project's
+ configure stage. This significantly speeds up the configure
+ phase when the required content is already populated and
+ up-to-date.
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 5f00c87447..2b413c21b8 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -1200,46 +1200,46 @@ function(_ep_parse_arguments keywords name ns args)
endfunction()
+if(NOT DEFINED CMAKE_SCRIPT_MODE_FILE)
+ define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED
+ BRIEF_DOCS "Base directory for External Project storage."
+ FULL_DOCS
+ "See documentation of the ExternalProject_Add() function in the "
+ "ExternalProject module."
+ )
-define_property(DIRECTORY PROPERTY "EP_BASE" INHERITED
- BRIEF_DOCS "Base directory for External Project storage."
- FULL_DOCS
- "See documentation of the ExternalProject_Add() function in the "
- "ExternalProject module."
- )
-
-define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED
- BRIEF_DOCS "Top prefix for External Project storage."
- FULL_DOCS
- "See documentation of the ExternalProject_Add() function in the "
- "ExternalProject module."
- )
-
-define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED
- BRIEF_DOCS
- "List of ExternalProject steps that automatically get corresponding targets"
- FULL_DOCS
- "These targets will be dependent on the main target dependencies. "
- "See documentation of the ExternalProject_Add_StepTargets() function in the "
- "ExternalProject module."
- )
+ define_property(DIRECTORY PROPERTY "EP_PREFIX" INHERITED
+ BRIEF_DOCS "Top prefix for External Project storage."
+ FULL_DOCS
+ "See documentation of the ExternalProject_Add() function in the "
+ "ExternalProject module."
+ )
-define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED
- BRIEF_DOCS
- "List of ExternalProject steps that automatically get corresponding targets"
- FULL_DOCS
- "These targets will not be dependent on the main target dependencies. "
- "See documentation of the ExternalProject_Add_StepTargets() function in the "
- "ExternalProject module."
- )
+ define_property(DIRECTORY PROPERTY "EP_STEP_TARGETS" INHERITED
+ BRIEF_DOCS
+ "List of ExternalProject steps that automatically get corresponding targets"
+ FULL_DOCS
+ "These targets will be dependent on the main target dependencies. "
+ "See documentation of the ExternalProject_Add_StepTargets() function in the "
+ "ExternalProject module."
+ )
-define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED
- BRIEF_DOCS "Never update automatically from the remote repo."
- FULL_DOCS
- "See documentation of the ExternalProject_Add() function in the "
- "ExternalProject module."
- )
+ define_property(DIRECTORY PROPERTY "EP_INDEPENDENT_STEP_TARGETS" INHERITED
+ BRIEF_DOCS
+ "List of ExternalProject steps that automatically get corresponding targets"
+ FULL_DOCS
+ "These targets will not be dependent on the main target dependencies. "
+ "See documentation of the ExternalProject_Add_StepTargets() function in the "
+ "ExternalProject module."
+ )
+ define_property(DIRECTORY PROPERTY "EP_UPDATE_DISCONNECTED" INHERITED
+ BRIEF_DOCS "Never update automatically from the remote repo."
+ FULL_DOCS
+ "See documentation of the ExternalProject_Add() function in the "
+ "ExternalProject module."
+ )
+endif()
function(_ep_write_gitclone_script
script_filename
@@ -1258,7 +1258,8 @@ function(_ep_write_gitclone_script
work_dir
gitclone_infofile
gitclone_stampfile
- tls_verify)
+ tls_verify
+ quiet)
if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5)
# Use `git checkout <tree-ish> --` to avoid ambiguity with a local path.
@@ -1322,7 +1323,8 @@ function(_ep_write_hgclone_script
src_name
work_dir
hgclone_infofile
- hgclone_stampfile)
+ hgclone_stampfile
+ quiet)
if("${hg_tag}" STREQUAL "")
message(FATAL_ERROR "Tag for hg checkout should not be empty.")
@@ -1347,7 +1349,8 @@ function(_ep_write_gitupdate_script
git_submodules
git_repository
work_dir
- git_update_strategy)
+ git_update_strategy
+ quiet)
if("${git_tag}" STREQUAL "")
message(FATAL_ERROR "Tag for git checkout should not be empty.")
@@ -1372,7 +1375,8 @@ function(_ep_write_hgupdate_script
script_filename
hg_EXECUTABLE
hg_tag
- work_dir)
+ work_dir
+ quiet)
configure_file(
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/hgupdate.cmake.in
@@ -1408,7 +1412,8 @@ function(_ep_write_downloadfile_script
http_headers
netrc
netrc_file
- extract_script_filename)
+ extract_script_filename
+ quiet)
if(timeout)
set(TIMEOUT_ARGS TIMEOUT ${timeout})
@@ -1426,7 +1431,7 @@ function(_ep_write_downloadfile_script
endif()
- if(no_progress)
+ if(no_progress OR quiet)
set(SHOW_PROGRESS "")
else()
set(SHOW_PROGRESS "SHOW_PROGRESS")
@@ -1523,7 +1528,8 @@ function(_ep_write_verifyfile_script
script_filename
LOCAL
hash
- extract_script_filename)
+ extract_script_filename
+ quiet)
_ep_get_hash_regex(_ep_hash_regex)
if("${hash}" MATCHES "${_ep_hash_regex}")
@@ -1551,7 +1557,8 @@ function(_ep_write_extractfile_script
script_filename
name
filename
- directory)
+ directory
+ quiet)
set(args "")
@@ -1578,7 +1585,8 @@ function(_ep_write_extractfile_script
endfunction()
-# This function is an implementation detail of ExternalProject_Add().
+# This function is an implementation detail of ExternalProject_Add() and
+# _ep_do_preconfigure_steps_now().
#
# The function expects keyword arguments to have already been parsed into
# variables of the form _EP_<keyword>. It will create the various directories
@@ -2059,7 +2067,7 @@ if(result)
message(FATAL_ERROR \"\${msg}\")
endif()
else()
- if(NOT \"${CMAKE_GENERATOR}\" MATCHES \"Ninja\")
+ if(NOT \"${CMAKE_GENERATOR}\" MATCHES \"Ninja\" AND NOT \"${_EP_QUIET}\")
set(msg \"${name} ${step} command succeeded. See also ${logbase}-*.log\")
message(STATUS \"\${msg}\")
endif()
@@ -2523,6 +2531,7 @@ function(_ep_write_command_script
commands
work_dir
genex_supported
+ quiet
have_commands_var)
set(sep "${_EP_LIST_SEPARATOR}")
@@ -2531,6 +2540,10 @@ function(_ep_write_command_script
endif()
_ep_replace_location_tags_from_vars(commands)
+ file(READ
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/customcommand.cmake.in
+ exec_command_template
+ )
set(script_content)
set(this_command)
foreach(token IN LISTS commands)
@@ -2539,13 +2552,8 @@ function(_ep_write_command_script
# Silently skip empty commands
continue()
endif()
- string(APPEND script_content "
-execute_process(
- COMMAND ${this_command}
- COMMAND_ERROR_IS_FATAL LAST
- WORKING_DIRECTORY [==[${work_dir}]==]
-)
-")
+ string(CONFIGURE "${exec_command_template}" content @ONLY)
+ string(APPEND script_content "${content}")
set(this_command)
else()
# Ensure we quote every token so we preserve empty items, quotes, etc
@@ -2554,20 +2562,20 @@ execute_process(
endforeach()
if(NOT "${this_command}" STREQUAL "")
- string(APPEND script_content "
-execute_process(
- COMMAND ${this_command}
- COMMAND_ERROR_IS_FATAL LAST
- WORKING_DIRECTORY [==[${work_dir}]==]
-)
-")
+ string(CONFIGURE "${exec_command_template}" content @ONLY)
+ string(APPEND script_content "${content}")
endif()
if(script_content STREQUAL "")
set(${have_commands_var} FALSE PARENT_SCOPE)
else()
set(${have_commands_var} TRUE PARENT_SCOPE)
- string(PREPEND script_content "cmake_minimum_required(VERSION 3.19)\n")
+ file(READ
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ExternalProject/customcommand_preamble.cmake.in
+ exec_command_preamble
+ )
+ string(CONFIGURE "${exec_command_preamble}" exec_command_preamble @ONLY)
+ string(PREPEND script_content "${exec_command_preamble}")
endif()
if(genex_supported)
@@ -2603,7 +2611,8 @@ function(_ep_add_preconfigure_command name step)
)
endfunction()
-# This function is an implementation detail of ExternalProject_Add().
+# This function is an implementation detail of ExternalProject_Add() and
+# _ep_do_preconfigure_steps_now().
#
# The function expects keyword arguments to have already been parsed into
# variables of the form _EP_<keyword>. It will populate the variable
@@ -2619,6 +2628,7 @@ function(_ep_prepare_download name genex_supported)
set(tmp_dir "${_EP_TMP_DIR}")
set(source_dir "${_EP_SOURCE_DIR}")
set(download_dir "${_EP_DOWNLOAD_DIR}")
+ set(quiet "${_EP_QUIET}")
set(comment)
@@ -2628,6 +2638,7 @@ function(_ep_prepare_download name genex_supported)
if(log)
set(script_filename ${tmp_dir}/${name}-download-impl.cmake)
set(log TRUE)
+ set(quiet FALSE) # Already quiet as a result of log being enabled
else()
set(script_filename ${tmp_dir}/${name}-download.cmake)
set(log FALSE)
@@ -2660,6 +2671,7 @@ work_dir=${work_dir}
"${_EP_DOWNLOAD_COMMAND}"
"${work_dir}"
"${genex_supported}"
+ "${quiet}"
script_does_something
)
set(comment "Performing download step (custom command) for '${name}'")
@@ -2698,6 +2710,7 @@ source_dir=${source_dir}
"${cmd}"
"${work_dir}"
"${genex_supported}"
+ "${quiet}"
script_does_something
)
set(comment "Performing download step (CVS checkout) for '${name}'")
@@ -2750,6 +2763,7 @@ source_dir=${source_dir}
"${cmd}"
"${work_dir}"
"${genex_supported}"
+ "${quiet}"
script_does_something
)
set(comment "Performing download step (SVN checkout) for '${name}'")
@@ -2835,6 +2849,7 @@ source_dir=${source_dir}
"${repo_info_file}"
"${last_run_file}"
"${tls_verify}"
+ "${quiet}"
)
set(comment "Performing download step (git clone) for '${name}'")
@@ -2880,6 +2895,7 @@ source_dir=${source_dir}
"${work_dir}"
"${repo_info_file}"
"${last_run_file}"
+ "${quiet}"
)
set(comment "Performing download step (hg clone) for '${name}'")
@@ -2982,6 +2998,7 @@ source_dir=${source_dir}
"${_EP_NETRC}"
"${_EP_NETRC_FILE}"
"${extract_script}"
+ "${quiet}"
)
if(no_extract)
set(steps "download and verify")
@@ -2995,6 +3012,7 @@ source_dir=${source_dir}
"${file}"
"${hash}"
"${extract_script}"
+ "${quiet}"
)
if(no_extract)
set(steps "verify")
@@ -3012,6 +3030,7 @@ source_dir=${source_dir}
"${name}"
"${file}"
"${source_dir}"
+ "${quiet}"
)
endif()
endif()
@@ -3079,7 +3098,8 @@ function(_ep_get_update_disconnected var)
set(${var} "${update_disconnected}" PARENT_SCOPE)
endfunction()
-# This function is an implementation detail of ExternalProject_Add().
+# This function is an implementation detail of ExternalProject_Add() and
+# _ep_do_preconfigure_steps_now().
#
# The function expects keyword arguments to have already been parsed into
# variables of the form _EP_<keyword>.
@@ -3091,6 +3111,7 @@ function(_ep_prepare_update name genex_supported)
set(tmp_dir "${_EP_TMP_DIR}")
set(source_dir "${_EP_SOURCE_DIR}")
+ set(quiet "${_EP_QUIET}")
set(comment)
@@ -3102,6 +3123,7 @@ function(_ep_prepare_update name genex_supported)
if(log)
set(script_filename ${tmp_dir}/${name}-update-impl.cmake)
set(log TRUE)
+ set(quiet FALSE) # Already quiet as a result of log being enabled
else()
set(script_filename ${tmp_dir}/${name}-update.cmake)
set(log FALSE)
@@ -3114,6 +3136,7 @@ function(_ep_prepare_update name genex_supported)
"${_EP_UPDATE_COMMAND}"
"${work_dir}"
"${genex_supported}"
+ "${quiet}"
script_does_something
)
set(comment "Performing update step (custom command) for '${name}'")
@@ -3132,6 +3155,7 @@ function(_ep_prepare_update name genex_supported)
"${cmd}"
"${work_dir}"
"${genex_supported}"
+ "${quiet}"
script_does_something
)
set(comment "Performing update step (CVS update) for '${name}'")
@@ -3165,6 +3189,7 @@ function(_ep_prepare_update name genex_supported)
"${cmd}"
"${work_dir}"
"${genex_supported}"
+ "${quiet}"
script_does_something
)
set(comment "Performing update step (SVN update) for '${name}'")
@@ -3222,6 +3247,7 @@ function(_ep_prepare_update name genex_supported)
"${_EP_GIT_REPOSITORY}"
"${work_dir}"
"${git_update_strategy}"
+ "${quiet}"
)
set(script_does_something TRUE)
set(comment "Performing update step (git update) for '${name}'")
@@ -3250,6 +3276,7 @@ Update to Mercurial >= 2.1.1.
"${HG_EXECUTABLE}"
"${hg_tag}"
"${work_dir}"
+ "${quiet}"
)
set(script_does_something TRUE)
set(comment "Performing update step (hg pull) for '${name}'")
@@ -3280,7 +3307,8 @@ Update to Mercurial >= 2.1.1.
endfunction()
-# This function is an implementation detail of ExternalProject_Add().
+# This function is an implementation detail of ExternalProject_Add() and
+# _ep_do_preconfigure_steps_now().
#
# The function expects keyword arguments to have already been parsed into
# variables of the form _EP_<keyword>.
@@ -3292,6 +3320,7 @@ function(_ep_prepare_patch name genex_supported)
set(tmp_dir "${_EP_TMP_DIR}")
set(source_dir "${_EP_SOURCE_DIR}")
+ set(quiet "${_EP_QUIET}")
_ep_get_update_disconnected(update_disconnected)
if(update_disconnected)
@@ -3306,6 +3335,7 @@ function(_ep_prepare_patch name genex_supported)
if(log)
set(script_filename ${tmp_dir}/${name}-patch-impl.cmake)
set(log TRUE)
+ set(quiet FALSE) # Already quiet as a result of log being enabled
else()
set(script_filename ${tmp_dir}/${name}-patch.cmake)
set(log FALSE)
@@ -3318,6 +3348,7 @@ function(_ep_prepare_patch name genex_supported)
"${_EP_PATCH_COMMAND}"
"${work_dir}"
"${genex_supported}"
+ "${quiet}"
script_does_something
)
if(script_does_something)
@@ -3837,6 +3868,73 @@ macro(_ep_get_add_keywords out_var)
endmacro()
+# Internal function called by FetchContent to populate immediately.
+# It only executes steps up to and including "patch". It takes the same
+# arguments as ExternalProject_Add() plus one additional argument: QUIET.
+#
+# Not to be used outside of CMake.
+#
+function(_ep_do_preconfigure_steps_now name)
+
+ cmake_policy(GET CMP0097 _EP_CMP0097
+ PARENT_SCOPE # undocumented, do not use outside of CMake
+ )
+
+ set(genex_supported FALSE)
+
+ _ep_get_add_keywords(keywords)
+ _ep_parse_arguments_to_vars("${keywords};QUIET" ${name} _EP_ "${ARGN}")
+
+ _ep_get_update_disconnected(update_disconnected)
+
+ _ep_prepare_directories(${name})
+ _ep_prepare_download(${name} ${genex_supported})
+ _ep_prepare_update(${name} ${genex_supported})
+ _ep_prepare_patch(${name} ${genex_supported})
+
+ set(stamp_dir "${_EP_STAMP_DIR}")
+ set(tmp_dir "${_EP_TMP_DIR}")
+
+ # Once any step has to run, all later steps have to be run too
+ set(need_to_run FALSE)
+ foreach(step IN ITEMS download update parse)
+ if(update_disconnected AND "${step}" STREQUAL "update")
+ continue()
+ endif()
+
+ string(TOUPPER "${step}" STEP)
+ if("${_EPcommand_${STEP}}" STREQUAL "")
+ continue()
+ endif()
+
+ set(stamp_file "${stamp_dir}/${name}-${step}")
+ set(script_file ${tmp_dir}/${name}-${step}.cmake)
+
+ if(NOT EXISTS ${stamp_file})
+ set(need_to_run TRUE)
+ endif()
+
+ if(NOT need_to_run)
+ foreach(dep_file ${script_file} ${_EPdepends_${STEP}})
+ if(NOT EXISTS ${dep_file} OR ${dep_file} IS_NEWER_THAN ${stamp_file})
+ set(need_to_run TRUE)
+ break()
+ endif()
+ endforeach()
+ endif()
+
+ if(need_to_run)
+ include(${script_file})
+ file(TOUCH ${stamp_file})
+ endif()
+ endforeach()
+
+ if("${_EP_DOWNLOAD_NO_EXTRACT}")
+ file(COPY "${_EP_DOWNLOADED_FILE}" DESTINATION "${_EP_SOURCE_DIR}")
+ endif()
+
+endfunction()
+
function(ExternalProject_Add name)
cmake_policy(GET CMP0097 _EP_CMP0097
PARENT_SCOPE # undocumented, do not use outside of CMake
diff --git a/Modules/ExternalProject/captured_process_setup.cmake b/Modules/ExternalProject/captured_process_setup.cmake
new file mode 100644
index 0000000000..9c8abb1203
--- /dev/null
+++ b/Modules/ExternalProject/captured_process_setup.cmake
@@ -0,0 +1,55 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+if(quiet)
+ set(capture_output
+ OUTPUT_VARIABLE out_var
+ ERROR_VARIABLE out_var
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+ set(capture_error_only
+ ERROR_VARIABLE out_var
+ ERROR_STRIP_TRAILING_WHITESPACE
+ )
+else()
+ unset(capture_output)
+ unset(capture_error_only)
+endif()
+
+set(out_var "")
+set(accumulated_output "")
+
+macro(_ep_message_quiet_capture mode)
+ if("${mode}" STREQUAL "FATAL_ERROR")
+ string(JOIN "" detail "${ARGN}")
+ if(NOT detail STREQUAL "" AND NOT accumulated_output STREQUAL "")
+ string(PREPEND detail "\n")
+ endif()
+ message(FATAL_ERROR "${accumulated_output}${detail}")
+ endif()
+
+ if(quiet)
+ if("${mode}" MATCHES "WARNING")
+ # We can't provide the full CMake backtrace, but we can at least record
+ # the warning message with a sensible prefix
+ string(APPEND accumulated_output "${mode}: ")
+ endif()
+ string(APPEND accumulated_output "${ARGN}\n")
+ else()
+ message(${mode} ${ARGN})
+ endif()
+endmacro()
+
+macro(_ep_accumulate_captured_output)
+ if(NOT "${out_var}" STREQUAL "")
+ string(APPEND accumulated_output "${out_var}\n")
+ endif()
+endmacro()
+
+macro(_ep_command_check_result result)
+ _ep_accumulate_captured_output()
+ if(result)
+ _ep_message_quiet_capture(FATAL_ERROR ${ARGN})
+ endif()
+endmacro()
diff --git a/Modules/ExternalProject/customcommand.cmake.in b/Modules/ExternalProject/customcommand.cmake.in
new file mode 100644
index 0000000000..d41f31b83e
--- /dev/null
+++ b/Modules/ExternalProject/customcommand.cmake.in
@@ -0,0 +1,8 @@
+
+execute_process(
+ COMMAND @this_command@
+ WORKING_DIRECTORY "@work_dir@"
+ RESULT_VARIABLE result
+ ${capture_output}
+)
+_ep_command_check_result(result)
diff --git a/Modules/ExternalProject/customcommand_preamble.cmake.in b/Modules/ExternalProject/customcommand_preamble.cmake.in
new file mode 100644
index 0000000000..ae4fec66cd
--- /dev/null
+++ b/Modules/ExternalProject/customcommand_preamble.cmake.in
@@ -0,0 +1,8 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+cmake_minimum_required(VERSION 3.5)
+
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
diff --git a/Modules/ExternalProject/download.cmake.in b/Modules/ExternalProject/download.cmake.in
index 6ef4eb1842..c8d2f28f18 100644
--- a/Modules/ExternalProject/download.cmake.in
+++ b/Modules/ExternalProject/download.cmake.in
@@ -3,13 +3,17 @@
cmake_minimum_required(VERSION 3.5)
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
+
function(check_file_hash has_hash hash_is_good)
if("${has_hash}" STREQUAL "")
- message(FATAL_ERROR "has_hash Can't be empty")
+ _ep_message_quiet_capture(FATAL_ERROR "has_hash Can't be empty")
endif()
if("${hash_is_good}" STREQUAL "")
- message(FATAL_ERROR "hash_is_good Can't be empty")
+ _ep_message_quiet_capture(FATAL_ERROR "hash_is_good Can't be empty")
endif()
if("@ALGO@" STREQUAL "")
@@ -21,18 +25,20 @@ function(check_file_hash has_hash hash_is_good)
set("${has_hash}" TRUE PARENT_SCOPE)
- message(STATUS "verifying file...
+ _ep_message_quiet_capture(STATUS "verifying file...
file='@LOCAL@'")
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
file("@ALGO@" "@LOCAL@" actual_value)
if(NOT "${actual_value}" STREQUAL "@EXPECT_VALUE@")
set("${hash_is_good}" FALSE PARENT_SCOPE)
- message(STATUS "@ALGO@ hash of
+ _ep_message_quiet_capture(STATUS "@ALGO@ hash of
@LOCAL@
does not match expected value
expected: '@EXPECT_VALUE@'
actual: '${actual_value}'")
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
else()
set("${hash_is_good}" TRUE PARENT_SCOPE)
endif()
@@ -44,7 +50,8 @@ function(sleep_before_download attempt)
endif()
if(attempt EQUAL 1)
- message(STATUS "Retrying...")
+ _ep_message_quiet_capture(STATUS "Retrying...")
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
return()
endif()
@@ -66,7 +73,10 @@ function(sleep_before_download attempt)
set(sleep_seconds 1200)
endif()
- message(STATUS "Retry after ${sleep_seconds} seconds (attempt #${attempt}) ...")
+ _ep_message_quiet_capture(STATUS
+ "Retry after ${sleep_seconds} seconds (attempt #${attempt}) ..."
+ )
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep "${sleep_seconds}")
endfunction()
@@ -84,18 +94,22 @@ function(download_and_verify)
check_file_hash(has_hash hash_is_good)
if(has_hash)
if(hash_is_good)
- message(STATUS
+ _ep_message_quiet_capture(STATUS
"File already exists and hash match (skip download):
file='@LOCAL@'
@ALGO@='@EXPECT_VALUE@'"
)
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
return()
else()
- message(STATUS "File already exists but hash mismatch. Removing...")
+ _ep_message_quiet_capture(STATUS
+ "File already exists but hash mismatch. Removing..."
+ )
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
file(REMOVE "@LOCAL@")
endif()
else()
- message(STATUS
+ _ep_message_quiet_capture(STATUS
"File already exists but no hash specified (use URL_HASH):
file='@LOCAL@'
Old file will be removed and new file downloaded from URL."
@@ -106,11 +120,12 @@ Old file will be removed and new file downloaded from URL."
set(retry_number 5)
- message(STATUS "Downloading...
+ _ep_message_quiet_capture(STATUS "Downloading...
dst='@LOCAL@'
timeout='@TIMEOUT_MSG@'
inactivity timeout='@INACTIVITY_TIMEOUT_MSG@'"
)
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
set(download_retry_codes 7 6 8 15)
set(skip_url_list)
set(status_code)
@@ -120,7 +135,8 @@ Old file will be removed and new file downloaded from URL."
endif()
foreach(url @REMOTE@)
if(NOT url IN_LIST skip_url_list)
- message(STATUS "Using src='${url}'")
+ _ep_message_quiet_capture(STATUS "Using src='${url}'")
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
@TLS_VERIFY_CODE@
@TLS_CAINFO_CODE@
@@ -145,10 +161,12 @@ Old file will be removed and new file downloaded from URL."
if(status_code EQUAL 0)
check_file_hash(has_hash hash_is_good)
if(has_hash AND NOT hash_is_good)
- message(STATUS "Hash mismatch, removing...")
+ _ep_message_quiet_capture(STATUS "Hash mismatch, removing...")
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
file(REMOVE "@LOCAL@")
else()
- message(STATUS "Downloading... done")
+ _ep_message_quiet_capture(STATUS "Downloading... done")
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
return()
endif()
else()
@@ -171,7 +189,7 @@ Old file will be removed and new file downloaded from URL."
endforeach()
endforeach()
- message(FATAL_ERROR
+ _ep_message_quiet_capture(FATAL_ERROR
"Each download failed!
${logFailedURLs}
"
diff --git a/Modules/ExternalProject/extractfile.cmake.in b/Modules/ExternalProject/extractfile.cmake.in
index d9e07f12aa..d46de73408 100644
--- a/Modules/ExternalProject/extractfile.cmake.in
+++ b/Modules/ExternalProject/extractfile.cmake.in
@@ -3,17 +3,24 @@
cmake_minimum_required(VERSION 3.5)
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
+
# Make file names absolute:
#
get_filename_component(filename "@filename@" ABSOLUTE)
get_filename_component(directory "@directory@" ABSOLUTE)
-message(STATUS "extracting...
+_ep_message_quiet_capture(STATUS "extracting...
src='${filename}'
- dst='${directory}'")
+ dst='${directory}'"
+)
if(NOT EXISTS "${filename}")
- message(FATAL_ERROR "File to extract does not exist: '${filename}'")
+ _ep_message_quiet_capture(FATAL_ERROR
+ "File to extract does not exist: '${filename}'"
+ )
endif()
# Prepare a space for extracting:
@@ -27,20 +34,23 @@ file(MAKE_DIRECTORY "${ut_dir}")
# Extract it:
#
-message(STATUS "extracting... [tar @args@]")
+_ep_message_quiet_capture(STATUS "extracting... [tar @args@]")
execute_process(COMMAND ${CMAKE_COMMAND} -E tar @args@ ${filename}
WORKING_DIRECTORY ${ut_dir}
- RESULT_VARIABLE rv)
+ RESULT_VARIABLE rv
+ ${capture_output}
+)
+_ep_accumulate_captured_output()
if(NOT rv EQUAL 0)
- message(STATUS "extracting... [error clean up]")
+ _ep_message_quiet_capture(STATUS "extracting... [error clean up]")
file(REMOVE_RECURSE "${ut_dir}")
- message(FATAL_ERROR "Extract of '${filename}' failed")
+ _ep_message_quiet_capture(FATAL_ERROR "Extract of '${filename}' failed")
endif()
# Analyze what came out of the tar file:
#
-message(STATUS "extracting... [analysis]")
+_ep_message_quiet_capture(STATUS "extracting... [analysis]")
file(GLOB contents "${ut_dir}/*")
list(REMOVE_ITEM contents "${ut_dir}/.DS_Store")
list(LENGTH contents n)
@@ -50,14 +60,14 @@ endif()
# Move "the one" directory to the final directory:
#
-message(STATUS "extracting... [rename]")
+_ep_message_quiet_capture(STATUS "extracting... [rename]")
file(REMOVE_RECURSE ${directory})
get_filename_component(contents ${contents} ABSOLUTE)
file(RENAME ${contents} ${directory})
# Clean up:
#
-message(STATUS "extracting... [clean up]")
+_ep_message_quiet_capture(STATUS "extracting... [clean up]")
file(REMOVE_RECURSE "${ut_dir}")
-message(STATUS "extracting... done")
+_ep_message_quiet_capture(STATUS "extracting... done")
diff --git a/Modules/ExternalProject/gitclone.cmake.in b/Modules/ExternalProject/gitclone.cmake.in
index 5e5c4156e3..a2e900c112 100644
--- a/Modules/ExternalProject/gitclone.cmake.in
+++ b/Modules/ExternalProject/gitclone.cmake.in
@@ -3,57 +3,81 @@
cmake_minimum_required(VERSION 3.5)
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
+
if(NOT "@gitclone_infofile@" IS_NEWER_THAN "@gitclone_stampfile@")
- message(STATUS "Avoiding repeated git clone, stamp file is up to date: '@gitclone_stampfile@'")
+ if(NOT quiet)
+ message(STATUS
+ "Avoiding repeated git clone, stamp file is up to date: "
+ "'@gitclone_stampfile@'"
+ )
+ endif()
return()
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E rm -rf "@source_dir@"
RESULT_VARIABLE error_code
- )
-if(error_code)
- message(FATAL_ERROR "Failed to remove directory: '@source_dir@'")
-endif()
+ ${capture_output}
+)
+_ep_command_check_result(
+ error_code "Failed to remove directory: '@source_dir@'"
+)
# try the clone 3 times in case there is an odd git clone issue
set(error_code 1)
set(number_of_tries 0)
while(error_code AND number_of_tries LESS 3)
+ # If you are seeing the following call hang and you have QUIET enabled, try
+ # turning QUIET off to show any output immediately. The command may be
+ # blocking while waiting for user input (e.g. a password to a SSH key).
execute_process(
- COMMAND "@git_EXECUTABLE@" @git_options@ clone @git_clone_options@ "@git_repository@" "@src_name@"
+ COMMAND "@git_EXECUTABLE@" @git_options@
+ clone @git_clone_options@ "@git_repository@" "@src_name@"
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
- )
+ ${capture_output}
+ )
+ if(NOT "${out_var}" STREQUAL "")
+ string(APPEND accumulated_output "${out_var}\n")
+ endif()
math(EXPR number_of_tries "${number_of_tries} + 1")
endwhile()
if(number_of_tries GREATER 1)
- message(STATUS "Had to git clone more than once:
- ${number_of_tries} times.")
-endif()
-if(error_code)
- message(FATAL_ERROR "Failed to clone repository: '@git_repository@'")
+ set(msg "Had to git clone more than once: ${number_of_tries} times.")
+ if(quiet)
+ string(APPEND accumulated_output "${msg}\n")
+ else()
+ message(STATUS "${msg}")
+ endif()
endif()
+_ep_command_check_result(
+ error_code "Failed to clone repository: '@git_repository@'"
+)
execute_process(
- COMMAND "@git_EXECUTABLE@" @git_options@ checkout "@git_tag@" @git_checkout_explicit--@
+ COMMAND "@git_EXECUTABLE@" @git_options@
+ checkout "@git_tag@" @git_checkout_explicit--@
WORKING_DIRECTORY "@work_dir@/@src_name@"
RESULT_VARIABLE error_code
- )
-if(error_code)
- message(FATAL_ERROR "Failed to checkout tag: '@git_tag@'")
-endif()
+ ${capture_output}
+)
+_ep_command_check_result(error_code "Failed to checkout tag: '@git_tag@'")
set(init_submodules @init_submodules@)
if(init_submodules)
execute_process(
- COMMAND "@git_EXECUTABLE@" @git_options@ submodule update @git_submodules_recurse@ --init @git_submodules@
+ COMMAND "@git_EXECUTABLE@" @git_options@
+ submodule update @git_submodules_recurse@ --init @git_submodules@
WORKING_DIRECTORY "@work_dir@/@src_name@"
RESULT_VARIABLE error_code
- )
-endif()
-if(error_code)
- message(FATAL_ERROR "Failed to update submodules in: '@work_dir@/@src_name@'")
+ ${capture_output}
+ )
+ _ep_command_check_result(
+ error_code "Failed to update submodules in: '@work_dir@/@src_name@'"
+ )
endif()
# Complete success, update the script-last-run stamp file:
@@ -61,7 +85,8 @@ endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "@gitclone_infofile@" "@gitclone_stampfile@"
RESULT_VARIABLE error_code
- )
-if(error_code)
- message(FATAL_ERROR "Failed to copy script-last-run stamp file: '@gitclone_stampfile@'")
-endif()
+ ${capture_output}
+)
+_ep_command_check_result(
+ error_code "Failed to copy script-last-run stamp file: '@gitclone_stampfile@'"
+)
diff --git a/Modules/ExternalProject/gitupdate.cmake.in b/Modules/ExternalProject/gitupdate.cmake.in
index 7033918056..fc2a6aba5e 100644
--- a/Modules/ExternalProject/gitupdate.cmake.in
+++ b/Modules/ExternalProject/gitupdate.cmake.in
@@ -3,6 +3,10 @@
cmake_minimum_required(VERSION 3.5)
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
+
function(get_hash_for_ref ref out_var err_var)
execute_process(
COMMAND "@git_EXECUTABLE@" rev-parse "${ref}"
@@ -49,7 +53,7 @@ elseif(show_ref_output MATCHES "^[a-z0-9]+[ \\t]+refs/tags/")
# FIXME: We should provide an option to always fetch for this case
get_hash_for_ref("@git_tag@" tag_sha error_msg)
if(tag_sha STREQUAL head_sha)
- message(VERBOSE "Already at requested tag: ${tag_sha}")
+ _ep_message_quiet_capture(VERBOSE "Already at requested tag: ${tag_sha}")
return()
endif()
@@ -65,7 +69,7 @@ else()
get_hash_for_ref("@git_tag@" tag_sha error_msg)
if(tag_sha STREQUAL head_sha)
# Have the right commit checked out already
- message(VERBOSE "Already at requested ref: ${tag_sha}")
+ _ep_message_quiet_capture(VERBOSE "Already at requested ref: ${tag_sha}")
return()
elseif(tag_sha STREQUAL "")
@@ -76,7 +80,7 @@ else()
set(fetch_required YES)
set(checkout_name "@git_tag@")
if(NOT error_msg STREQUAL "")
- message(VERBOSE "${error_msg}")
+ _ep_message_quiet_capture(VERBOSE "${error_msg}")
endif()
else()
@@ -86,18 +90,22 @@ else()
set(fetch_required NO)
set(checkout_name "@git_tag@")
if(NOT error_msg STREQUAL "")
- message(WARNING "${error_msg}")
+ _ep_message_quiet_capture(WARNING "${error_msg}")
endif()
endif()
endif()
if(fetch_required)
- message(VERBOSE "Fetching latest from the remote @git_remote_name@")
+ _ep_message_quiet_capture(VERBOSE "Fetching latest from the remote @git_remote_name@")
execute_process(
COMMAND "@git_EXECUTABLE@" fetch --tags --force "@git_remote_name@"
WORKING_DIRECTORY "@work_dir@"
- COMMAND_ERROR_IS_FATAL ANY
+ RESULT_VARIABLE error_code
+ ${capture_output}
+ )
+ _ep_command_check_result(
+ error_code "Failed to fetch from the remote @git_remote_name@'"
)
endif()
@@ -128,12 +136,15 @@ if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$")
else()
execute_process(
- COMMAND "@git_EXECUTABLE@" for-each-ref "--format='%(upstream:short)'" "${current_branch}"
+ COMMAND "@git_EXECUTABLE@" for-each-ref
+ "--format='%(upstream:short)'" "${current_branch}"
WORKING_DIRECTORY "@work_dir@"
+ RESULT_VARIABLE error_code # There is no error if no upstream is set
OUTPUT_VARIABLE upstream_branch
OUTPUT_STRIP_TRAILING_WHITESPACE
- COMMAND_ERROR_IS_FATAL ANY # There is no error if no upstream is set
+ ${capture_error_only}
)
+ _ep_command_check_result(error_code)
if(NOT upstream_branch STREQUAL checkout_name)
# Not safe to rebase when asked to checkout a different branch to the one
# we are tracking. If we did rebase, we could end up with arbitrary
@@ -145,7 +156,9 @@ if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$")
endif()
elseif(NOT git_update_strategy STREQUAL "CHECKOUT")
- message(FATAL_ERROR "Unsupported git update strategy: ${git_update_strategy}")
+ _ep_message_quiet_capture(FATAL_ERROR
+ "Unsupported git update strategy: ${git_update_strategy}"
+ )
endif()
@@ -155,10 +168,9 @@ execute_process(
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
OUTPUT_VARIABLE repo_status
+ ${capture_error_only}
)
-if(error_code)
- message(FATAL_ERROR "Failed to get the status")
-endif()
+_ep_command_check_result(error_code "Failed to get the status")
string(LENGTH "${repo_status}" need_stash)
# If not in clean state, stash changes in order to be able to perform a
@@ -167,16 +179,20 @@ if(need_stash)
execute_process(
COMMAND "@git_EXECUTABLE@" stash save @git_stash_save_options@
WORKING_DIRECTORY "@work_dir@"
- COMMAND_ERROR_IS_FATAL ANY
+ RESULT_VARIABLE error_code
+ ${capture_output}
)
+ _ep_command_check_result(error_code)
endif()
if(git_update_strategy STREQUAL "CHECKOUT")
execute_process(
COMMAND "@git_EXECUTABLE@" checkout "${checkout_name}"
WORKING_DIRECTORY "@work_dir@"
- COMMAND_ERROR_IS_FATAL ANY
+ RESULT_VARIABLE error_code
+ ${capture_output}
)
+ _ep_command_check_result(error_code)
else()
execute_process(
COMMAND "@git_EXECUTABLE@" rebase "${checkout_name}"
@@ -198,12 +214,14 @@ else()
execute_process(
COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
WORKING_DIRECTORY "@work_dir@"
- )
+ )
endif()
- message(FATAL_ERROR "\nFailed to rebase in: '@work_dir@'."
- "\nOutput from the attempted rebase follows:"
- "\n${rebase_output}"
- "\n\nYou will have to resolve the conflicts manually")
+ _ep_message_quiet_capture(FATAL_ERROR
+ "\nFailed to rebase in: '@work_dir@'."
+ "\nOutput from the attempted rebase follows:"
+ "\n${rebase_output}"
+ "\n\nYou will have to resolve the conflicts manually"
+ )
endif()
# Fall back to checkout. We create an annotated tag so that the user
@@ -215,21 +233,27 @@ else()
set(tag_name _cmake_ExternalProject_moved_from_here_${tag_timestamp}Z)
set(error_log_file ${CMAKE_CURRENT_LIST_DIR}/rebase_error_${tag_timestamp}Z.log)
file(WRITE ${error_log_file} "${rebase_output}")
- message(WARNING "Rebase failed, output has been saved to ${error_log_file}"
- "\nFalling back to checkout, previous commit tagged as ${tag_name}")
+ _ep_message_quiet_capture(WARNING
+ "Rebase failed, output has been saved to ${error_log_file}"
+ "\nFalling back to checkout, previous commit tagged as ${tag_name}"
+ )
execute_process(
COMMAND "@git_EXECUTABLE@" tag -a
-m "ExternalProject attempting to move from here to ${checkout_name}"
${tag_name}
WORKING_DIRECTORY "@work_dir@"
- COMMAND_ERROR_IS_FATAL ANY
+ RESULT_VARIABLE error_code
+ ${capture_output}
)
+ _ep_command_check_result(error_code)
execute_process(
COMMAND "@git_EXECUTABLE@" checkout "${checkout_name}"
WORKING_DIRECTORY "@work_dir@"
- COMMAND_ERROR_IS_FATAL ANY
+ RESULT_VARIABLE error_code
+ ${capture_output}
)
+ _ep_command_check_result(error_code)
endif()
endif()
@@ -239,30 +263,42 @@ if(need_stash)
COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
- )
+ ${capture_output}
+ )
+ _ep_accumulate_captured_output()
if(error_code)
# Stash pop --index failed: Try again dropping the index
execute_process(
COMMAND "@git_EXECUTABLE@" reset --hard --quiet
WORKING_DIRECTORY "@work_dir@"
+ ${capture_output}
)
+ _ep_accumulate_captured_output()
execute_process(
COMMAND "@git_EXECUTABLE@" stash pop --quiet
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
+ ${capture_output}
)
+ _ep_accumulate_captured_output()
if(error_code)
# Stash pop failed: Restore previous state.
execute_process(
COMMAND "@git_EXECUTABLE@" reset --hard --quiet ${head_sha}
WORKING_DIRECTORY "@work_dir@"
+ ${capture_output}
)
+ _ep_accumulate_captured_output()
execute_process(
COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
WORKING_DIRECTORY "@work_dir@"
+ ${capture_output}
+ )
+ _ep_accumulate_captured_output()
+ _ep_message_quiet_capture(FATAL_ERROR
+ "Failed to unstash changes in: '@work_dir@'.\n"
+ "You will have to resolve the conflicts manually"
)
- message(FATAL_ERROR "\nFailed to unstash changes in: '@work_dir@'."
- "\nYou will have to resolve the conflicts manually")
endif()
endif()
endif()
@@ -272,6 +308,8 @@ if(init_submodules)
execute_process(
COMMAND "@git_EXECUTABLE@" submodule update @git_submodules_recurse@ --init @git_submodules@
WORKING_DIRECTORY "@work_dir@"
- COMMAND_ERROR_IS_FATAL ANY
+ RESULT_VARIABLE error_code
+ ${capture_output}
)
+ _ep_command_check_result(error_code)
endif()
diff --git a/Modules/ExternalProject/hgclone.cmake.in b/Modules/ExternalProject/hgclone.cmake.in
index 09395cc19f..5561955cad 100644
--- a/Modules/ExternalProject/hgclone.cmake.in
+++ b/Modules/ExternalProject/hgclone.cmake.in
@@ -3,43 +3,56 @@
cmake_minimum_required(VERSION 3.5)
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
+
if(NOT "@hgclone_infofile@" IS_NEWER_THAN "@hgclone_stampfile@")
- message(STATUS "Avoiding repeated hg clone, stamp file is up to date: '@hgclone_stampfile@'")
+ if(NOT quiet)
+ message(STATUS
+ "Avoiding repeated hg clone, stamp file is up to date: "
+ "'@hgclone_stampfile@'"
+ )
+ endif()
return()
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} -E rm -rf "@source_dir@"
RESULT_VARIABLE error_code
- )
-if(error_code)
- message(FATAL_ERROR "Failed to remove directory: '@source_dir@'")
-endif()
+ ${capture_output}
+)
+_ep_command_check_result(
+ error_code "Failed to remove directory: '@source_dir@'"
+)
execute_process(
COMMAND "@hg_EXECUTABLE@" clone -U "@hg_repository@" "@src_name@"
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE error_code
- )
-if(error_code)
- message(FATAL_ERROR "Failed to clone repository: '@hg_repository@'")
-endif()
+ ${capture_output}
+)
+_ep_command_check_result(
+ error_code "Failed to clone repository: '@hg_repository@'"
+)
execute_process(
COMMAND "@hg_EXECUTABLE@" update @hg_tag@
WORKING_DIRECTORY "@work_dir@/@src_name@"
RESULT_VARIABLE error_code
- )
-if(error_code)
- message(FATAL_ERROR "Failed to checkout tag: '@hg_tag@'")
-endif()
+ ${capture_output}
+)
+_ep_command_check_result(
+ error_code "Failed to checkout tag: '@hg_tag@'"
+)
# Complete success, update the script-last-run stamp file:
#
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy "@hgclone_infofile@" "@hgclone_stampfile@"
RESULT_VARIABLE error_code
- )
-if(error_code)
- message(FATAL_ERROR "Failed to copy script-last-run stamp file: '@hgclone_stampfile@'")
-endif()
+ ${capture_output}
+)
+_ep_command_check_result(
+ error_code "Failed to copy script-last-run stamp file: '@hgclone_stampfile@'"
+)
diff --git a/Modules/ExternalProject/hgupdate.cmake.in b/Modules/ExternalProject/hgupdate.cmake.in
index f88e1eef44..a82a819f47 100644
--- a/Modules/ExternalProject/hgupdate.cmake.in
+++ b/Modules/ExternalProject/hgupdate.cmake.in
@@ -3,14 +3,22 @@
cmake_minimum_required(VERSION 3.19)
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
+
execute_process(
COMMAND "@hg_EXECUTABLE@" pull
- COMMAND_ERROR_IS_FATAL ANY
WORKING_DIRECTORY "@work_dir@"
+ RESULT_VARIABLE error_code
+ ${capture_output}
)
+_ep_command_check_result(error_code)
execute_process(
COMMAND "@hg_EXECUTABLE@" update @hg_tag@
- COMMAND_ERROR_IS_FATAL ANY
WORKING_DIRECTORY "@work_dir@"
+ RESULT_VARIABLE error_code
+ ${capture_output}
)
+_ep_command_check_result(error_code)
diff --git a/Modules/ExternalProject/verify.cmake.in b/Modules/ExternalProject/verify.cmake.in
index f37059bf74..cd34ba95ea 100644
--- a/Modules/ExternalProject/verify.cmake.in
+++ b/Modules/ExternalProject/verify.cmake.in
@@ -3,6 +3,10 @@
cmake_minimum_required(VERSION 3.5)
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
+
if("@LOCAL@" STREQUAL "")
message(FATAL_ERROR "LOCAL can't be empty")
endif()
@@ -13,22 +17,27 @@ endif()
function(do_verify)
if("@ALGO@" STREQUAL "")
- message(WARNING "File will not be verified since no URL_HASH specified")
+ _ep_message_quiet_capture(WARNING
+ "File will not be verified since no URL_HASH specified"
+ )
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
return()
endif()
if("@EXPECT_VALUE@" STREQUAL "")
- message(FATAL_ERROR "EXPECT_VALUE can't be empty")
+ _ep_message_quiet_capture(FATAL_ERROR "EXPECT_VALUE can't be empty")
endif()
- message(STATUS
+ _ep_message_quiet_capture(STATUS
"verifying file...
- file='@LOCAL@'")
+ file='@LOCAL@'"
+ )
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
file("@ALGO@" "@LOCAL@" actual_value)
if(NOT "${actual_value}" STREQUAL "@EXPECT_VALUE@")
- message(FATAL_ERROR
+ _ep_message_quiet_capture(FATAL_ERROR
"error: @ALGO@ hash of
@LOCAL@
does not match expected value
@@ -37,7 +46,8 @@ does not match expected value
")
endif()
- message(STATUS "verifying file... done")
+ _ep_message_quiet_capture(STATUS "verifying file... done")
+ set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
endfunction()
do_verify()
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 8adef47778..6a4cf38884 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -849,8 +849,6 @@ function(__FetchContent_directPopulate contentName)
SUBBUILD_DIR
SOURCE_DIR
BINARY_DIR
- # We need special processing if DOWNLOAD_NO_EXTRACT is true
- DOWNLOAD_NO_EXTRACT
# Prevent the following from being passed through
CONFIGURE_COMMAND
BUILD_COMMAND
@@ -894,123 +892,28 @@ function(__FetchContent_directPopulate contentName)
set(${contentName}_SOURCE_DIR "${ARG_SOURCE_DIR}" PARENT_SCOPE)
set(${contentName}_BINARY_DIR "${ARG_BINARY_DIR}" PARENT_SCOPE)
- # The unparsed arguments may contain spaces, so build up ARG_EXTRA
- # in such a way that it correctly substitutes into the generated
- # CMakeLists.txt file with each argument quoted.
- unset(ARG_EXTRA)
- foreach(arg IN LISTS ARG_UNPARSED_ARGUMENTS)
- set(ARG_EXTRA "${ARG_EXTRA} \"${arg}\"")
- endforeach()
-
- if(ARG_DOWNLOAD_NO_EXTRACT)
- set(ARG_EXTRA "${ARG_EXTRA} DOWNLOAD_NO_EXTRACT YES")
- set(__FETCHCONTENT_COPY_FILE
-"
-ExternalProject_Get_Property(${contentName}-populate DOWNLOADED_FILE)
-get_filename_component(dlFileName \"\${DOWNLOADED_FILE}\" NAME)
-
-ExternalProject_Add_Step(${contentName}-populate copyfile
- COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
- \"<DOWNLOADED_FILE>\" \"${ARG_SOURCE_DIR}\"
- DEPENDEES patch
- DEPENDERS configure
- BYPRODUCTS \"${ARG_SOURCE_DIR}/\${dlFileName}\"
- COMMENT \"Copying file to SOURCE_DIR\"
-)
-")
+ if(ARG_QUIET)
+ set(quiet TRUE)
else()
- unset(__FETCHCONTENT_COPY_FILE)
- endif()
-
- # Hide output if requested, but save it to a variable in case there's an
- # error so we can show the output upon failure. When not quiet, don't
- # capture the output to a variable because the user may want to see the
- # output as it happens (e.g. progress during long downloads). Combine both
- # stdout and stderr in the one capture variable so the output stays in order.
- if (ARG_QUIET)
- set(outputOptions
- OUTPUT_VARIABLE capturedOutput
- ERROR_VARIABLE capturedOutput
- )
- else()
- set(capturedOutput)
- set(outputOptions)
+ set(quiet FALSE)
message(STATUS "Populating ${contentName}")
endif()
- if(CMAKE_GENERATOR)
- set(subCMakeOpts "-G${CMAKE_GENERATOR}")
- if(CMAKE_GENERATOR_PLATFORM)
- list(APPEND subCMakeOpts "-A${CMAKE_GENERATOR_PLATFORM}")
- endif()
- if(CMAKE_GENERATOR_TOOLSET)
- list(APPEND subCMakeOpts "-T${CMAKE_GENERATOR_TOOLSET}")
- endif()
-
- if(CMAKE_MAKE_PROGRAM)
- list(APPEND subCMakeOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
- endif()
-
- else()
- # Likely we've been invoked via CMake's script mode where no
- # generator is set (and hence CMAKE_MAKE_PROGRAM could not be
- # trusted even if provided). We will have to rely on being
- # able to find the default generator and build tool.
- unset(subCMakeOpts)
- endif()
-
- if(DEFINED CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY)
- list(APPEND subCMakeOpts
- "-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.
- # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
- # has this set to something not findable on the PATH.
- configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in"
- "${ARG_SUBBUILD_DIR}/CMakeLists.txt")
- execute_process(
- COMMAND ${CMAKE_COMMAND} ${subCMakeOpts} .
- RESULT_VARIABLE result
- ${outputOptions}
- WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
- )
- if(result)
- if(capturedOutput)
- message("${capturedOutput}")
- endif()
- message(FATAL_ERROR "CMake step for ${contentName} failed: ${result}")
- endif()
- execute_process(
- COMMAND ${CMAKE_COMMAND} --build .
- RESULT_VARIABLE result
- ${outputOptions}
- WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
+ include(ExternalProject)
+ set(argsQuoted)
+ foreach(__item IN LISTS ARG_UNPARSED_ARGUMENTS)
+ string(APPEND argsQuoted " [==[${__item}]==]")
+ endforeach()
+ cmake_language(EVAL CODE "
+ _ep_do_preconfigure_steps_now(${contentName}
+ ${argsQuoted}
+ QUIET ${quiet}
+ SOURCE_DIR [==[${ARG_SOURCE_DIR}]==]
+ BINARY_DIR [==[${ARG_BINARY_DIR}]==]
+ USES_TERMINAL_DOWNLOAD YES
+ USES_TERMINAL_UPDATE YES
+ )"
)
- if(result)
- if(capturedOutput)
- message("${capturedOutput}")
- endif()
- message(FATAL_ERROR "Build step for ${contentName} failed: ${result}")
- endif()
endfunction()
diff --git a/Modules/FetchContent/CMakeLists.cmake.in b/Modules/FetchContent/CMakeLists.cmake.in
deleted file mode 100644
index 5ebb12f1ad..0000000000
--- a/Modules/FetchContent/CMakeLists.cmake.in
+++ /dev/null
@@ -1,27 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-cmake_minimum_required(VERSION ${CMAKE_VERSION})
-
-# We name the project and the target for the ExternalProject_Add() call
-# to something that will highlight to the user what we are working on if
-# something goes wrong and an error message is produced.
-
-project(${contentName}-populate NONE)
-
-@__FETCHCONTENT_CACHED_INFO@
-
-include(ExternalProject)
-ExternalProject_Add(${contentName}-populate
- ${ARG_EXTRA}
- SOURCE_DIR "${ARG_SOURCE_DIR}"
- BINARY_DIR "${ARG_BINARY_DIR}"
- CONFIGURE_COMMAND ""
- BUILD_COMMAND ""
- INSTALL_COMMAND ""
- TEST_COMMAND ""
- USES_TERMINAL_DOWNLOAD YES
- USES_TERMINAL_UPDATE YES
-)
-
-@__FETCHCONTENT_COPY_FILE@
diff --git a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
index 9baeab75e2..b4973827a3 100644
--- a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
@@ -7,7 +7,6 @@ run_cmake(DirectIgnoresDetails)
run_cmake(FirstDetailsWin)
run_cmake(DownloadTwice)
run_cmake(DownloadFile)
-run_cmake(SameGenerator)
run_cmake(VarDefinitions)
run_cmake(GetProperties)
run_cmake(UsesTerminalOverride)
diff --git a/Tests/RunCMake/FetchContent/SameGenerator.cmake b/Tests/RunCMake/FetchContent/SameGenerator.cmake
deleted file mode 100644
index 58204ef041..0000000000
--- a/Tests/RunCMake/FetchContent/SameGenerator.cmake
+++ /dev/null
@@ -1,17 +0,0 @@
-include(FetchContent)
-
-FetchContent_Declare(
- t1
- DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E echo "Download command executed"
-)
-
-FetchContent_Populate(t1)
-
-file(STRINGS "${FETCHCONTENT_BASE_DIR}/t1-subbuild/CMakeCache.txt"
- matchLine REGEX "^CMAKE_GENERATOR:.*="
- LIMIT_COUNT 1
-)
-if(NOT matchLine MATCHES "${CMAKE_GENERATOR}")
- message(FATAL_ERROR "Generator line mismatch: ${matchLine}\n"
- " Expected type: ${CMAKE_GENERATOR}")
-endif()