diff options
-rw-r--r-- | Modules/ExternalProject.cmake | 192 | ||||
-rw-r--r-- | Modules/FetchContent.cmake | 62 | ||||
-rw-r--r-- | Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt | 6 | ||||
-rw-r--r-- | Tests/RunCMake/ExternalProject/PreserveEmptyArgs-build-stdout.txt | 21 | ||||
-rw-r--r-- | Tests/RunCMake/ExternalProject/PreserveEmptyArgs.cmake | 13 | ||||
-rw-r--r-- | Tests/RunCMake/ExternalProject/RunCMakeTest.cmake | 4 | ||||
-rw-r--r-- | Tests/RunCMake/ExternalProject/countArgs.cmake | 5 | ||||
-rw-r--r-- | Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/FetchContent/PreserveEmptyArgs.cmake | 13 | ||||
-rw-r--r-- | Tests/RunCMake/FetchContent/RunCMakeTest.cmake | 4 | ||||
-rw-r--r-- | Tests/RunCMake/FetchContent/countArgs.cmake | 5 |
11 files changed, 235 insertions, 94 deletions
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 9b1963f..e366b80 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -1787,7 +1787,11 @@ function(_ep_get_build_command name step cmd_var) get_target_property(args ${name} _EP_${step}_ARGS) endif() - list(APPEND cmd ${args}) + if(NOT "${args}" STREQUAL "") + # args could have empty items, so we must quote it to prevent them + # from being silently removed + list(APPEND cmd "${args}") + endif() set(${cmd_var} "${cmd}" PARENT_SCOPE) endfunction() @@ -2103,17 +2107,23 @@ function(ExternalProject_Add_Step name step) set(command ${CMAKE_COMMAND} -E echo_append) endif() - add_custom_command( - OUTPUT ${stamp_file} - BYPRODUCTS ${byproducts} - COMMENT ${comment} - COMMAND ${command} - COMMAND ${touch} - DEPENDS ${depends} - WORKING_DIRECTORY ${work_dir} - VERBATIM - ${uses_terminal} - ) + set(__cmdQuoted) + foreach(__item IN LISTS command) + string(APPEND __cmdQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + add_custom_command( + OUTPUT \${stamp_file} + BYPRODUCTS \${byproducts} + COMMENT \${comment} + COMMAND ${__cmdQuoted} + COMMAND \${touch} + DEPENDS \${depends} + WORKING_DIRECTORY \${work_dir} + VERBATIM + ${uses_terminal} + )" + ) set_property(TARGET ${name} APPEND PROPERTY _EP_STEPS ${step}) # Add custom "step target"? @@ -2568,15 +2578,21 @@ function(_ep_add_download_command name) set(uses_terminal "") endif() - ExternalProject_Add_Step(${name} download - COMMENT ${comment} - COMMAND ${cmd} - WORKING_DIRECTORY ${work_dir} - DEPENDS ${depends} - DEPENDEES mkdir - ${log} - ${uses_terminal} - ) + set(__cmdQuoted) + foreach(__item IN LISTS cmd) + string(APPEND __cmdQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + ExternalProject_Add_Step(\${name} download + COMMENT \${comment} + COMMAND ${__cmdQuoted} + WORKING_DIRECTORY \${work_dir} + DEPENDS \${depends} + DEPENDEES mkdir + ${log} + ${uses_terminal} + )" + ) endfunction() function(_ep_get_update_disconnected var name) @@ -2725,16 +2741,22 @@ Update to Mercurial >= 2.1.1. set(uses_terminal "") endif() - ExternalProject_Add_Step(${name} update - COMMENT ${comment} - COMMAND ${cmd} - ALWAYS ${always} - EXCLUDE_FROM_MAIN ${update_disconnected} - WORKING_DIRECTORY ${work_dir} - DEPENDEES download - ${log} - ${uses_terminal} - ) + set(__cmdQuoted) + foreach(__item IN LISTS cmd) + string(APPEND __cmdQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + ExternalProject_Add_Step(${name} update + COMMENT \${comment} + COMMAND ${__cmdQuoted} + ALWAYS \${always} + EXCLUDE_FROM_MAIN \${update_disconnected} + WORKING_DIRECTORY \${work_dir} + DEPENDEES download + ${log} + ${uses_terminal} + )" + ) if(update_disconnected) _ep_get_step_stampfile(${name} skip-update skip-update_stamp_file) @@ -2780,12 +2802,18 @@ function(_ep_add_patch_command name) set(update_dep update) endif() - ExternalProject_Add_Step(${name} patch - COMMAND ${cmd} - WORKING_DIRECTORY ${work_dir} - DEPENDEES download ${update_dep} - ${log} - ) + set(__cmdQuoted) + foreach(__item IN LISTS cmd) + string(APPEND __cmdQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + ExternalProject_Add_Step(${name} patch + COMMAND ${__cmdQuoted} + WORKING_DIRECTORY \${work_dir} + DEPENDEES download \${update_dep} + ${log} + )" + ) endfunction() @@ -2945,14 +2973,20 @@ function(_ep_add_configure_command name) set(update_dep update) endif() - ExternalProject_Add_Step(${name} configure - COMMAND ${cmd} - WORKING_DIRECTORY ${binary_dir} - DEPENDEES ${update_dep} patch - DEPENDS ${file_deps} - ${log} - ${uses_terminal} - ) + set(__cmdQuoted) + foreach(__item IN LISTS cmd) + string(APPEND __cmdQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + ExternalProject_Add_Step(${name} configure + COMMAND ${__cmdQuoted} + WORKING_DIRECTORY \${binary_dir} + DEPENDEES \${update_dep} patch + DEPENDS \${file_deps} + ${log} + ${uses_terminal} + )" + ) endfunction() @@ -2990,15 +3024,21 @@ function(_ep_add_build_command name) get_property(build_byproducts TARGET ${name} PROPERTY _EP_BUILD_BYPRODUCTS) - ExternalProject_Add_Step(${name} build - COMMAND ${cmd} - BYPRODUCTS ${build_byproducts} - WORKING_DIRECTORY ${binary_dir} - DEPENDEES configure - ALWAYS ${always} - ${log} - ${uses_terminal} - ) + set(__cmdQuoted) + foreach(__item IN LISTS cmd) + string(APPEND __cmdQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + ExternalProject_Add_Step(${name} build + COMMAND ${__cmdQuoted} + BYPRODUCTS \${build_byproducts} + WORKING_DIRECTORY \${binary_dir} + DEPENDEES configure + ALWAYS \${always} + ${log} + ${uses_terminal} + )" + ) endfunction() @@ -3027,13 +3067,19 @@ function(_ep_add_install_command name) set(uses_terminal "") endif() - ExternalProject_Add_Step(${name} install - COMMAND ${cmd} - WORKING_DIRECTORY ${binary_dir} - DEPENDEES build - ${log} - ${uses_terminal} - ) + set(__cmdQuoted) + foreach(__item IN LISTS cmd) + string(APPEND __cmdQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + ExternalProject_Add_Step(${name} install + COMMAND ${__cmdQuoted} + WORKING_DIRECTORY \${binary_dir} + DEPENDEES build + ${log} + ${uses_terminal} + )" + ) endfunction() @@ -3088,15 +3134,21 @@ function(_ep_add_test_command name) set(uses_terminal "") endif() - ExternalProject_Add_Step(${name} test - COMMAND ${cmd} - WORKING_DIRECTORY ${binary_dir} - ${dependees_args} - ${dependers_args} - ${exclude_args} - ${log} - ${uses_terminal} - ) + set(__cmdQuoted) + foreach(__item IN LISTS cmd) + string(APPEND __cmdQuoted " [==[${__item}]==]") + endforeach() + cmake_language(EVAL CODE " + ExternalProject_Add_Step(${name} test + COMMAND ${__cmdQuoted} + WORKING_DIRECTORY \${binary_dir} + ${dependees_args} + ${dependers_args} + ${exclude_args} + ${log} + ${uses_terminal} + )" + ) endif() endfunction() diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 45b50d4..69f2513 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/ExternalProject/NO_DEPENDS-stderr.txt b/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt index 4cb051d..928d88a 100644 --- a/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt +++ b/Tests/RunCMake/ExternalProject/NO_DEPENDS-stderr.txt @@ -2,7 +2,7 @@ CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\): Using NO_DEPENDS for "configure" step might break parallel builds Call Stack \(most recent call first\): .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\) - .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\) + .*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\) .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_configure_command\) NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\) CMakeLists.txt:[0-9]+ \(include\) @@ -12,7 +12,7 @@ CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\): Using NO_DEPENDS for "build" step might break parallel builds Call Stack \(most recent call first\): .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\) - .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\) + .*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\) .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_build_command\) NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\) CMakeLists.txt:[0-9]+ \(include\) @@ -22,7 +22,7 @@ CMake Warning \(dev\) at .*/Modules/ExternalProject.cmake:[0-9]+. \(message\): Using NO_DEPENDS for "install" step might break parallel builds Call Stack \(most recent call first\): .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_StepTargets\) - .*/Modules/ExternalProject.cmake:[0-9]+ \(ExternalProject_Add_Step\) + .*/Modules/ExternalProject.cmake:[0-9]+:EVAL:2 \(ExternalProject_Add_Step\) .*/Modules/ExternalProject.cmake:[0-9]+ \(_ep_add_install_command\) NO_DEPENDS.cmake:[0-9]+ \(ExternalProject_Add\) CMakeLists.txt:[0-9]+ \(include\) diff --git a/Tests/RunCMake/ExternalProject/PreserveEmptyArgs-build-stdout.txt b/Tests/RunCMake/ExternalProject/PreserveEmptyArgs-build-stdout.txt new file mode 100644 index 0000000..0e21b8f --- /dev/null +++ b/Tests/RunCMake/ExternalProject/PreserveEmptyArgs-build-stdout.txt @@ -0,0 +1,21 @@ +.*-- Number of arguments for download: 6 +.*-- download argument 4: '' +.*-- download argument 5: 'after' +.*-- Number of arguments for update: 6 +.*-- update argument 4: '' +.*-- update argument 5: 'after' +.*-- Number of arguments for patch: 6 +.*-- patch argument 4: '' +.*-- patch argument 5: 'after' +.*-- Number of arguments for configure: 6 +.*-- configure argument 4: '' +.*-- configure argument 5: 'after' +.*-- Number of arguments for build: 6 +.*-- build argument 4: '' +.*-- build argument 5: 'after' +.*-- Number of arguments for install: 6 +.*-- install argument 4: '' +.*-- install argument 5: 'after' +.*-- Number of arguments for test: 6 +.*-- test argument 4: '' +.*-- test argument 5: 'after' diff --git a/Tests/RunCMake/ExternalProject/PreserveEmptyArgs.cmake b/Tests/RunCMake/ExternalProject/PreserveEmptyArgs.cmake new file mode 100644 index 0000000..ded1000 --- /dev/null +++ b/Tests/RunCMake/ExternalProject/PreserveEmptyArgs.cmake @@ -0,0 +1,13 @@ +include(ExternalProject) + +set(script "${CMAKE_CURRENT_LIST_DIR}/countArgs.cmake") +ExternalProject_Add( + blankChecker + DOWNLOAD_COMMAND ${CMAKE_COMMAND} -P "${script}" download "" after + UPDATE_COMMAND ${CMAKE_COMMAND} -P "${script}" update "" after + PATCH_COMMAND ${CMAKE_COMMAND} -P "${script}" patch "" after + CONFIGURE_COMMAND ${CMAKE_COMMAND} -P "${script}" configure "" after + BUILD_COMMAND ${CMAKE_COMMAND} -P "${script}" build "" after + INSTALL_COMMAND ${CMAKE_COMMAND} -P "${script}" install "" after + TEST_COMMAND ${CMAKE_COMMAND} -P "${script}" test "" after +) diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake index caaf0d2..0d1da26 100644 --- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake +++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake @@ -29,6 +29,10 @@ endfunction() __ep_test_with_build(MultiCommand) +set(RunCMake_TEST_OUTPUT_MERGE 1) +__ep_test_with_build(PreserveEmptyArgs) +set(RunCMake_TEST_OUTPUT_MERGE 0) + # Output is not predictable enough to be able to verify it reliably # when using the various different Visual Studio generators if(NOT RunCMake_GENERATOR MATCHES "Visual Studio") diff --git a/Tests/RunCMake/ExternalProject/countArgs.cmake b/Tests/RunCMake/ExternalProject/countArgs.cmake new file mode 100644 index 0000000..ee6429a --- /dev/null +++ b/Tests/RunCMake/ExternalProject/countArgs.cmake @@ -0,0 +1,5 @@ +message(STATUS "Number of arguments for ${CMAKE_ARGV3}: ${CMAKE_ARGC}") +math(EXPR last "${CMAKE_ARGC} - 1") +foreach(n RANGE 4 ${last}) + message(STATUS "${CMAKE_ARGV3} argument ${n}: '${CMAKE_ARGV${n}}'") +endforeach() diff --git a/Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt b/Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt new file mode 100644 index 0000000..a72d914 --- /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 0000000..4f35448 --- /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 5e2e5e1..f3ed3e2 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 0000000..7542af4 --- /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() |