CMake should have a mechanism to load a file before the top lists file is loaded, that could overwrite find_package() with a function that does dependency fetching based on a small config file.
Something like PreLoad.cmake, but system-wide, documented and recommended for this use.
A unified standard interface could be dictated based on what FetchContent and find_package() are capable of at the moment, so the implementation could be swapped out by the user at any time.
In my opinion a command mode like cmake --package-loader <path_to_cmake_script> could be used to register the provided file for the current user as something to run after the undocumented PreLoad.cmake file when present, or halt CMake execution if absent to make the user aware that something went wrong with the package loader.
Why should an interface be defined instead of an implementation provided?
Inspired by how Java (JSR) (and PHP (PSR) to some extent) have interfaces defined with many existing implementations allows people to pick and choose the one that is best fit for their needs, but still allows some uniform behaviour everyone can expect.
Variables that I can think of affecting the find_package() override would be whether to consider the package loader’s config file at all, so switching testing installed and FetchContent imported dependencies are trivial:
CMAKE_USE_PACKAGE_LOADER - variable to globally control the find_package() override
CMAKE_<package_name>_USE_PACKAGE_LOADER - variable to control the find_package() override’s behaviour for <package_name> only
The above could look like so:
# $XDG_CONFIG_HOME/cmake/package-loader.cmake
macro(find_package PACKAGE)
if (DEFINED CMAKE_USE_PACKAGE_LOADER
AND NOT CMAKE_USE_PACKAGE_LOADER
OR DEFINED CMAKE_${PACKAGE}_USE_PACKAGE_LOADER
AND NOT CMAKE_${PACKAGE}_USE_PACKAGE_LOADER)
# Call to the built-in find_package command
_find_package(${ARGV})
else ()
# ...
endif ()
endmacro()
I’m sure there are more variables that can be of great use, but I lack the knowledge to list more.