Просмотр исходного кода

ExternalProject: Preserve empty string arguments

Craig Scott 5 лет назад
Родитель
Сommit
cbf2daeed0

+ 122 - 70
Modules/ExternalProject.cmake

@@ -1908,7 +1908,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()
 
@@ -2224,17 +2228,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"?
@@ -2689,15 +2699,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)
@@ -2834,16 +2850,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)
@@ -2889,12 +2911,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()
 
 
@@ -3054,14 +3082,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()
 
 
@@ -3099,15 +3133,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()
 
 
@@ -3136,13 +3176,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()
 
 
@@ -3197,15 +3243,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()
 

+ 3 - 3
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\)

+ 21 - 0
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'

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

+ 4 - 0
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")

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