Browse Source

Merge topic 'fetchcontent-source-dir'

b972e25276 FetchContent: Fix SOURCE_DIR, BUILD_DIR when disconnected or overridden

Acked-by: Kitware Robot <[email protected]>
Merge-request: !5156
Craig Scott 5 years ago
parent
commit
9e61327d03

+ 31 - 10
Modules/FetchContent.cmake

@@ -1038,6 +1038,11 @@ function(FetchContent_Populate contentName)
     message(FATAL_ERROR "Content ${contentName} already populated in ${${contentNameLower}_SOURCE_DIR}")
   endif()
 
+  __FetchContent_getSavedDetails(${contentName} contentDetails)
+  if("${contentDetails}" STREQUAL "")
+    message(FATAL_ERROR "No details have been set for content: ${contentName}")
+  endif()
+
   string(TOUPPER ${contentName} contentNameUpper)
   set(FETCHCONTENT_SOURCE_DIR_${contentNameUpper}
       "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}"
@@ -1045,14 +1050,35 @@ function(FetchContent_Populate contentName)
 
   if(FETCHCONTENT_SOURCE_DIR_${contentNameUpper})
     # The source directory has been explicitly provided in the cache,
-    # so no population is required
+    # so no population is required. The build directory may still be specified
+    # by the declared details though.
     set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
-    set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
+
+    cmake_parse_arguments(savedDetails "" "BINARY_DIR" "" ${contentDetails})
+
+    if(savedDetails_BINARY_DIR)
+      set(${contentNameLower}_BINARY_DIR ${savedDetails_BINARY_DIR})
+    else()
+      set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
+    endif()
 
   elseif(FETCHCONTENT_FULLY_DISCONNECTED)
-    # Bypass population and assume source is already there from a previous run
-    set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src")
-    set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
+    # Bypass population and assume source is already there from a previous run.
+    # Declared details may override the default source or build directories.
+
+    cmake_parse_arguments(savedDetails "" "SOURCE_DIR;BINARY_DIR" "" ${contentDetails})
+
+    if(savedDetails_SOURCE_DIR)
+      set(${contentNameLower}_SOURCE_DIR ${savedDetails_SOURCE_DIR})
+    else()
+      set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src")
+    endif()
+
+    if(savedDetails_BINARY_DIR)
+      set(${contentNameLower}_BINARY_DIR ${savedDetails_BINARY_DIR})
+    else()
+      set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
+    endif()
 
   else()
     # Support both a global "disconnect all updates" and a per-content
@@ -1072,11 +1098,6 @@ function(FetchContent_Populate contentName)
       unset(quietFlag)
     endif()
 
-    __FetchContent_getSavedDetails(${contentName} contentDetails)
-    if("${contentDetails}" STREQUAL "")
-      message(FATAL_ERROR "No details have been set for content: ${contentName}")
-    endif()
-
     set(__detailsQuoted)
     foreach(__item IN LISTS contentDetails)
       string(APPEND __detailsQuoted " [==[${__item}]==]")

+ 23 - 2
Tests/RunCMake/FetchContent/DirOverrides.cmake

@@ -4,18 +4,23 @@ include(FetchContent)
 FetchContent_Declare(
   t1
   SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/savedSrc
-  DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E make_directory <SOURCE_DIR>
+  BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/savedBin
+  DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E make_directory <SOURCE_DIR> <BINARY_DIR>
 )
 FetchContent_Populate(t1)
 if(NOT IS_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/savedSrc)
   message(FATAL_ERROR "Saved details SOURCE_DIR override failed")
 endif()
+if(NOT IS_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/savedBin)
+  message(FATAL_ERROR "Saved details BINARY_DIR override failed")
+endif()
 
 # Test direct population
 FetchContent_Populate(
   t2
   SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/directSrc
-  DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E make_directory <SOURCE_DIR>
+  BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/directBin
+  DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E make_directory <SOURCE_DIR> <BINARY_DIR>
 )
 if(NOT IS_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/directSrc)
   message(FATAL_ERROR "Direct details SOURCE_DIR override failed")
@@ -44,3 +49,19 @@ FetchContent_Populate(
 if(IS_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/savedNobuildDir-build)
   message(FATAL_ERROR "Direct details BINARY_DIR override failed")
 endif()
+
+# Test overriding the source directory by reusing the one from t1
+set(FETCHCONTENT_SOURCE_DIR_T5 ${CMAKE_CURRENT_BINARY_DIR}/savedSrc)
+FetchContent_Declare(
+  t5
+  SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/doesNotExist
+  BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/wontBeCreated
+  DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E false
+)
+FetchContent_Populate(t5)
+if(NOT "${t5_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/savedSrc")
+  message(FATAL_ERROR "Wrong SOURCE_DIR returned: ${t5_SOURCE_DIR}")
+endif()
+if(NOT "${t5_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/wontBeCreated")
+  message(FATAL_ERROR "Wrong BINARY_DIR returned: ${t5_BINARY_DIR}")
+endif()

+ 18 - 0
Tests/RunCMake/FetchContent/DirOverridesDisconnected.cmake

@@ -0,0 +1,18 @@
+include(FetchContent)
+
+# Test using saved details. We are re-using a SOURCE_DIR from a previous test
+# so the download command should not be executed.
+FetchContent_Declare(
+  t1
+  SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/savedSrc
+  BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/savedBin
+  DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E false
+)
+FetchContent_Populate(t1)
+
+if(NOT "${t1_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/savedSrc")
+  message(FATAL_ERROR "Wrong SOURCE_DIR returned: ${t1_SOURCE_DIR}")
+endif()
+if(NOT "${t1_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/savedBin")
+  message(FATAL_ERROR "Wrong BINARY_DIR returned: ${t1_BINARY_DIR}")
+endif()

+ 14 - 1
Tests/RunCMake/FetchContent/RunCMakeTest.cmake

@@ -10,12 +10,25 @@ run_cmake(DownloadFile)
 run_cmake(SameGenerator)
 run_cmake(VarDefinitions)
 run_cmake(GetProperties)
-run_cmake(DirOverrides)
 run_cmake(UsesTerminalOverride)
 run_cmake(MakeAvailable)
 run_cmake(MakeAvailableTwice)
 run_cmake(MakeAvailableUndeclared)
 
+function(run_FetchContent_DirOverrides)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/DirOverrides-build)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake(DirOverrides)
+
+  set(RunCMake_TEST_NO_CLEAN 1)
+  run_cmake_with_options(DirOverridesDisconnected
+    -D FETCHCONTENT_FULLY_DISCONNECTED=YES
+  )
+endfunction()
+run_FetchContent_DirOverrides()
+
 set(RunCMake_TEST_OUTPUT_MERGE 1)
 run_cmake(PreserveEmptyArgs)
 set(RunCMake_TEST_OUTPUT_MERGE 0)