Browse Source

Merge topic 'fetchcontent-performance'

17e5516e60 FetchContent: Invoke steps directly and avoid a separate sub-build
4f3d1abbb4 ExternalProject: Refactor pre-configure steps to support no-target uses
23aab9ecce ExternalProject: Avoid scanning docs for keywords, use include_guard()

Acked-by: Kitware Robot <[email protected]>
Acked-by: Robert Maynard <[email protected]>
Acked-by: Michael Hirsch, Ph.D. <[email protected]>
Acked-by: Lars Melchior <[email protected]>
Merge-request: !5749
Brad King 4 years ago
parent
commit
acb33d0904
36 changed files with 1286 additions and 885 deletions
  1. 13 0
      Help/release/dev/fetchcontent-performance.rst
  2. 0 173
      Modules/ExternalProject-download.cmake.in
  3. 0 37
      Modules/ExternalProject-verify.cmake.in
  4. 572 436
      Modules/ExternalProject.cmake
  5. 1 0
      Modules/ExternalProject/RepositoryInfo.txt.in
  6. 55 0
      Modules/ExternalProject/captured_process_setup.cmake
  7. 1 0
      Modules/ExternalProject/cfgcmd.txt.in
  8. 10 0
      Modules/ExternalProject/copydir.cmake.in
  9. 8 0
      Modules/ExternalProject/customcommand.cmake.in
  10. 8 0
      Modules/ExternalProject/customcommand_preamble.cmake.in
  11. 205 0
      Modules/ExternalProject/download.cmake.in
  12. 73 0
      Modules/ExternalProject/extractfile.cmake.in
  13. 92 0
      Modules/ExternalProject/gitclone.cmake.in
  14. 65 27
      Modules/ExternalProject/gitupdate.cmake.in
  15. 58 0
      Modules/ExternalProject/hgclone.cmake.in
  16. 24 0
      Modules/ExternalProject/hgupdate.cmake.in
  17. 19 0
      Modules/ExternalProject/mkdirs.cmake.in
  18. 58 0
      Modules/ExternalProject/verify.cmake.in
  19. 17 114
      Modules/FetchContent.cmake
  20. 0 27
      Modules/FetchContent/CMakeLists.cmake.in
  21. 0 3
      Modules/RepositoryInfo.txt.in
  22. 0 1
      Tests/RunCMake/ExternalProject/IncludeScope-Add-result.txt
  23. 0 7
      Tests/RunCMake/ExternalProject/IncludeScope-Add-stderr.txt
  24. 0 12
      Tests/RunCMake/ExternalProject/IncludeScope-Add.cmake
  25. 0 1
      Tests/RunCMake/ExternalProject/IncludeScope-Add_Step-result.txt
  26. 0 7
      Tests/RunCMake/ExternalProject/IncludeScope-Add_Step-stderr.txt
  27. 0 13
      Tests/RunCMake/ExternalProject/IncludeScope-Add_Step.cmake
  28. 1 1
      Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-stderr.txt
  29. 2 2
      Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN-stderr.txt
  30. 1 1
      Tests/RunCMake/ExternalProject/NoOptions-stderr.txt
  31. 0 2
      Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
  32. 1 1
      Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt
  33. 1 1
      Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt
  34. 1 1
      Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake
  35. 0 1
      Tests/RunCMake/FetchContent/RunCMakeTest.cmake
  36. 0 17
      Tests/RunCMake/FetchContent/SameGenerator.cmake

+ 13 - 0
Help/release/dev/fetchcontent-performance.rst

@@ -0,0 +1,13 @@
+fetchcontent-performance
+------------------------
+
+* 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.

+ 0 - 173
Modules/ExternalProject-download.cmake.in

@@ -1,173 +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)
-
-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}
-  "
-)

+ 0 - 37
Modules/ExternalProject-verify.cmake.in

@@ -1,37 +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)
-
-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
+ 572 - 436
Modules/ExternalProject.cmake


