FetchContent: Fix SOURCE_DIR, BUILD_DIR when disconnected or overridden

Fixes: #21123
This commit is contained in:
Craig Scott
2020-08-23 18:38:47 +10:00
parent 269d1a8624
commit b972e25276
4 changed files with 86 additions and 13 deletions

View File

@@ -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}]==]")

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)