Browse Source

FetchContent: Preserve empty string arguments

Fixes: #20579
Craig Scott 5 years ago
parent
commit
8dca6bd04b

+ 41 - 21
Modules/FetchContent.cmake

@@ -656,7 +656,12 @@ function(__FetchContent_declareDetails contentName)
       BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
       BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
       FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
       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()
   endif()
 
 
 endfunction()
 endfunction()
@@ -689,7 +694,8 @@ function(FetchContent_Declare contentName)
   set(oneValueArgs SVN_REPOSITORY)
   set(oneValueArgs SVN_REPOSITORY)
   set(multiValueArgs "")
   set(multiValueArgs "")
 
 
-  cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+  cmake_parse_arguments(PARSE_ARGV 1 ARG
+    "${options}" "${oneValueArgs}" "${multiValueArgs}")
 
 
   unset(srcDirSuffix)
   unset(srcDirSuffix)
   unset(svnRepoArgs)
   unset(svnRepoArgs)
@@ -707,13 +713,20 @@ function(FetchContent_Declare contentName)
   endif()
   endif()
 
 
   string(TOLOWER ${contentName} contentNameLower)
   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()
 endfunction()
@@ -844,7 +857,8 @@ function(__FetchContent_directPopulate contentName)
   )
   )
   set(multiValueArgs "")
   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)
   if(NOT ARG_SUBBUILD_DIR)
     message(FATAL_ERROR "Internal error: SUBBUILD_DIR not set")
     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}")
       message(FATAL_ERROR "No details have been set for content: ${contentName}")
     endif()
     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()
   endif()
 
 

+ 4 - 0
Tests/RunCMake/FetchContent/PreserveEmptyArgs-stdout.txt

@@ -0,0 +1,4 @@
+.*-- Number of arguments: 6
+.*-- Argument 3: 'before'
+.*-- Argument 4: ''
+.*-- Argument 5: 'after'

+ 13 - 0
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)

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

@@ -16,6 +16,10 @@ run_cmake(MakeAvailable)
 run_cmake(MakeAvailableTwice)
 run_cmake(MakeAvailableTwice)
 run_cmake(MakeAvailableUndeclared)
 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
 # We need to pass through CMAKE_GENERATOR and CMAKE_MAKE_PROGRAM
 # to ensure the test can run on machines where the build tool
 # to ensure the test can run on machines where the build tool
 # isn't on the PATH. Some build slaves explicitly test with such
 # isn't on the PATH. Some build slaves explicitly test with such

+ 5 - 0
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()