mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-14 02:08:27 +08:00
Revert ExternalProject and FetchContent refactoring
Refactoring of the ExternalProject and FetchContent modules moved the commands into CMake scripts. This broke custom commands that used shell redirection or special build tool variables of the form $(MakeVar). Undo the sequence of commits that performed this refactoring and follow-up fixes associated with it. The following commits are reverted by this change:4f3d1abbb4
(ExternalProject: Refactor pre-configure steps to support no-target uses, 2021-02-05)17e5516e60
(FetchContent: Invoke steps directly and avoid a separate sub-build, 2021-01-29)bd876f3849
(FetchContent: Restore patch command support, 2021-02-18)404cddb7bb
(ExternalProject: Fix misuse of IS_NEWER_THAN in timestamp checks, 2021-02-21)b0da671243
(FetchContent: Don't update timestamps if files don't change, 2021-02-18) Fixes: #21892
This commit is contained in:
@@ -318,18 +318,6 @@ Other Changes
|
||||
* Ninja generators now transform the ``DEPFILE`` generated by an
|
||||
:command:`add_custom_command`. See policy :policy:`CMP0116` for details.
|
||||
|
||||
* The implementation of the :module:`ExternalProject` module was
|
||||
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.
|
||||
|
||||
* The precompiled Linux binaries provided on
|
||||
`cmake.org <https://cmake.org/download/>`_ have changed their naming pattern
|
||||
to ``cmake-$ver-linux-$arch``, where ``$arch`` is either ``x86_64`` or
|
||||
|
173
Modules/ExternalProject-download.cmake.in
Normal file
173
Modules/ExternalProject-download.cmake.in
Normal file
@@ -0,0 +1,173 @@
|
||||
# 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)
|
||||
|
||||
function(check_file_hash has_hash hash_is_good)
|
||||
if("${has_hash}" STREQUAL "")
|
||||
message(FATAL_ERROR "has_hash Can't be empty")
|
||||
endif()
|
||||
|
||||
if("${hash_is_good}" STREQUAL "")
|
||||
message(FATAL_ERROR "hash_is_good Can't be empty")
|
||||
endif()
|
||||
|
||||
if("@ALGO@" STREQUAL "")
|
||||
# No check
|
||||
set("${has_hash}" FALSE PARENT_SCOPE)
|
||||
set("${hash_is_good}" FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set("${has_hash}" TRUE PARENT_SCOPE)
|
||||
|
||||
message(STATUS "verifying file...
|
||||
file='@LOCAL@'")
|
||||
|
||||
file("@ALGO@" "@LOCAL@" actual_value)
|
||||
|
||||
if(NOT "${actual_value}" STREQUAL "@EXPECT_VALUE@")
|
||||
set("${hash_is_good}" FALSE PARENT_SCOPE)
|
||||
message(STATUS "@ALGO@ hash of
|
||||
@LOCAL@
|
||||
does not match expected value
|
||||
expected: '@EXPECT_VALUE@'
|
||||
actual: '${actual_value}'")
|
||||
else()
|
||||
set("${hash_is_good}" TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(sleep_before_download attempt)
|
||||
if(attempt EQUAL 0)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(attempt EQUAL 1)
|
||||
message(STATUS "Retrying...")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(sleep_seconds 0)
|
||||
|
||||
if(attempt EQUAL 2)
|
||||
set(sleep_seconds 5)
|
||||
elseif(attempt EQUAL 3)
|
||||
set(sleep_seconds 5)
|
||||
elseif(attempt EQUAL 4)
|
||||
set(sleep_seconds 15)
|
||||
elseif(attempt EQUAL 5)
|
||||
set(sleep_seconds 60)
|
||||
elseif(attempt EQUAL 6)
|
||||
set(sleep_seconds 90)
|
||||
elseif(attempt EQUAL 7)
|
||||
set(sleep_seconds 300)
|
||||
else()
|
||||
set(sleep_seconds 1200)
|
||||
endif()
|
||||
|
||||
message(STATUS "Retry after ${sleep_seconds} seconds (attempt #${attempt}) ...")
|
||||
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep "${sleep_seconds}")
|
||||
endfunction()
|
||||
|
||||
if("@LOCAL@" STREQUAL "")
|
||||
message(FATAL_ERROR "LOCAL can't be empty")
|
||||
endif()
|
||||
|
||||
if("@REMOTE@" STREQUAL "")
|
||||
message(FATAL_ERROR "REMOTE can't be empty")
|
||||
endif()
|
||||
|
||||
if(EXISTS "@LOCAL@")
|
||||
check_file_hash(has_hash hash_is_good)
|
||||
if(has_hash)
|
||||
if(hash_is_good)
|
||||
message(STATUS "File already exists and hash match (skip download):
|
||||
file='@LOCAL@'
|
||||
@ALGO@='@EXPECT_VALUE@'"
|
||||
)
|
||||
return()
|
||||
else()
|
||||
message(STATUS "File already exists but hash mismatch. Removing...")
|
||||
file(REMOVE "@LOCAL@")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "File already exists but no hash specified (use URL_HASH):
|
||||
file='@LOCAL@'
|
||||
Old file will be removed and new file downloaded from URL."
|
||||
)
|
||||
file(REMOVE "@LOCAL@")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(retry_number 5)
|
||||
|
||||
message(STATUS "Downloading...
|
||||
dst='@LOCAL@'
|
||||
timeout='@TIMEOUT_MSG@'
|
||||
inactivity timeout='@INACTIVITY_TIMEOUT_MSG@'"
|
||||
)
|
||||
set(download_retry_codes 7 6 8 15)
|
||||
set(skip_url_list)
|
||||
set(status_code)
|
||||
foreach(i RANGE ${retry_number})
|
||||
if(status_code IN_LIST download_retry_codes)
|
||||
sleep_before_download(${i})
|
||||
endif()
|
||||
foreach(url @REMOTE@)
|
||||
if(NOT url IN_LIST skip_url_list)
|
||||
message(STATUS "Using src='${url}'")
|
||||
|
||||
@TLS_VERIFY_CODE@
|
||||
@TLS_CAINFO_CODE@
|
||||
@NETRC_CODE@
|
||||
@NETRC_FILE_CODE@
|
||||
|
||||
file(
|
||||
DOWNLOAD
|
||||
"${url}" "@LOCAL@"
|
||||
@SHOW_PROGRESS@
|
||||
@TIMEOUT_ARGS@
|
||||
@INACTIVITY_TIMEOUT_ARGS@
|
||||
STATUS status
|
||||
LOG log
|
||||
@USERPWD_ARGS@
|
||||
@HTTP_HEADERS_ARGS@
|
||||
)
|
||||
|
||||
list(GET status 0 status_code)
|
||||
list(GET status 1 status_string)
|
||||
|
||||
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...")
|
||||
file(REMOVE "@LOCAL@")
|
||||
else()
|
||||
message(STATUS "Downloading... done")
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
string(APPEND logFailedURLs "error: downloading '${url}' failed
|
||||
status_code: ${status_code}
|
||||
status_string: ${status_string}
|
||||
log:
|
||||
--- LOG BEGIN ---
|
||||
${log}
|
||||
--- LOG END ---
|
||||
"
|
||||
)
|
||||
if(NOT status_code IN_LIST download_retry_codes)
|
||||
list(APPEND skip_url_list "${url}")
|
||||
break()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
message(FATAL_ERROR "Each download failed!
|
||||
${logFailedURLs}
|
||||
"
|
||||
)
|
@@ -3,10 +3,6 @@
|
||||
|
||||
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}"
|
||||
@@ -53,7 +49,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)
|
||||
_ep_message_quiet_capture(VERBOSE "Already at requested tag: ${tag_sha}")
|
||||
message(VERBOSE "Already at requested tag: ${tag_sha}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
@@ -69,7 +65,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
|
||||
_ep_message_quiet_capture(VERBOSE "Already at requested ref: ${tag_sha}")
|
||||
message(VERBOSE "Already at requested ref: ${tag_sha}")
|
||||
return()
|
||||
|
||||
elseif(tag_sha STREQUAL "")
|
||||
@@ -80,7 +76,7 @@ else()
|
||||
set(fetch_required YES)
|
||||
set(checkout_name "@git_tag@")
|
||||
if(NOT error_msg STREQUAL "")
|
||||
_ep_message_quiet_capture(VERBOSE "${error_msg}")
|
||||
message(VERBOSE "${error_msg}")
|
||||
endif()
|
||||
|
||||
else()
|
||||
@@ -90,22 +86,18 @@ else()
|
||||
set(fetch_required NO)
|
||||
set(checkout_name "@git_tag@")
|
||||
if(NOT error_msg STREQUAL "")
|
||||
_ep_message_quiet_capture(WARNING "${error_msg}")
|
||||
message(WARNING "${error_msg}")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(fetch_required)
|
||||
_ep_message_quiet_capture(VERBOSE "Fetching latest from the remote @git_remote_name@")
|
||||
message(VERBOSE "Fetching latest from the remote @git_remote_name@")
|
||||
execute_process(
|
||||
COMMAND "@git_EXECUTABLE@" fetch --tags --force "@git_remote_name@"
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
)
|
||||
_ep_command_check_result(
|
||||
error_code "Failed to fetch from the remote @git_remote_name@'"
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -136,15 +128,12 @@ 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
|
||||
${capture_error_only}
|
||||
COMMAND_ERROR_IS_FATAL ANY # There is no error if no upstream is set
|
||||
)
|
||||
_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
|
||||
@@ -156,9 +145,7 @@ if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$")
|
||||
|
||||
endif()
|
||||
elseif(NOT git_update_strategy STREQUAL "CHECKOUT")
|
||||
_ep_message_quiet_capture(FATAL_ERROR
|
||||
"Unsupported git update strategy: ${git_update_strategy}"
|
||||
)
|
||||
message(FATAL_ERROR "Unsupported git update strategy: ${git_update_strategy}")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -168,9 +155,10 @@ execute_process(
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
RESULT_VARIABLE error_code
|
||||
OUTPUT_VARIABLE repo_status
|
||||
${capture_error_only}
|
||||
)
|
||||
_ep_command_check_result(error_code "Failed to get the status")
|
||||
if(error_code)
|
||||
message(FATAL_ERROR "Failed to get the status")
|
||||
endif()
|
||||
string(LENGTH "${repo_status}" need_stash)
|
||||
|
||||
# If not in clean state, stash changes in order to be able to perform a
|
||||
@@ -179,20 +167,16 @@ if(need_stash)
|
||||
execute_process(
|
||||
COMMAND "@git_EXECUTABLE@" stash save @git_stash_save_options@
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
_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@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
_ep_command_check_result(error_code)
|
||||
else()
|
||||
execute_process(
|
||||
COMMAND "@git_EXECUTABLE@" rebase "${checkout_name}"
|
||||
@@ -214,14 +198,12 @@ else()
|
||||
execute_process(
|
||||
COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
)
|
||||
)
|
||||
endif()
|
||||
_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"
|
||||
)
|
||||
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")
|
||||
endif()
|
||||
|
||||
# Fall back to checkout. We create an annotated tag so that the user
|
||||
@@ -233,27 +215,21 @@ 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}")
|
||||
_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}"
|
||||
)
|
||||
message(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@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
_ep_command_check_result(error_code)
|
||||
|
||||
execute_process(
|
||||
COMMAND "@git_EXECUTABLE@" checkout "${checkout_name}"
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
_ep_command_check_result(error_code)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -263,42 +239,30 @@ 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()
|
||||
@@ -308,8 +272,6 @@ if(init_submodules)
|
||||
execute_process(
|
||||
COMMAND "@git_EXECUTABLE@" submodule update @git_submodules_recurse@ --init @git_submodules@
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
COMMAND_ERROR_IS_FATAL ANY
|
||||
)
|
||||
_ep_command_check_result(error_code)
|
||||
endif()
|
37
Modules/ExternalProject-verify.cmake.in
Normal file
37
Modules/ExternalProject-verify.cmake.in
Normal file
@@ -0,0 +1,37 @@
|
||||
# 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)
|
||||
|
||||
if("@LOCAL@" STREQUAL "")
|
||||
message(FATAL_ERROR "LOCAL can't be empty")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "@LOCAL@")
|
||||
message(FATAL_ERROR "File not found: @LOCAL@")
|
||||
endif()
|
||||
|
||||
if("@ALGO@" STREQUAL "")
|
||||
message(WARNING "File will not be verified since no URL_HASH specified")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if("@EXPECT_VALUE@" STREQUAL "")
|
||||
message(FATAL_ERROR "EXPECT_VALUE can't be empty")
|
||||
endif()
|
||||
|
||||
message(STATUS "verifying file...
|
||||
file='@LOCAL@'")
|
||||
|
||||
file("@ALGO@" "@LOCAL@" actual_value)
|
||||
|
||||
if(NOT "${actual_value}" STREQUAL "@EXPECT_VALUE@")
|
||||
message(FATAL_ERROR "error: @ALGO@ hash of
|
||||
@LOCAL@
|
||||
does not match expected value
|
||||
expected: '@EXPECT_VALUE@'
|
||||
actual: '${actual_value}'
|
||||
")
|
||||
endif()
|
||||
|
||||
message(STATUS "verifying file... done")
|
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
@repo_info_content@
|
@@ -1,55 +0,0 @@
|
||||
# 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()
|
@@ -1 +0,0 @@
|
||||
cmd='@cmd@'
|
@@ -1,10 +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 3.5)
|
||||
|
||||
file(REMOVE_RECURSE "@to_dir@")
|
||||
|
||||
# Copy the _contents_ of the source dir into the destination dir, hence the
|
||||
# trailing slash on the from_dir
|
||||
file(COPY "@from_dir@/" DESTINATION "@to_dir@")
|
@@ -1,8 +0,0 @@
|
||||
|
||||
execute_process(
|
||||
COMMAND @this_command@
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
RESULT_VARIABLE result
|
||||
${capture_output}
|
||||
)
|
||||
_ep_command_check_result(result)
|
@@ -1,8 +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 3.5)
|
||||
|
||||
set(quiet "@quiet@")
|
||||
set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
|
||||
include(${script_dir}/captured_process_setup.cmake)
|
@@ -1,205 +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 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 "")
|
||||
_ep_message_quiet_capture(FATAL_ERROR "has_hash Can't be empty")
|
||||
endif()
|
||||
|
||||
if("${hash_is_good}" STREQUAL "")
|
||||
_ep_message_quiet_capture(FATAL_ERROR "hash_is_good Can't be empty")
|
||||
endif()
|
||||
|
||||
if("@ALGO@" STREQUAL "")
|
||||
# No check
|
||||
set("${has_hash}" FALSE PARENT_SCOPE)
|
||||
set("${hash_is_good}" FALSE PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set("${has_hash}" TRUE PARENT_SCOPE)
|
||||
|
||||
_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)
|
||||
_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()
|
||||
endfunction()
|
||||
|
||||
function(sleep_before_download attempt)
|
||||
if(attempt EQUAL 0)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(attempt EQUAL 1)
|
||||
_ep_message_quiet_capture(STATUS "Retrying...")
|
||||
set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(sleep_seconds 0)
|
||||
|
||||
if(attempt EQUAL 2)
|
||||
set(sleep_seconds 5)
|
||||
elseif(attempt EQUAL 3)
|
||||
set(sleep_seconds 5)
|
||||
elseif(attempt EQUAL 4)
|
||||
set(sleep_seconds 15)
|
||||
elseif(attempt EQUAL 5)
|
||||
set(sleep_seconds 60)
|
||||
elseif(attempt EQUAL 6)
|
||||
set(sleep_seconds 90)
|
||||
elseif(attempt EQUAL 7)
|
||||
set(sleep_seconds 300)
|
||||
else()
|
||||
set(sleep_seconds 1200)
|
||||
endif()
|
||||
|
||||
_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()
|
||||
|
||||
if("@LOCAL@" STREQUAL "")
|
||||
message(FATAL_ERROR "LOCAL can't be empty")
|
||||
endif()
|
||||
|
||||
if("@REMOTE@" STREQUAL "")
|
||||
message(FATAL_ERROR "REMOTE can't be empty")
|
||||
endif()
|
||||
|
||||
function(download_and_verify)
|
||||
if(EXISTS "@LOCAL@")
|
||||
check_file_hash(has_hash hash_is_good)
|
||||
if(has_hash)
|
||||
if(hash_is_good)
|
||||
_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()
|
||||
_ep_message_quiet_capture(STATUS
|
||||
"File already exists but hash mismatch. Removing..."
|
||||
)
|
||||
set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
|
||||
file(REMOVE "@LOCAL@")
|
||||
endif()
|
||||
else()
|
||||
_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."
|
||||
)
|
||||
file(REMOVE "@LOCAL@")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(retry_number 5)
|
||||
|
||||
_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)
|
||||
foreach(i RANGE ${retry_number})
|
||||
if(status_code IN_LIST download_retry_codes)
|
||||
sleep_before_download(${i})
|
||||
endif()
|
||||
foreach(url @REMOTE@)
|
||||
if(NOT url IN_LIST skip_url_list)
|
||||
_ep_message_quiet_capture(STATUS "Using src='${url}'")
|
||||
set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
|
||||
|
||||
@TLS_VERIFY_CODE@
|
||||
@TLS_CAINFO_CODE@
|
||||
@NETRC_CODE@
|
||||
@NETRC_FILE_CODE@
|
||||
|
||||
file(
|
||||
DOWNLOAD
|
||||
"${url}" "@LOCAL@"
|
||||
@SHOW_PROGRESS@
|
||||
@TIMEOUT_ARGS@
|
||||
@INACTIVITY_TIMEOUT_ARGS@
|
||||
STATUS status
|
||||
LOG log
|
||||
@USERPWD_ARGS@
|
||||
@HTTP_HEADERS_ARGS@
|
||||
)
|
||||
|
||||
list(GET status 0 status_code)
|
||||
list(GET status 1 status_string)
|
||||
|
||||
if(status_code EQUAL 0)
|
||||
check_file_hash(has_hash hash_is_good)
|
||||
if(has_hash AND NOT hash_is_good)
|
||||
_ep_message_quiet_capture(STATUS "Hash mismatch, removing...")
|
||||
set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
|
||||
file(REMOVE "@LOCAL@")
|
||||
else()
|
||||
_ep_message_quiet_capture(STATUS "Downloading... done")
|
||||
set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
string(APPEND logFailedURLs
|
||||
"error: downloading '${url}' failed
|
||||
status_code: ${status_code}
|
||||
status_string: ${status_string}
|
||||
log:
|
||||
--- LOG BEGIN ---
|
||||
${log}
|
||||
--- LOG END ---
|
||||
"
|
||||
)
|
||||
if(NOT status_code IN_LIST download_retry_codes)
|
||||
list(APPEND skip_url_list "${url}")
|
||||
break()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
_ep_message_quiet_capture(FATAL_ERROR
|
||||
"Each download failed!
|
||||
${logFailedURLs}
|
||||
"
|
||||
)
|
||||
|
||||
endfunction()
|
||||
|
||||
download_and_verify()
|
||||
|
||||
set(extract_script @extract_script_filename@)
|
||||
if(NOT "${extract_script}" STREQUAL "")
|
||||
include(${extract_script})
|
||||
endif()
|
@@ -1,73 +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 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)
|
||||
|
||||
_ep_message_quiet_capture(STATUS "extracting...
|
||||
src='${filename}'
|
||||
dst='${directory}'"
|
||||
)
|
||||
|
||||
if(NOT EXISTS "${filename}")
|
||||
_ep_message_quiet_capture(FATAL_ERROR
|
||||
"File to extract does not exist: '${filename}'"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Prepare a space for extracting:
|
||||
#
|
||||
set(i 1234)
|
||||
while(EXISTS "${directory}/../ex-@name@${i}")
|
||||
math(EXPR i "${i} + 1")
|
||||
endwhile()
|
||||
set(ut_dir "${directory}/../ex-@name@${i}")
|
||||
file(MAKE_DIRECTORY "${ut_dir}")
|
||||
|
||||
# Extract it:
|
||||
#
|
||||
_ep_message_quiet_capture(STATUS "extracting... [tar @args@]")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E tar @args@ ${filename}
|
||||
WORKING_DIRECTORY ${ut_dir}
|
||||
RESULT_VARIABLE rv
|
||||
${capture_output}
|
||||
)
|
||||
_ep_accumulate_captured_output()
|
||||
|
||||
if(NOT rv EQUAL 0)
|
||||
_ep_message_quiet_capture(STATUS "extracting... [error clean up]")
|
||||
file(REMOVE_RECURSE "${ut_dir}")
|
||||
_ep_message_quiet_capture(FATAL_ERROR "Extract of '${filename}' failed")
|
||||
endif()
|
||||
|
||||
# Analyze what came out of the tar file:
|
||||
#
|
||||
_ep_message_quiet_capture(STATUS "extracting... [analysis]")
|
||||
file(GLOB contents "${ut_dir}/*")
|
||||
list(REMOVE_ITEM contents "${ut_dir}/.DS_Store")
|
||||
list(LENGTH contents n)
|
||||
if(NOT n EQUAL 1 OR NOT IS_DIRECTORY "${contents}")
|
||||
set(contents "${ut_dir}")
|
||||
endif()
|
||||
|
||||
# Move "the one" directory to the final directory:
|
||||
#
|
||||
_ep_message_quiet_capture(STATUS "extracting... [rename]")
|
||||
file(REMOVE_RECURSE ${directory})
|
||||
get_filename_component(contents ${contents} ABSOLUTE)
|
||||
file(RENAME ${contents} ${directory})
|
||||
|
||||
# Clean up:
|
||||
#
|
||||
_ep_message_quiet_capture(STATUS "extracting... [clean up]")
|
||||
file(REMOVE_RECURSE "${ut_dir}")
|
||||
|
||||
_ep_message_quiet_capture(STATUS "extracting... done")
|
@@ -1,93 +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 3.5)
|
||||
|
||||
set(quiet "@quiet@")
|
||||
set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
|
||||
include(${script_dir}/captured_process_setup.cmake)
|
||||
|
||||
if(EXISTS "@gitclone_stampfile@" AND EXISTS "@gitclone_infofile@" AND
|
||||
"@gitclone_stampfile@" IS_NEWER_THAN "@gitclone_infofile@")
|
||||
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
|
||||
${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@"
|
||||
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)
|
||||
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--@
|
||||
WORKING_DIRECTORY "@work_dir@/@src_name@"
|
||||
RESULT_VARIABLE error_code
|
||||
${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@
|
||||
WORKING_DIRECTORY "@work_dir@/@src_name@"
|
||||
RESULT_VARIABLE error_code
|
||||
${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:
|
||||
#
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "@gitclone_infofile@" "@gitclone_stampfile@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
)
|
||||
_ep_command_check_result(
|
||||
error_code "Failed to copy script-last-run stamp file: '@gitclone_stampfile@'"
|
||||
)
|
@@ -1,59 +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 3.5)
|
||||
|
||||
set(quiet "@quiet@")
|
||||
set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
|
||||
include(${script_dir}/captured_process_setup.cmake)
|
||||
|
||||
if(EXISTS "@hgclone_stampfile@" AND EXISTS "@hgclone_infofile@" AND
|
||||
"@hgclone_stampfile@" IS_NEWER_THAN "@hgclone_infofile@")
|
||||
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
|
||||
${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
|
||||
${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
|
||||
${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
|
||||
${capture_output}
|
||||
)
|
||||
_ep_command_check_result(
|
||||
error_code "Failed to copy script-last-run stamp file: '@hgclone_stampfile@'"
|
||||
)
|
@@ -1,24 +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 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
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
)
|
||||
_ep_command_check_result(error_code)
|
||||
|
||||
execute_process(
|
||||
COMMAND "@hg_EXECUTABLE@" update @hg_tag@
|
||||
WORKING_DIRECTORY "@work_dir@"
|
||||
RESULT_VARIABLE error_code
|
||||
${capture_output}
|
||||
)
|
||||
_ep_command_check_result(error_code)
|
@@ -1,19 +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 3.5)
|
||||
|
||||
file(MAKE_DIRECTORY
|
||||
"@source_dir@"
|
||||
"@binary_dir@"
|
||||
"@install_dir@"
|
||||
"@tmp_dir@"
|
||||
"@stamp_dir@"
|
||||
"@download_dir@"
|
||||
"@log_dir@"
|
||||
)
|
||||
|
||||
set(configSubDirs @CMAKE_CONFIGURATION_TYPES@)
|
||||
foreach(subDir IN LISTS configSubDirs)
|
||||
file(MAKE_DIRECTORY "@stamp_dir@/${subDir}")
|
||||
endforeach()
|
@@ -1,58 +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 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()
|
||||
|
||||
if(NOT EXISTS "@LOCAL@")
|
||||
message(FATAL_ERROR "File not found: @LOCAL@")
|
||||
endif()
|
||||
|
||||
function(do_verify)
|
||||
if("@ALGO@" STREQUAL "")
|
||||
_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 "")
|
||||
_ep_message_quiet_capture(FATAL_ERROR "EXPECT_VALUE can't be empty")
|
||||
endif()
|
||||
|
||||
_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@")
|
||||
_ep_message_quiet_capture(FATAL_ERROR
|
||||
"error: @ALGO@ hash of
|
||||
@LOCAL@
|
||||
does not match expected value
|
||||
expected: '@EXPECT_VALUE@'
|
||||
actual: '${actual_value}'
|
||||
")
|
||||
endif()
|
||||
|
||||
_ep_message_quiet_capture(STATUS "verifying file... done")
|
||||
set(accumulated_output "${accumulated_output}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
do_verify()
|
||||
|
||||
set(extract_script "@extract_script_filename@")
|
||||
if(NOT "${extract_script}" STREQUAL "")
|
||||
include("${extract_script}")
|
||||
endif()
|
@@ -849,6 +849,8 @@ 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
|
||||
@@ -892,28 +894,123 @@ function(__FetchContent_directPopulate contentName)
|
||||
set(${contentName}_SOURCE_DIR "${ARG_SOURCE_DIR}" PARENT_SCOPE)
|
||||
set(${contentName}_BINARY_DIR "${ARG_BINARY_DIR}" PARENT_SCOPE)
|
||||
|
||||
if(ARG_QUIET)
|
||||
set(quiet TRUE)
|
||||
# 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\"
|
||||
)
|
||||
")
|
||||
else()
|
||||
set(quiet FALSE)
|
||||
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)
|
||||
message(STATUS "Populating ${contentName}")
|
||||
endif()
|
||||
|
||||
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(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}"
|
||||
)
|
||||
if(result)
|
||||
if(capturedOutput)
|
||||
message("${capturedOutput}")
|
||||
endif()
|
||||
message(FATAL_ERROR "Build step for ${contentName} failed: ${result}")
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
|
27
Modules/FetchContent/CMakeLists.cmake.in
Normal file
27
Modules/FetchContent/CMakeLists.cmake.in
Normal file
@@ -0,0 +1,27 @@
|
||||
# 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@
|
3
Modules/RepositoryInfo.txt.in
Normal file
3
Modules/RepositoryInfo.txt.in
Normal file
@@ -0,0 +1,3 @@
|
||||
repository='@repository@'
|
||||
module='@module@'
|
||||
tag='@tag@'
|
@@ -10,7 +10,7 @@ Call Stack \(most recent call first\):
|
||||
[^
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
|
||||
[^
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_preconfigure_command\)
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_mkdir_command\)
|
||||
NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
|
||||
NO_DEPENDS-CMP0114-NEW.cmake:[0-9]+ \(include\)
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
|
@@ -13,7 +13,7 @@ Call Stack \(most recent call first\):
|
||||
[^
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
|
||||
[^
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_preconfigure_command\)
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_mkdir_command\)
|
||||
NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
|
||||
NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
@@ -68,7 +68,7 @@ Call Stack \(most recent call first\):
|
||||
[^
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\)
|
||||
[^
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_preconfigure_command\)
|
||||
]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_mkdir_command\)
|
||||
NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
|
||||
NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
||||
|
@@ -13,6 +13,6 @@
|
||||
\* HG_REPOSITORY
|
||||
\* CVS_REPOSITORY and CVS_MODULE
|
||||
Call Stack \(most recent call first\):
|
||||
.*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_prepare_download\)
|
||||
.*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
|
||||
NoOptions.cmake:[0-9]+ \(ExternalProject_Add\)
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
|
@@ -13,6 +13,6 @@
|
||||
\* HG_REPOSITORY
|
||||
\* CVS_REPOSITORY and CVS_MODULE
|
||||
Call Stack \(most recent call first\):
|
||||
.*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_prepare_download\)
|
||||
.*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
|
||||
SourceEmpty.cmake:[0-9]+ \(ExternalProject_Add\)
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
|
@@ -13,6 +13,6 @@
|
||||
\* HG_REPOSITORY
|
||||
\* CVS_REPOSITORY and CVS_MODULE
|
||||
Call Stack \(most recent call first\):
|
||||
.*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_prepare_download\)
|
||||
.*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
|
||||
SourceMissing.cmake:[0-9]+ \(ExternalProject_Add\)
|
||||
CMakeLists.txt:[0-9]+ \(include\)$
|
||||
|
@@ -19,7 +19,7 @@ cmake_minimum_required(VERSION 3.3)
|
||||
# console pool.
|
||||
macro(CheckNinjaStep _target _step _require)
|
||||
if("${_build}" MATCHES
|
||||
" DESC = Performing ${_step} step (\\([a-zA-Z0-9 ]*\\) )?for '${_target}'
|
||||
" DESC = Performing ${_step} step for '${_target}'
|
||||
pool = console"
|
||||
)
|
||||
if(NOT ${_require})
|
||||
|
@@ -1,6 +0,0 @@
|
||||
.* *download 1
|
||||
.* *download 2
|
||||
.* *update 1
|
||||
.* *update 2
|
||||
.* *patch 1
|
||||
.* *patch 2
|
@@ -1,18 +0,0 @@
|
||||
include(FetchContent)
|
||||
|
||||
# Verify COMMAND keyword is recognised after various *_COMMAND options
|
||||
FetchContent_Declare(multiCommand
|
||||
DOWNLOAD_COMMAND "${CMAKE_COMMAND}" -E echo "download 1"
|
||||
COMMAND "${CMAKE_COMMAND}" -E echo "download 2"
|
||||
UPDATE_COMMAND "${CMAKE_COMMAND}" -E echo "update 1"
|
||||
COMMAND "${CMAKE_COMMAND}" -E echo "update 2"
|
||||
PATCH_COMMAND "${CMAKE_COMMAND}" -E echo "patch 1"
|
||||
COMMAND "${CMAKE_COMMAND}" -E echo "patch 2"
|
||||
)
|
||||
|
||||
# Force all steps to be re-run by removing timestamps, scripts, etc. from any
|
||||
# previous run
|
||||
file(REMOVE_RECURSE "${FETCHCONTENT_BASE_DIR}/multiCommand-subbuild")
|
||||
|
||||
set(FETCHCONTENT_QUIET FALSE)
|
||||
FetchContent_MakeAvailable(multiCommand)
|
@@ -2,12 +2,12 @@ include(RunCMake)
|
||||
|
||||
unset(RunCMake_TEST_NO_CLEAN)
|
||||
|
||||
run_cmake(MultiCommand)
|
||||
run_cmake(MissingDetails)
|
||||
run_cmake(DirectIgnoresDetails)
|
||||
run_cmake(FirstDetailsWin)
|
||||
run_cmake(DownloadTwice)
|
||||
run_cmake(DownloadFile)
|
||||
run_cmake(SameGenerator)
|
||||
run_cmake(VarDefinitions)
|
||||
run_cmake(GetProperties)
|
||||
run_cmake(UsesTerminalOverride)
|
||||
@@ -27,36 +27,6 @@ run_cmake_with_options(ManualSourceDirectoryRelative
|
||||
-D "FETCHCONTENT_SOURCE_DIR_WITHPROJECT:STRING=WithProject"
|
||||
)
|
||||
|
||||
function(run_FetchContent_TimeStamps)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/TimeStamps)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
|
||||
# First run should execute the commands
|
||||
run_cmake(TimeStamps)
|
||||
|
||||
# Ensure that the file checks we use in the TimeStampsRerun-check.cmake script
|
||||
# will not be defeated by file systems with only one second resolution.
|
||||
# The IS_NEWER_THAN check returns TRUE if the timestamps of the two files are
|
||||
# the same, which has been observed where filesystems only have one second
|
||||
# resolution.
|
||||
set(cmpTimeStamp ${RunCMake_TEST_BINARY_DIR}/cmpTimeStamp.txt)
|
||||
set(checkTimeStamp ${RunCMake_TEST_BINARY_DIR}/cmpTimeStampCheck.txt)
|
||||
file(TOUCH ${cmpTimeStamp})
|
||||
file(TOUCH ${checkTimeStamp})
|
||||
if("${cmpTimeStamp}" IS_NEWER_THAN "${checkTimeStamp}")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E sleep 1.125
|
||||
COMMAND_ERROR_IS_FATAL LAST
|
||||
)
|
||||
endif()
|
||||
|
||||
# Run again with no changes, no commands should re-execute
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake(TimeStampsRerun)
|
||||
endfunction()
|
||||
run_FetchContent_TimeStamps()
|
||||
|
||||
function(run_FetchContent_DirOverrides)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/DirOverrides-build)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
|
17
Tests/RunCMake/FetchContent/SameGenerator.cmake
Normal file
17
Tests/RunCMake/FetchContent/SameGenerator.cmake
Normal file
@@ -0,0 +1,17 @@
|
||||
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()
|
@@ -1,2 +0,0 @@
|
||||
.* *download executed
|
||||
.* *patch executed
|
@@ -1,14 +0,0 @@
|
||||
include(FetchContent)
|
||||
|
||||
# Do nothing for an update because it would result in always re-running the
|
||||
# patch step. We want to test that a patch step that only depends on the
|
||||
# download step is not re-run unnecessarily.
|
||||
FetchContent_Declare(customCommands
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DOWNLOAD_COMMAND "${CMAKE_COMMAND}" -E echo "download executed"
|
||||
UPDATE_COMMAND ""
|
||||
PATCH_COMMAND "${CMAKE_COMMAND}" -E echo "patch executed"
|
||||
)
|
||||
|
||||
set(FETCHCONTENT_QUIET FALSE)
|
||||
FetchContent_MakeAvailable(customCommands)
|
@@ -1,38 +0,0 @@
|
||||
set(cmpFile ${RunCMake_TEST_BINARY_DIR}/cmpTimeStamp.txt)
|
||||
set(scriptDir ${RunCMake_TEST_BINARY_DIR}/tmp)
|
||||
set(stampDir ${RunCMake_TEST_BINARY_DIR}/src/customcommands-stamp)
|
||||
|
||||
set(errorMessages)
|
||||
if(NOT EXISTS "${cmpFile}")
|
||||
list(APPEND errorMessages " ${cmpFile} is missing")
|
||||
else()
|
||||
foreach(script IN ITEMS mkdirs download patch)
|
||||
set(scriptFile "${scriptDir}/customcommands-${script}.cmake")
|
||||
if(NOT EXISTS "${scriptFile}")
|
||||
list(APPEND errorMessages " ${scriptFile} is missing")
|
||||
elseif(NOT "${cmpFile}" IS_NEWER_THAN "${scriptFile}")
|
||||
list(APPEND errorMessages " ${scriptFile} was unexectedly updated")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# special case, not a script, has different extension
|
||||
set(repoInfoFile "${scriptDir}/customcommands-download-repoinfo.txt")
|
||||
if(NOT EXISTS "${repoInfoFile}")
|
||||
list(APPEND errorMessages " ${repoInfoFile} is missing")
|
||||
elseif(NOT "${cmpFile}" IS_NEWER_THAN "${repoInfoFile}")
|
||||
list(APPEND errorMessages " ${repoInfoFile} was unexectedly updated")
|
||||
endif()
|
||||
|
||||
foreach(step IN ITEMS download patch)
|
||||
set(stampFile "${stampDir}/customcommands-${step}")
|
||||
if(NOT EXISTS "${stampFile}")
|
||||
list(APPEND errorMessages " ${stampFile} is missing")
|
||||
elseif(NOT "${cmpFile}" IS_NEWER_THAN "${stampFile}")
|
||||
list(APPEND errorMessages " ${stampFile} was unexectedly updated")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(errorMessages)
|
||||
list(JOIN errorMessages "\n" RunCMake_TEST_FAILED)
|
||||
endif()
|
@@ -1 +0,0 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/TimeStamps.cmake)
|
Reference in New Issue
Block a user