瀏覽代碼

Merge topic 'ExternalProject-stamp-genex' into release-3.24

c111d440ce ExternalProject: Express per-config step stamp file paths using CONFIG genex

Acked-by: Kitware Robot <[email protected]>
Merge-request: !7341
Brad King 3 年之前
父節點
當前提交
ec6d574d4a

+ 22 - 15
Modules/ExternalProject.cmake

@@ -2063,19 +2063,19 @@ endif()
   set(${cmd_var} "${command}" PARENT_SCOPE)
   set(${cmd_var} "${command}" PARENT_SCOPE)
 endfunction()
 endfunction()
 
 
-# This module used to use "/${CMAKE_CFG_INTDIR}" directly and produced
-# makefiles with "/./" in paths for custom command dependencies. Which
-# resulted in problems with parallel make -j invocations.
-#
-# This function was added so that the suffix (search below for ${cfgdir}) is
-# only set to "/${CMAKE_CFG_INTDIR}" when ${CMAKE_CFG_INTDIR} is not going to
-# be "." (multi-configuration build systems like Visual Studio and Xcode...)
-#
-function(_ep_get_configuration_subdir_suffix suffix_var)
+# On multi-config generators, provide a placeholder for a per-config subdir.
+# On single-config generators, this is empty.
+function(_ep_get_configuration_subdir_genex suffix_var)
   set(suffix "")
   set(suffix "")
   get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
   get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
   if(_isMultiConfig)
   if(_isMultiConfig)
-    set(suffix "/${CMAKE_CFG_INTDIR}")
+    if(CMAKE_GENERATOR STREQUAL "Xcode")
+      # The Xcode generator does not support per-config sources,
+      # so use the underlying build system's placeholder instead.
+      set(suffix "/${CMAKE_CFG_INTDIR}")
+    else()
+      set(suffix "/$<CONFIG>")
+    endif()
   endif()
   endif()
   set(${suffix_var} "${suffix}" PARENT_SCOPE)
   set(${suffix_var} "${suffix}" PARENT_SCOPE)
 endfunction()
 endfunction()
@@ -2088,7 +2088,7 @@ function(_ep_get_step_stampfile
 )
 )
   ExternalProject_Get_Property(${name} stamp_dir)
   ExternalProject_Get_Property(${name} stamp_dir)
 
 
-  _ep_get_configuration_subdir_suffix(cfgdir)
+  _ep_get_configuration_subdir_genex(cfgdir)
   set(stampfile "${stamp_dir}${cfgdir}/${name}-${step}")
   set(stampfile "${stamp_dir}${cfgdir}/${name}-${step}")
 
 
   set(${stampfile_var} "${stampfile}" PARENT_SCOPE)
   set(${stampfile_var} "${stampfile}" PARENT_SCOPE)
@@ -2100,7 +2100,7 @@ function(_ep_get_complete_stampfile
   stampfile_var
   stampfile_var
 )
 )
   set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
   set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
-  _ep_get_configuration_subdir_suffix(cfgdir)
+  _ep_get_configuration_subdir_genex(cfgdir)
   set(stampfile "${cmf_dir}${cfgdir}/${name}-complete")
   set(stampfile "${cmf_dir}${cfgdir}/${name}-complete")
 
 
   set(${stampfile_var} ${stampfile} PARENT_SCOPE)
   set(${stampfile_var} ${stampfile} PARENT_SCOPE)
@@ -2423,18 +2423,25 @@ function(ExternalProject_Add_Step name step)
     PROPERTY _EP_${step}_ALWAYS
     PROPERTY _EP_${step}_ALWAYS
   )
   )
   if(always)
   if(always)
-    set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1)
     set(touch)
     set(touch)
+    # Mark stamp files for all configs as SYMBOLIC since we do not create them.
     # Remove any existing stamp in case the option changed in an existing tree.
     # Remove any existing stamp in case the option changed in an existing tree.
     get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
     get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
     if(_isMultiConfig)
     if(_isMultiConfig)
+      _ep_get_configuration_subdir_genex(cfgdir)
       foreach(cfg ${CMAKE_CONFIGURATION_TYPES})
       foreach(cfg ${CMAKE_CONFIGURATION_TYPES})
-        string(REPLACE "/${CMAKE_CFG_INTDIR}" "/${cfg}"
+        string(REPLACE "${cfgdir}" "/${cfg}"
           stamp_file_config "${stamp_file}"
           stamp_file_config "${stamp_file}"
         )
         )
+        set_property(SOURCE ${stamp_file_config} PROPERTY SYMBOLIC 1)
         file(REMOVE ${stamp_file_config})
         file(REMOVE ${stamp_file_config})
       endforeach()
       endforeach()
+      if(CMAKE_GENERATOR STREQUAL "Xcode")
+        # See Xcode case in _ep_get_configuration_subdir_genex.
+        set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1)
+      endif()
     else()
     else()
+      set_property(SOURCE ${stamp_file} PROPERTY SYMBOLIC 1)
       file(REMOVE ${stamp_file})
       file(REMOVE ${stamp_file})
     endif()
     endif()
   else()
   else()
@@ -3940,7 +3947,7 @@ function(ExternalProject_Add name)
     PARENT_SCOPE # undocumented, do not use outside of CMake
     PARENT_SCOPE # undocumented, do not use outside of CMake
   )
   )
 
 
-  _ep_get_configuration_subdir_suffix(cfgdir)
+  _ep_get_configuration_subdir_genex(cfgdir)
 
 
   # Add a custom target for the external project.
   # Add a custom target for the external project.
   set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)
   set(cmf_dir ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles)

+ 9 - 0
Tests/RunCMake/NinjaMultiConfig/ExternalProject.cmake

@@ -0,0 +1,9 @@
+include(ExternalProject)
+ExternalProject_Add(proj1
+  DOWNLOAD_COMMAND ""
+  SOURCE_DIR ""
+  CONFIGURE_COMMAND ${CMAKE_COMMAND} -E echo "Configure proj1"
+  BUILD_COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/out-$<CONFIG>.txt
+  BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/out-$<CONFIG>.txt
+  INSTALL_COMMAND ""
+)

+ 7 - 0
Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake

@@ -432,6 +432,13 @@ run_cmake_configure(ExcludeFromAll)
 include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
 include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
 run_cmake_build(ExcludeFromAll all "" all:all)
 run_cmake_build(ExcludeFromAll all "" all:all)
 
 
+set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/ExternalProject-build)
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release")
+run_cmake_configure(ExternalProject)
+unset(RunCMake_TEST_OPTIONS)
+run_cmake_build(ExternalProject release-in-debug-graph "Debug" all:Release)
+run_cmake_build(ExternalProject debug-in-release-graph "Release" all:Debug)
+
 # FIXME Get this working
 # FIXME Get this working
 #set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutoMocExecutable-build)
 #set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AutoMocExecutable-build)
 #run_cmake_configure(AutoMocExecutable)
 #run_cmake_configure(AutoMocExecutable)