+ 1 - 0
Modules/ExternalProject/RepositoryInfo.txt.in

@@ -0,0 +1 @@
+@repo_info_content@

+ 55 - 0
Modules/ExternalProject/captured_process_setup.cmake

@@ -0,0 +1,55 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+if(quiet)
+  set(capture_output
+    OUTPUT_VARIABLE out_var
+    ERROR_VARIABLE  out_var
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    ERROR_STRIP_TRAILING_WHITESPACE
+  )
+  set(capture_error_only
+    ERROR_VARIABLE  out_var
+    ERROR_STRIP_TRAILING_WHITESPACE
+  )
+else()
+  unset(capture_output)
+  unset(capture_error_only)
+endif()
+
+set(out_var "")
+set(accumulated_output "")
+
+macro(_ep_message_quiet_capture mode)
+  if("${mode}" STREQUAL "FATAL_ERROR")
+    string(JOIN "" detail "${ARGN}")
+    if(NOT detail STREQUAL "" AND NOT accumulated_output STREQUAL "")
+      string(PREPEND detail "\n")
+    endif()
+    message(FATAL_ERROR "${accumulated_output}${detail}")
+  endif()
+
+  if(quiet)
+    if("${mode}" MATCHES "WARNING")
+      # We can't provide the full CMake backtrace, but we can at least record
+      # the warning message with a sensible prefix
+      string(APPEND accumulated_output "${mode}: ")
+    endif()
+    string(APPEND accumulated_output "${ARGN}\n")
+  else()
+    message(${mode} ${ARGN})
+  endif()
+endmacro()
+
+macro(_ep_accumulate_captured_output)
+  if(NOT "${out_var}" STREQUAL "")
+    string(APPEND accumulated_output "${out_var}\n")
+  endif()
+endmacro()
+
+macro(_ep_command_check_result result)
+  _ep_accumulate_captured_output()
+  if(result)
+    _ep_message_quiet_capture(FATAL_ERROR ${ARGN})
+  endif()
+endmacro()

+ 1 - 0
Modules/ExternalProject/cfgcmd.txt.in

@@ -0,0 +1 @@
+cmd='@cmd@'

+ 10 - 0
Modules/ExternalProject/copydir.cmake.in

@@ -0,0 +1,10 @@
+# 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@")

+ 8 - 0
Modules/ExternalProject/customcommand.cmake.in

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

+ 8 - 0
Modules/ExternalProject/customcommand_preamble.cmake.in

@@ -0,0 +1,8 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+cmake_minimum_required(VERSION 3.5)
+
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)

+ 205 - 0
Modules/ExternalProject/download.cmake.in

@@ -0,0 +1,205 @@
+# 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()

+ 73 - 0
Modules/ExternalProject/extractfile.cmake.in

@@ -0,0 +1,73 @@
+# 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")

+ 92 - 0
Modules/ExternalProject/gitclone.cmake.in

@@ -0,0 +1,92 @@
+# 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(NOT "@gitclone_infofile@" IS_NEWER_THAN "@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
+  ${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@'"
+)

+ 65 - 27
Modules/ExternalProject-gitupdate.cmake.in → Modules/ExternalProject/gitupdate.cmake.in

@@ -3,6 +3,10 @@
 
 cmake_minimum_required(VERSION 3.5)
 
