Skip to content

FetchContent: New module for populating content at configure time

Craig Scott requested to merge craig.scott/cmake:download_dependency into master

The new FetchContent module provides the ability to populate content at configure time using any of the methods supported by ExternalProject_Add(). A private sub-build is set up to populate the content immediately during configure, so the populated content is available immediately rather than being delayed until build time. This allows the content to be used in commands like add_subdirectory(), include(), file(...) and so on.

A key feature of the module is the ability to define download/update details separately from the command to initiate the population. The definition of content details acts on a "first to define them, wins" approach. This allows hierarchical project dependencies to be set up and for parent projects to override content details in child projects. The canonical pattern for use of this module is similar to the following:

include(FetchContent)
FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        release-1.8.0
)

FetchContent_GetProperties(googletest)
if(NOT googletest_POPULATED)
    FetchContent_Populate(googletest)
    add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
endif()

The above pattern requires no central repository of build recipes, etc., but the parent still has the ability to set CMake variables, etc. before calling add_subdirectory() so as to influence the child project's behaviour. Note also that the content doesn't have to be a project, it can be anything, such as asset packs that simply need to be downloaded to a predictable location so other parts of the build can pull things out of it. For those wanting to use the download facilities provided by this module in CMake's script mode, a syntax is provided to allow such downloads to be performed directly.

The module has been in development for about 2 years and has been used in production environments with complex project hierarchies across Linux, Windows, Solaris, MacOS and iOS. The code contained in this merge request is derived from that, but has been restructured, documented and tests added to conform to CMake's style and conventions. See the included documentation for instructions on how this module can be used. Some of the options (e.g. those to disconnect download/update steps) were added in response to the desire for those features while dog-fooding the module.

Topic-rename: module-fetchcontent

Edited by Craig Scott

Merge request reports