diff options
author | Craig Scott <craig.scott@crascit.com> | 2021-03-09 21:59:59 (GMT) |
---|---|---|
committer | Craig Scott <craig.scott@crascit.com> | 2021-03-09 22:07:44 (GMT) |
commit | 57d442e182bcb9a4426912ed7ba68b58c4dcc940 (patch) | |
tree | 7f3509df9143f39bc8cb40a1627625aee6632100 /Modules/FetchContent.cmake | |
parent | 791338359f7a78032209a255d16a613360f5430a (diff) | |
download | CMake-57d442e182bcb9a4426912ed7ba68b58c4dcc940.zip CMake-57d442e182bcb9a4426912ed7ba68b58c4dcc940.tar.gz CMake-57d442e182bcb9a4426912ed7ba68b58c4dcc940.tar.bz2 |
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
Diffstat (limited to 'Modules/FetchContent.cmake')
-rw-r--r-- | Modules/FetchContent.cmake | 131 |
1 files changed, 114 insertions, 17 deletions
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 6a4cf38..8adef47 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -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() |