+set(quiet "@quiet@")
+set(script_dir "@CMAKE_CURRENT_FUNCTION_LIST_DIR@/ExternalProject")
+include(${script_dir}/captured_process_setup.cmake)
+
 function(get_hash_for_ref ref out_var err_var)
   execute_process(
     COMMAND "@git_EXECUTABLE@" rev-parse "${ref}"
@@ -49,7 +53,7 @@ elseif(show_ref_output MATCHES "^[a-z0-9]+[ \\t]+refs/tags/")
   # FIXME: We should provide an option to always fetch for this case
   get_hash_for_ref("@git_tag@" tag_sha error_msg)
   if(tag_sha STREQUAL head_sha)
-    message(VERBOSE "Already at requested tag: ${tag_sha}")
+    _ep_message_quiet_capture(VERBOSE "Already at requested tag: ${tag_sha}")
     return()
   endif()
 
@@ -65,7 +69,7 @@ else()
   get_hash_for_ref("@git_tag@" tag_sha error_msg)
   if(tag_sha STREQUAL head_sha)
     # Have the right commit checked out already
-    message(VERBOSE "Already at requested ref: ${tag_sha}")
+    _ep_message_quiet_capture(VERBOSE "Already at requested ref: ${tag_sha}")
     return()
 
   elseif(tag_sha STREQUAL "")
@@ -76,7 +80,7 @@ else()
     set(fetch_required YES)
     set(checkout_name "@git_tag@")
     if(NOT error_msg STREQUAL "")
-      message(VERBOSE "${error_msg}")
+      _ep_message_quiet_capture(VERBOSE "${error_msg}")
     endif()
 
   else()
@@ -86,18 +90,22 @@ else()
     set(fetch_required NO)
     set(checkout_name "@git_tag@")
     if(NOT error_msg STREQUAL "")
-      message(WARNING "${error_msg}")
+      _ep_message_quiet_capture(WARNING "${error_msg}")
     endif()
 
   endif()
 endif()
 
 if(fetch_required)
-  message(VERBOSE "Fetching latest from the remote @git_remote_name@")
+  _ep_message_quiet_capture(VERBOSE "Fetching latest from the remote @git_remote_name@")
   execute_process(
     COMMAND "@git_EXECUTABLE@" fetch --tags --force "@git_remote_name@"
     WORKING_DIRECTORY "@work_dir@"
-    COMMAND_ERROR_IS_FATAL ANY
+    RESULT_VARIABLE error_code
+    ${capture_output}
+  )
+  _ep_command_check_result(
+    error_code "Failed to fetch from the remote @git_remote_name@'"
   )
 endif()
 
@@ -128,12 +136,15 @@ if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$")
 
   else()
     execute_process(
-      COMMAND "@git_EXECUTABLE@" for-each-ref "--format='%(upstream:short)'" "${current_branch}"
+      COMMAND "@git_EXECUTABLE@" for-each-ref
+              "--format='%(upstream:short)'" "${current_branch}"
       WORKING_DIRECTORY "@work_dir@"
+      RESULT_VARIABLE error_code  # There is no error if no upstream is set
       OUTPUT_VARIABLE upstream_branch
       OUTPUT_STRIP_TRAILING_WHITESPACE
-      COMMAND_ERROR_IS_FATAL ANY  # There is no error if no upstream is set
+      ${capture_error_only}
     )
+    _ep_command_check_result(error_code)
     if(NOT upstream_branch STREQUAL checkout_name)
       # Not safe to rebase when asked to checkout a different branch to the one
       # we are tracking. If we did rebase, we could end up with arbitrary
@@ -145,7 +156,9 @@ if(git_update_strategy MATCHES "^REBASE(_CHECKOUT)?$")
 
   endif()
 elseif(NOT git_update_strategy STREQUAL "CHECKOUT")
-  message(FATAL_ERROR "Unsupported git update strategy: ${git_update_strategy}")
+  _ep_message_quiet_capture(FATAL_ERROR
+    "Unsupported git update strategy: ${git_update_strategy}"
+  )
 endif()
 
 
@@ -155,10 +168,9 @@ execute_process(
   WORKING_DIRECTORY "@work_dir@"
   RESULT_VARIABLE error_code
   OUTPUT_VARIABLE repo_status
+  ${capture_error_only}
 )
-if(error_code)
-  message(FATAL_ERROR "Failed to get the status")
-endif()
+_ep_command_check_result(error_code "Failed to get the status")
 string(LENGTH "${repo_status}" need_stash)
 
 # If not in clean state, stash changes in order to be able to perform a
@@ -167,16 +179,20 @@ if(need_stash)
   execute_process(
     COMMAND "@git_EXECUTABLE@" stash save @git_stash_save_options@
     WORKING_DIRECTORY "@work_dir@"
-    COMMAND_ERROR_IS_FATAL ANY
+    RESULT_VARIABLE error_code
+    ${capture_output}
   )
+  _ep_command_check_result(error_code)
 endif()
 
 if(git_update_strategy STREQUAL "CHECKOUT")
   execute_process(
     COMMAND "@git_EXECUTABLE@" checkout "${checkout_name}"
     WORKING_DIRECTORY "@work_dir@"
-    COMMAND_ERROR_IS_FATAL ANY
+    RESULT_VARIABLE error_code
+    ${capture_output}
   )
+  _ep_command_check_result(error_code)
 else()
   execute_process(
     COMMAND "@git_EXECUTABLE@" rebase "${checkout_name}"
@@ -198,12 +214,14 @@ else()
         execute_process(
           COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
           WORKING_DIRECTORY "@work_dir@"
-          )
+        )
       endif()
-      message(FATAL_ERROR "\nFailed to rebase in: '@work_dir@'."
-                          "\nOutput from the attempted rebase follows:"
-                          "\n${rebase_output}"
-                          "\n\nYou will have to resolve the conflicts manually")
+      _ep_message_quiet_capture(FATAL_ERROR
+        "\nFailed to rebase in: '@work_dir@'."
+        "\nOutput from the attempted rebase follows:"
+        "\n${rebase_output}"
+        "\n\nYou will have to resolve the conflicts manually"
+      )
     endif()
 
     # Fall back to checkout. We create an annotated tag so that the user
@@ -215,21 +233,27 @@ else()
     set(tag_name _cmake_ExternalProject_moved_from_here_${tag_timestamp}Z)
     set(error_log_file ${CMAKE_CURRENT_LIST_DIR}/rebase_error_${tag_timestamp}Z.log)
     file(WRITE ${error_log_file} "${rebase_output}")
-    message(WARNING "Rebase failed, output has been saved to ${error_log_file}"
-                    "\nFalling back to checkout, previous commit tagged as ${tag_name}")
+    _ep_message_quiet_capture(WARNING
+      "Rebase failed, output has been saved to ${error_log_file}"
+      "\nFalling back to checkout, previous commit tagged as ${tag_name}"
+    )
     execute_process(
       COMMAND "@git_EXECUTABLE@" tag -a
               -m "ExternalProject attempting to move from here to ${checkout_name}"
               ${tag_name}
       WORKING_DIRECTORY "@work_dir@"
-      COMMAND_ERROR_IS_FATAL ANY
+      RESULT_VARIABLE error_code
+      ${capture_output}
     )
+    _ep_command_check_result(error_code)
 
     execute_process(
       COMMAND "@git_EXECUTABLE@" checkout "${checkout_name}"
       WORKING_DIRECTORY "@work_dir@"
-      COMMAND_ERROR_IS_FATAL ANY
+      RESULT_VARIABLE error_code
+      ${capture_output}
     )
+    _ep_command_check_result(error_code)
   endif()
 endif()
 
@@ -239,30 +263,42 @@ if(need_stash)
     COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
     WORKING_DIRECTORY "@work_dir@"
     RESULT_VARIABLE error_code
-    )
+    ${capture_output}
+  )
+  _ep_accumulate_captured_output()
   if(error_code)
     # Stash pop --index failed: Try again dropping the index
     execute_process(
       COMMAND "@git_EXECUTABLE@" reset --hard --quiet
       WORKING_DIRECTORY "@work_dir@"
+      ${capture_output}
     )
