summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCraig Scott <craig.scott@crascit.com>2020-08-23 08:38:47 (GMT)
committerCraig Scott <craig.scott@crascit.com>2020-08-23 08:38:47 (GMT)
commitb972e25276186ea43879dccfab50f43024f44390 (patch)
tree9541ac0c0c4f316e3e1a2aab0491a695ae39212b
parent269d1a86249ea037a2884133daffc8c44a38d926 (diff)
downloadCMake-b972e25276186ea43879dccfab50f43024f44390.zip
CMake-b972e25276186ea43879dccfab50f43024f44390.tar.gz
CMake-b972e25276186ea43879dccfab50f43024f44390.tar.bz2
FetchContent: Fix SOURCE_DIR, BUILD_DIR when disconnected or overridden
Fixes: #21123
-rw-r--r--Modules/FetchContent.cmake41
-rw-r--r--Tests/RunCMake/FetchContent/DirOverrides.cmake25
-rw-r--r--Tests/RunCMake/FetchContent/DirOverridesDisconnected.cmake18
-rw-r--r--Tests/RunCMake/FetchContent/RunCMakeTest.cmake15
4 files changed, 86 insertions, 13 deletions
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index c85e2d8..acf2a94 100644
--- a/Modules/FetchContent.cmake
+++ b/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}]==]")
diff --git a/Tests/RunCMake/FetchContent/DirOverrides.cmake b/Tests/RunCMake/FetchContent/DirOverrides.cmake
index 50eef16..ad61a00 100644
--- a/Tests/RunCMake/FetchContent/DirOverrides.cmake
+++ b/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()
diff --git a/Tests/RunCMake/FetchContent/DirOverridesDisconnected.cmake b/Tests/RunCMake/FetchContent/DirOverridesDisconnected.cmake
new file mode 100644
index 0000000..768a82e
--- /dev/null
+++ b/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()
diff --git a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake b/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
index f3ed3e2..ad9e48e 100644
--- a/Tests/RunCMake/FetchContent/RunCMakeTest.cmake
+++ b/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)