diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 45b50d4131..69f25138b6 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -656,7 +656,12 @@ function(__FetchContent_declareDetails contentName) BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()" FULL_DOCS "Details used by FetchContent_Populate() for ${contentName}" ) - set_property(GLOBAL PROPERTY ${propertyName} ${ARGN}) + set(__cmdArgs) + foreach(__item IN LISTS ARGN) + string(APPEND __cmdArgs " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE + "set_property(GLOBAL PROPERTY ${propertyName} ${__cmdArgs})") endif() endfunction() @@ -689,7 +694,8 @@ function(FetchContent_Declare contentName) set(oneValueArgs SVN_REPOSITORY) set(multiValueArgs "") - cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + cmake_parse_arguments(PARSE_ARGV 1 ARG + "${options}" "${oneValueArgs}" "${multiValueArgs}") unset(srcDirSuffix) unset(svnRepoArgs) @@ -707,13 +713,20 @@ function(FetchContent_Declare contentName) endif() string(TOLOWER ${contentName} contentNameLower) - __FetchContent_declareDetails( - ${contentNameLower} - SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src${srcDirSuffix}" - BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build" - ${svnRepoArgs} - # List these last so they can override things we set above - ${ARG_UNPARSED_ARGUMENTS} + + set(__argsQuoted) + foreach(__item IN LISTS ARG_UNPARSED_ARGUMENTS) + string(APPEND __argsQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + __FetchContent_declareDetails( + ${contentNameLower} + SOURCE_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src${srcDirSuffix}\" + BINARY_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build\" + \${svnRepoArgs} + # List these last so they can override things we set above + ${__argsQuoted} + )" ) endfunction() @@ -844,7 +857,8 @@ function(__FetchContent_directPopulate contentName) ) set(multiValueArgs "") - cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + cmake_parse_arguments(PARSE_ARGV 1 ARG + "${options}" "${oneValueArgs}" "${multiValueArgs}") if(NOT ARG_SUBBUILD_DIR) message(FATAL_ERROR "Internal error: SUBBUILD_DIR not set") @@ -1056,17 +1070,23 @@ function(FetchContent_Populate contentName) message(FATAL_ERROR "No details have been set for content: ${contentName}") endif() - __FetchContent_directPopulate( - ${contentNameLower} - ${quietFlag} - UPDATE_DISCONNECTED ${disconnectUpdates} - SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-subbuild" - SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src" - BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build" - # Put the saved details last so they can override any of the - # the options we set above (this can include SOURCE_DIR or - # BUILD_DIR) - ${contentDetails} + set(__detailsQuoted) + foreach(__item IN LISTS contentDetails) + string(APPEND __detailsQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + __FetchContent_directPopulate( + ${contentNameLower} + ${quietFlag} + UPDATE_DISCONNECTED ${disconnectUpdates} + SUBBUILD_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-subbuild\" + SOURCE_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src\" + BINARY_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build\" + # Put the saved details last so they can override any of the + # the options we set above (this can include SOURCE_DIR or + # BUILD_DIR) + ${__detailsQuoted} + )" ) endif() diff --git a/Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt b/Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt new file mode 100644 index 0000000000..a72d914c6e --- /dev/null +++ b/Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt @@ -0,0 +1,4 @@ +.*-- Number of arguments: 6 +.*-- Argument 3: 'before' +.*-- Argument 4: '' +.*-- Argument 5: 'after' diff --git a/Tests/RunCMake/FetchContent/PreserveEmptyArgs.cmake b/Tests/RunCMake/FetchContent/PreserveEmptyArgs.cmake new file mode 100644 index 0000000000..4f354482fe --- /dev/null +++ b/Tests/RunCMake/FetchContent/PreserveEmptyArgs.cmake @@ -0,0 +1,13 @@ +include(FetchContent) + +# Need to see the download command output +set(FETCHCONTENT_QUIET OFF) + +FetchContent_Declare( + t1 + DOWNLOAD_COMMAND ${CMAKE_COMMAND} -P + ${CMAKE_CURRENT_LIST_DIR}/countArgs.cmake + before "" after +) + +FetchContent_Populate(t1) diff --git a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake index 5e2e5e12e3..f3ed3e2d6d 100644 --- a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake +++ b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake @@ -16,6 +16,10 @@ run_cmake(MakeAvailable) run_cmake(MakeAvailableTwice) run_cmake(MakeAvailableUndeclared) +set(RunCMake_TEST_OUTPUT_MERGE 1) +run_cmake(PreserveEmptyArgs) +set(RunCMake_TEST_OUTPUT_MERGE 0) + # We need to pass through CMAKE_GENERATOR and CMAKE_MAKE_PROGRAM # to ensure the test can run on machines where the build tool # isn't on the PATH. Some build slaves explicitly test with such diff --git a/Tests/RunCMake/FetchContent/countArgs.cmake b/Tests/RunCMake/FetchContent/countArgs.cmake new file mode 100644 index 0000000000..7542af4a32 --- /dev/null +++ b/Tests/RunCMake/FetchContent/countArgs.cmake @@ -0,0 +1,5 @@ +message(STATUS "Number of arguments: ${CMAKE_ARGC}") +math(EXPR last "${CMAKE_ARGC} - 1") +foreach(n RANGE 3 ${last}) + message(STATUS "Argument ${n}: '${CMAKE_ARGV${n}}'") +endforeach()