+    _ep_accumulate_captured_output()
     execute_process(
       COMMAND "@git_EXECUTABLE@" stash pop --quiet
       WORKING_DIRECTORY "@work_dir@"
       RESULT_VARIABLE error_code
+      ${capture_output}
     )
+    _ep_accumulate_captured_output()
     if(error_code)
       # Stash pop failed: Restore previous state.
       execute_process(
         COMMAND "@git_EXECUTABLE@" reset --hard --quiet ${head_sha}
         WORKING_DIRECTORY "@work_dir@"
+        ${capture_output}
       )
+      _ep_accumulate_captured_output()
       execute_process(
         COMMAND "@git_EXECUTABLE@" stash pop --index --quiet
         WORKING_DIRECTORY "@work_dir@"
+        ${capture_output}
+      )
+      _ep_accumulate_captured_output()
+      _ep_message_quiet_capture(FATAL_ERROR
+        "Failed to unstash changes in: '@work_dir@'.\n"
+        "You will have to resolve the conflicts manually"
       )
-      message(FATAL_ERROR "\nFailed to unstash changes in: '@work_dir@'."
-                          "\nYou will have to resolve the conflicts manually")
     endif()
   endif()
 endif()
@@ -272,6 +308,8 @@ if(init_submodules)
   execute_process(
     COMMAND "@git_EXECUTABLE@" submodule update @git_submodules_recurse@ --init @git_submodules@
     WORKING_DIRECTORY "@work_dir@"
-    COMMAND_ERROR_IS_FATAL ANY
+    RESULT_VARIABLE error_code
+    ${capture_output}
   )
