diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 5006069527..4532b78421 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -1574,15 +1574,25 @@ function(__FetchContent_doPopulation contentName) USES_TERMINAL_DOWNLOAD USES_TERMINAL_UPDATE USES_TERMINAL_PATCH + # Internal options, may change at any time + __DIRECT_POPULATION ) set(multiValueArgs "") cmake_parse_arguments(PARSE_ARGV 1 ARG "${options}" "${oneValueArgs}" "${multiValueArgs}") - get_property(direct_population GLOBAL PROPERTY - "_FetchContent_${contentNameLower}_direct_population" - ) + if(DEFINED ARG___DIRECT_POPULATION) + # Direct call to FetchContent_Populate() with full details. The policy + # setting of its caller is included in the function arguments. + set(direct_population ${ARG___DIRECT_POPULATION}) + else() + # FetchContent_Populate() called with only the name of a dependency. + # We need the policy setting of the corresponding FetchContent_Declare(). + get_property(direct_population GLOBAL PROPERTY + "_FetchContent_${contentNameLower}_direct_population" + ) + endif() if(NOT ARG_SUBBUILD_DIR) if(NOT direct_population) @@ -1926,6 +1936,19 @@ function(FetchContent_Populate contentName) message(FATAL_ERROR "Empty contentName not allowed for FetchContent_Populate()") endif() + if(ARGC EQUAL 1) + set(__doDirectArgs) + else() + cmake_policy(GET CMP0168 cmp0168 + PARENT_SCOPE # undocumented, do not use outside of CMake + ) + if(cmp0168 STREQUAL "NEW") + set(__doDirectArgs __DIRECT_POPULATION YES) + else() + set(__doDirectArgs __DIRECT_POPULATION NO) + endif() + endif() + string(TOLOWER ${contentName} contentNameLower) if(ARGN) @@ -1937,6 +1960,7 @@ function(FetchContent_Populate contentName) SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-build" ${ARGN} # Could override any of the above ..._DIR variables + ${__doDirectArgs} ) # Pass source and binary dir variables back to the caller diff --git a/Tests/RunCMake/FetchContent/ScriptMode.cmake b/Tests/RunCMake/FetchContent/ScriptMode.cmake index bf66140bdd..41b624aebe 100644 --- a/Tests/RunCMake/FetchContent/ScriptMode.cmake +++ b/Tests/RunCMake/FetchContent/ScriptMode.cmake @@ -1,3 +1,4 @@ +cmake_minimum_required(VERSION 3.29) cmake_policy(SET CMP0168 ${CMP0168}) include(FetchContent) @@ -13,6 +14,11 @@ FetchContent_Populate( if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/t1-src/done1.txt) message(FATAL_ERROR "Default SOURCE_DIR doesn't contain done1.txt") endif() +if(CMP0168 STREQUAL "NEW" AND EXISTS ${CMAKE_CURRENT_BINARY_DIR}/t1-subbuild) + message(FATAL_ERROR "t1 sub-build used when expected direct population") +elseif(CMP0168 STREQUAL "OLD" AND NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/t1-subbuild) + message(FATAL_ERROR "t1 used direct population when a sub-build was expected") +endif() FetchContent_Populate( t2 @@ -24,6 +30,11 @@ FetchContent_Populate( if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/mysrc/done2.txt) message(FATAL_ERROR "Specified SOURCE_DIR doesn't contain done2.txt") endif() +if(CMP0168 STREQUAL "NEW" AND EXISTS ${CMAKE_CURRENT_BINARY_DIR}/t2-subbuild) + message(FATAL_ERROR "t2 sub-build used when expected direct population") +elseif(CMP0168 STREQUAL "OLD" AND NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/t2-subbuild) + message(FATAL_ERROR "t2 used direct population when a sub-build was expected") +endif() FetchContent_Populate( t3 @@ -35,3 +46,8 @@ FetchContent_Populate( if(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/myrelsrc/done3.txt) message(FATAL_ERROR "Relative SOURCE_DIR doesn't contain done3.txt") endif() +if(CMP0168 STREQUAL "NEW" AND EXISTS ${CMAKE_CURRENT_BINARY_DIR}/t3-subbuild) + message(FATAL_ERROR "t3 sub-build used when expected direct population") +elseif(CMP0168 STREQUAL "OLD" AND NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/t3-subbuild) + message(FATAL_ERROR "t3 used direct population when a sub-build was expected") +endif()