FetchContent: Invoke steps directly and avoid a separate sub-build

The cost of setting up and executing a separate sub-build to do the
download, update and patch steps required for FetchContent population
can be significant with some platforms and CMake generators. Avoid the
sub-build altogether by invoking the step scripts directly.

Previously, if no generator was set (e.g. population was being done in
script mode), a generator needed to be available on the default PATH.
Since we no longer use a sub-build, this restriction is also now gone.

Fixes: #21703
This commit is contained in:
Craig Scott
2021-01-29 23:22:45 +11:00
parent 4f3d1abbb4
commit 17e5516e60
16 changed files with 481 additions and 326 deletions

View File

@@ -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.

View File

@@ -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_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_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_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."
)
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

View File

@@ -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()

View File

@@ -0,0 +1,8 @@
execute_process(
COMMAND @this_command@
WORKING_DIRECTORY "@work_dir@"
RESULT_VARIABLE result
${capture_output}
)
_ep_command_check_result(result)

View File

@@ -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)

View File

@@ -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}
"

View File

@@ -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")

View File

@@ -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@'"
)

View File

@@ -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()

View File

@@ -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@'"
)

View File

@@ -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)

View File

@@ -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()

View File

@@ -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}"
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 "CMake step for ${contentName} failed: ${result}")
endif()
execute_process(
COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
${outputOptions}
WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
)
if(result)
if(capturedOutput)
message("${capturedOutput}")
endif()
message(FATAL_ERROR "Build step for ${contentName} failed: ${result}")
endif()
endfunction()

View File

@@ -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@

View File

@@ -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)

View File

@@ -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()