+  _ep_command_check_result(error_code)
 endif()

+ 58 - 0
Modules/ExternalProject/hgclone.cmake.in

@@ -0,0 +1,58 @@
+# 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(NOT "@hgclone_infofile@" IS_NEWER_THAN "@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
+  ${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@'"
+)

+ 24 - 0
Modules/ExternalProject/hgupdate.cmake.in

@@ -0,0 +1,24 @@
+# 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)

+ 19 - 0
Modules/ExternalProject/mkdirs.cmake.in

@@ -0,0 +1,19 @@
+# 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()

+ 58 - 0
Modules/ExternalProject/verify.cmake.in

@@ -0,0 +1,58 @@
+# 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()

+ 17 - 114
Modules/FetchContent.cmake

@@ -849,8 +849,6 @@ function(__FetchContent_directPopulate contentName)
       SUBBUILD_DIR
       SOURCE_DIR
       BINARY_DIR
-      # We need special processing if DOWNLOAD_NO_EXTRACT is true
-      DOWNLOAD_NO_EXTRACT
       # Prevent the following from being passed through
       CONFIGURE_COMMAND
       BUILD_COMMAND
@@ -894,123 +892,28 @@ function(__FetchContent_directPopulate contentName)
   set(${contentName}_SOURCE_DIR "${ARG_SOURCE_DIR}" PARENT_SCOPE)
   set(${contentName}_BINARY_DIR "${ARG_BINARY_DIR}" PARENT_SCOPE)
 
-  # The unparsed arguments may contain spaces, so build up ARG_EXTRA
-  # in such a way that it correctly substitutes into the generated
-  # CMakeLists.txt file with each argument quoted.
-  unset(ARG_EXTRA)
-  foreach(arg IN LISTS ARG_UNPARSED_ARGUMENTS)
-    set(ARG_EXTRA "${ARG_EXTRA} \"${arg}\"")
-  endforeach()
-
-  if(ARG_DOWNLOAD_NO_EXTRACT)
-    set(ARG_EXTRA "${ARG_EXTRA} DOWNLOAD_NO_EXTRACT YES")
-    set(__FETCHCONTENT_COPY_FILE
-"
-ExternalProject_Get_Property(${contentName}-populate DOWNLOADED_FILE)
-get_filename_component(dlFileName \"\${DOWNLOADED_FILE}\" NAME)
-
-ExternalProject_Add_Step(${contentName}-populate copyfile
-  COMMAND    \"${CMAKE_COMMAND}\" -E copy_if_different
-             \"<DOWNLOADED_FILE>\" \"${ARG_SOURCE_DIR}\"
-  DEPENDEES  patch
-  DEPENDERS  configure
-  BYPRODUCTS \"${ARG_SOURCE_DIR}/\${dlFileName}\"
-  COMMENT    \"Copying file to SOURCE_DIR\"
-)
-")
+  if(ARG_QUIET)
+    set(quiet TRUE)
   else()
-    unset(__FETCHCONTENT_COPY_FILE)
-  endif()
-
-  # Hide output if requested, but save it to a variable in case there's an
-  # error so we can show the output upon failure. When not quiet, don't
-  # capture the output to a variable because the user may want to see the
-  # output as it happens (e.g. progress during long downloads). Combine both
-  # stdout and stderr in the one capture variable so the output stays in order.
-  if (ARG_QUIET)
-    set(outputOptions
-        OUTPUT_VARIABLE capturedOutput
-        ERROR_VARIABLE  capturedOutput
-    )
-  else()
-    set(capturedOutput)
-    set(outputOptions)
+    set(quiet FALSE)
     message(STATUS "Populating ${contentName}")
   endif()
 
-  if(CMAKE_GENERATOR)
-    set(subCMakeOpts "-G${CMAKE_GENERATOR}")
-    if(CMAKE_GENERATOR_PLATFORM)
-      list(APPEND subCMakeOpts "-A${CMAKE_GENERATOR_PLATFORM}")
-    endif()
-    if(CMAKE_GENERATOR_TOOLSET)
-      list(APPEND subCMakeOpts "-T${CMAKE_GENERATOR_TOOLSET}")
-    endif()
-
-    if(CMAKE_MAKE_PROGRAM)
-      list(APPEND subCMakeOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
-    endif()
-
-  else()
-    # Likely we've been invoked via CMake's script mode where no
-    # generator is set (and hence CMAKE_MAKE_PROGRAM could not be
-    # trusted even if provided). We will have to rely on being
-    # able to find the default generator and build tool.
-    unset(subCMakeOpts)
-  endif()
-
-  if(DEFINED CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY)
-    list(APPEND subCMakeOpts
-      "-DCMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY=${CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY}")
-  endif()
-
-  # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings
-  set(__FETCHCONTENT_CACHED_INFO "")
-  list(FIND ARG_UNPARSED_ARGUMENTS GIT_REPOSITORY indexResult)
-  if(indexResult GREATER_EQUAL 0)
-    find_package(Git QUIET)
-    set(__FETCHCONTENT_CACHED_INFO
-"# Pass through things we've already detected in the main project to avoid
-# paying the cost of redetecting them again in ExternalProject_Add()
-set(GIT_EXECUTABLE [==[${GIT_EXECUTABLE}]==])
-set(GIT_VERSION_STRING [==[${GIT_VERSION_STRING}]==])
-set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION
-  [==[${GIT_EXECUTABLE};${GIT_VERSION_STRING}]==]
-)
-")
-  endif()
-
-  # Create and build a separate CMake project to carry out the population.
-  # If we've already previously done these steps, they will not cause
-  # anything to be updated, so extra rebuilds of the project won't occur.
-  # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
-  # has this set to something not findable on the PATH.
-  configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in"
-                 "${ARG_SUBBUILD_DIR}/CMakeLists.txt")
-  execute_process(
-    COMMAND ${CMAKE_COMMAND} ${subCMakeOpts} .
-    RESULT_VARIABLE result
-    ${outputOptions}
-    WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
-  )
-  if(result)
-    if(capturedOutput)
-      message("${capturedOutput}")
-    endif()
-    message(FATAL_ERROR "CMake step for ${contentName} failed: ${result}")
-  endif()
-  execute_process(
-    COMMAND ${CMAKE_COMMAND} --build .
-    RESULT_VARIABLE result
-    ${outputOptions}
-    WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
+  include(ExternalProject)
+  set(argsQuoted)
+  foreach(__item IN LISTS ARG_UNPARSED_ARGUMENTS)
+    string(APPEND argsQuoted " [==[${__item}]==]")
+  endforeach()
+  cmake_language(EVAL CODE "
+    _ep_do_preconfigure_steps_now(${contentName}
+      ${argsQuoted}
+      QUIET                   ${quiet}
+      SOURCE_DIR              [==[${ARG_SOURCE_DIR}]==]
+      BINARY_DIR              [==[${ARG_BINARY_DIR}]==]
+      USES_TERMINAL_DOWNLOAD  YES
+      USES_TERMINAL_UPDATE    YES
+    )"
   )
-  if(result)
-    if(capturedOutput)
-      message("${capturedOutput}")
-    endif()
-    message(FATAL_ERROR "Build step for ${contentName} failed: ${result}")
-  endif()
 
 endfunction()
 

+ 0 - 27
Modules/FetchContent/CMakeLists.cmake.in

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

+ 0 - 3
Modules/RepositoryInfo.txt.in

@@ -1,3 +0,0 @@
-repository='@repository@'
-module='@module@'
-tag='@tag@'

+ 0 - 1
Tests/RunCMake/ExternalProject/IncludeScope-Add-result.txt

@@ -1 +0,0 @@
-1

+ 0 - 7
Tests/RunCMake/ExternalProject/IncludeScope-Add-stderr.txt

@@ -1,7 +0,0 @@
-^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
-  error: ExternalProject module must be explicitly included before using
-  ExternalProject_Add function
-Call Stack \(most recent call first\):
-  .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_parse_arguments\)
-  IncludeScope-Add.cmake:[0-9]+ \(ExternalProject_Add\)
-  CMakeLists.txt:[0-9]+ \(include\)$

+ 0 - 12
Tests/RunCMake/ExternalProject/IncludeScope-Add.cmake

@@ -1,12 +0,0 @@
-function(IncludeScope_IncludeOnly)
-  include(ExternalProject)
-endfunction()
-
-IncludeScope_IncludeOnly()
-
-ExternalProject_Add(MyProj
-    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
-    CONFIGURE_COMMAND ""
-    BUILD_COMMAND     ""
-    INSTALL_COMMAND   ""
-)

+ 0 - 1
Tests/RunCMake/ExternalProject/IncludeScope-Add_Step-result.txt

@@ -1 +0,0 @@
-1

+ 0 - 7
Tests/RunCMake/ExternalProject/IncludeScope-Add_Step-stderr.txt

@@ -1,7 +0,0 @@
-^CMake Error at .*/Modules/ExternalProject.cmake:[0-9]+ \(message\):
-  error: ExternalProject module must be explicitly included before using
-  ExternalProject_Add_Step function
-Call Stack \(most recent call first\):
-  .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_parse_arguments\)
-  IncludeScope-Add_Step.cmake:[0-9]+ \(ExternalProject_Add_Step\)
-  CMakeLists.txt:[0-9]+ \(include\)$

+ 0 - 13
Tests/RunCMake/ExternalProject/IncludeScope-Add_Step.cmake

@@ -1,13 +0,0 @@
-function(IncludeScope_DefineProj)
-  include(ExternalProject)
-  ExternalProject_Add(MyProj
-    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
-    CONFIGURE_COMMAND ""
-    BUILD_COMMAND     ""
-    INSTALL_COMMAND   ""
-  )
-endfunction()
-
-IncludeScope_DefineProj()
-
-ExternalProject_Add_Step(MyProj extraStep COMMENT "Foo")

+ 1 - 1
Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-NEW-stderr.txt

@@ -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_mkdir_command\)
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_preconfigure_command\)
   NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
   NO_DEPENDS-CMP0114-NEW.cmake:[0-9]+ \(include\)
   CMakeLists.txt:[0-9]+ \(include\)$

+ 2 - 2
Tests/RunCMake/ExternalProject/NO_DEPENDS-CMP0114-WARN-stderr.txt

@@ -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_mkdir_command\)
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_preconfigure_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_mkdir_command\)
+]*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_preconfigure_command\)
   NO_DEPENDS-CMP0114-Common.cmake:[0-9]+ \(ExternalProject_Add\)
   NO_DEPENDS-CMP0114-WARN.cmake:[0-9]+ \(include\)
   CMakeLists.txt:[0-9]+ \(include\)

+ 1 - 1
Tests/RunCMake/ExternalProject/NoOptions-stderr.txt

@@ -13,6 +13,6 @@
    \* HG_REPOSITORY
    \* CVS_REPOSITORY and CVS_MODULE
 Call Stack \(most recent call first\):
-  .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
+  .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_prepare_download\)
   NoOptions.cmake:[0-9]+ \(ExternalProject_Add\)
   CMakeLists.txt:[0-9]+ \(include\)$

+ 0 - 2
Tests/RunCMake/ExternalProject/RunCMakeTest.cmake

@@ -8,8 +8,6 @@ unset(ENV{https_proxy})
 
 run_cmake(BadIndependentStep1)
 run_cmake(BadIndependentStep2)
-run_cmake(IncludeScope-Add)
-run_cmake(IncludeScope-Add_Step)
 run_cmake(NoOptions)
 run_cmake(SourceEmpty)
 run_cmake(SourceMissing)

+ 1 - 1
Tests/RunCMake/ExternalProject/SourceEmpty-stderr.txt

@@ -13,6 +13,6 @@
    \* HG_REPOSITORY
    \* CVS_REPOSITORY and CVS_MODULE
 Call Stack \(most recent call first\):
-  .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
+  .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_prepare_download\)
   SourceEmpty.cmake:[0-9]+ \(ExternalProject_Add\)
   CMakeLists.txt:[0-9]+ \(include\)$

+ 1 - 1
Tests/RunCMake/ExternalProject/SourceMissing-stderr.txt

@@ -13,6 +13,6 @@
    \* HG_REPOSITORY
    \* CVS_REPOSITORY and CVS_MODULE
 Call Stack \(most recent call first\):
-  .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_download_command\)
+  .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_prepare_download\)
   SourceMissing.cmake:[0-9]+ \(ExternalProject_Add\)
   CMakeLists.txt:[0-9]+ \(include\)$

+ 1 - 1
Tests/RunCMake/ExternalProject/UsesTerminal-check.cmake

@@ -19,7 +19,7 @@ cmake_minimum_required(VERSION 3.3)
 # console pool.
 macro(CheckNinjaStep _target _step _require)
   if("${_build}" MATCHES
-"  DESC = Performing ${_step} step for '${_target}'
+"  DESC = Performing ${_step} step (\\([a-zA-Z0-9 ]*\\) )?for '${_target}'
   pool = console"
   )
     if(NOT ${_require})

+ 0 - 1
Tests/RunCMake/FetchContent/RunCMakeTest.cmake

@@ -7,7 +7,6 @@ run_cmake(DirectIgnoresDetails)
 run_cmake(FirstDetailsWin)
 run_cmake(DownloadTwice)
 run_cmake(DownloadFile)
-run_cmake(SameGenerator)
 run_cmake(VarDefinitions)
 run_cmake(GetProperties)
 run_cmake(UsesTerminalOverride)

+ 0 - 17
Tests/RunCMake/FetchContent/SameGenerator.cmake

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

Some files were not shown because too many files changed in this diff