diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index 72aedba912..7d2440e1d2 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -57,6 +57,7 @@ Policies Introduced by CMake 3.30 .. toctree:: :maxdepth: 1 + CMP0169: FetchContent_Populate(depName) single-argument signature is deprecated. CMP0168: FetchContent implements steps directly instead of through a sub-build. CMP0167: The FindBoost module is removed. CMP0166: TARGET_PROPERTY evaluates link properties transitively over private dependencies of static libraries. diff --git a/Help/policy/CMP0169.rst b/Help/policy/CMP0169.rst new file mode 100644 index 0000000000..38b8dcbb4d --- /dev/null +++ b/Help/policy/CMP0169.rst @@ -0,0 +1,49 @@ +CMP0169 +------- + +.. versionadded:: 3.30 + +Calling :command:`FetchContent_Populate` with a single argument (the name of +a declared dependency) is deprecated. + +Prior to the introduction of :command:`FetchContent_MakeAvailable`, projects +populated previously declared content (with :command:`FetchContent_Declare`) +using the following pattern: + +.. code-block:: cmake + + FetchContent_GetProperties(depname) + if(NOT depname_POPULATED) + FetchContent_Populate(depname) + add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR}) + endif() + +The above pattern does not support a number of features that have been added +to :module:`FetchContent` over time. It ignores options like ``SYSTEM`` and +``EXCLUDE_FROM_ALL`` which may be given to :command:`FetchContent_Declare`, +but can't be made known to the above project code. It also does not support +:ref:`dependency providers `. +Projects should call :command:`FetchContent_MakeAvailable` instead of using +the above pattern. + +CMake 3.30 and above prefers to reject calls to +:command:`FetchContent_Populate` with the name of a declared dependency. +This policy provides compatibility for projects that have not been updated +to call :command:`FetchContent_MakeAvailable` instead. + +The ``OLD`` behavior of this policy allows :command:`FetchContent_Populate` +to be called with the name of a declared dependency. +The ``NEW`` behavior halts with a fatal error in such cases. + +.. note:: + Calling :command:`FetchContent_Populate` with the full population details + as command arguments rather than just a dependency name remains fully + supported. Only the form calling :command:`FetchContent_Populate` with a + single argument (the name of a previously declared dependency) is deprecated + with this policy. + +.. |INTRODUCED_IN_CMAKE_VERSION| replace:: 3.30 +.. |WARNS_OR_DOES_NOT_WARN| replace:: warns +.. include:: STANDARD_ADVICE.txt + +.. include:: DEPRECATED.txt diff --git a/Help/release/dev/deprecate-fetchcontent_populate.rst b/Help/release/dev/deprecate-fetchcontent_populate.rst new file mode 100644 index 0000000000..9165415ea8 --- /dev/null +++ b/Help/release/dev/deprecate-fetchcontent_populate.rst @@ -0,0 +1,8 @@ +deprecate-fetchcontent_populate +------------------------------- + +* Calling :command:`FetchContent_Populate` with just the name of a + dependency is now deprecated. Projects should call + :command:`FetchContent_MakeAvailable` instead. See policy :policy:`CMP0169`. + Calling :command:`FetchContent_Populate` with full population details + rather than just a dependency name remains fully supported. diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake index 189cb96612..a4bd7fe79a 100644 --- a/Modules/FetchContent.cmake +++ b/Modules/FetchContent.cmake @@ -68,33 +68,6 @@ first instead of repeating the population again. See the :ref:`Examples ` which demonstrate this scenario. -In some cases, the main project may need to have more precise control over -the population, or it may be required to explicitly define the population -steps in a way that cannot be captured by the declared details alone. -For such situations, the lower level :command:`FetchContent_GetProperties` and -:command:`FetchContent_Populate` commands can be used. These lack the richer -features provided by :command:`FetchContent_MakeAvailable` though, so their -direct use should be considered a last resort. The typical pattern of such -custom steps looks like this: - -.. code-block:: cmake - - # NOTE: Where possible, prefer to use FetchContent_MakeAvailable() - # instead of custom logic like this - - # Check if population has already been performed - FetchContent_GetProperties(depname) - if(NOT depname_POPULATED) - # Fetch the content using previously declared details - FetchContent_Populate(depname) - - # Set custom variables, policies, etc. - # ... - - # Bring the populated content into the build - add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR}) - endif() - The ``FetchContent`` module also supports defining and populating content in a single call, with no check for whether the content has been populated elsewhere already. This should not be done in projects, but may @@ -316,8 +289,8 @@ Commands :command:`FetchContent_GetProperties`, then skip the remaining steps below and move on to the next dependency in the list. - * Call :command:`FetchContent_Populate` to populate the dependency using - the details recorded by an earlier call to :command:`FetchContent_Declare`. + * Populate the dependency using the details recorded by an earlier call + to :command:`FetchContent_Declare`. Halt with a fatal error if no such details have been recorded. :variable:`FETCHCONTENT_SOURCE_DIR_` can be used to override the declared details and use content provided at the specified location @@ -331,10 +304,10 @@ Commands ``Config.cmake`` and ``ConfigVersion.cmake``). The directory that the :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` variable points to is cleared at the start of every CMake run. - If no config file exists when :command:`FetchContent_Populate` returns, - a minimal one will be written which :command:`includes ` any - ``-extra.cmake`` or ``Extra.cmake`` file with the - ``OPTIONAL`` flag (so the files can be missing and won't generate a + If no config file exists after populating the dependency in the previous + step, a minimal one will be written which :command:`includes ` + any ``-extra.cmake`` or ``Extra.cmake`` file with + the ``OPTIONAL`` flag (so the files can be missing and won't generate a warning). Similarly, if no config version file exists, a very simple one will be written which sets ``PACKAGE_VERSION_COMPATIBLE`` and ``PACKAGE_VERSION_EXACT`` to true. This ensures all future calls to @@ -428,68 +401,13 @@ Commands .. command:: FetchContent_Populate - .. note:: - Where possible, prefer to use :command:`FetchContent_MakeAvailable` - instead of implementing population manually with this command. - - .. code-block:: cmake - - FetchContent_Populate() - - In most cases, the only argument given to ``FetchContent_Populate()`` is the - ````. When used this way, the command assumes the content details have - been recorded by an earlier call to :command:`FetchContent_Declare`. The - details are stored in a global property, so they are unaffected by things - like variable or directory scope. Therefore, it doesn't matter where in the - project the details were previously declared, as long as they have been - declared before the call to ``FetchContent_Populate()``. Those saved details - are then used to populate the content using a method based on - :command:`ExternalProject_Add` (see policy :policy:`CMP0168` for important - behavioral aspects of how that is done). The implementation ensures that if - the content has already been populated in a previous CMake run, that content - will be reused rather than repopulating them again. For the common case - where population involves downloading content, the cost of the download is - only paid once. - - An internal global property records when a particular content population - request has been processed. If ``FetchContent_Populate()`` is called more - than once for the same content name within a configure run, the second call - will halt with an error. Projects can and should check whether content - population has already been processed with the - :command:`FetchContent_GetProperties` command before calling - ``FetchContent_Populate()``. - - ``FetchContent_Populate()`` will set three variables in the scope of the - caller: - - ``_POPULATED`` - This will always be set to ``TRUE`` by the call. - - ``_SOURCE_DIR`` - The location where the populated content can be found upon return. - - ``_BINARY_DIR`` - A directory intended for use as a corresponding build directory. - - The main use case for the ``_SOURCE_DIR`` and - ``_BINARY_DIR`` variables is to call - :command:`add_subdirectory` immediately after population: - - .. code-block:: cmake - - FetchContent_Populate(FooBar) - add_subdirectory(${foobar_SOURCE_DIR} ${foobar_BINARY_DIR}) - - The values of the three variables can also be retrieved from anywhere in the - project hierarchy using the :command:`FetchContent_GetProperties` command. - - The ``FetchContent_Populate()`` command also supports a syntax allowing the - content details to be specified directly rather than using any saved - details. This is more low-level and use of this form is generally to be - avoided in favor of using saved content details as outlined above. - Nevertheless, in certain situations it can be useful to invoke the content - population as an isolated operation (typically as part of implementing some - other higher level feature or when using CMake in script mode): + The ``FetchContent_Populate()`` command is a self-contained call which can + be used to perform content population as an isolated operation. + It is rarely the right command to use, projects should almost always use + :command:`FetchContent_Declare` and :command:`FetchContent_MakeAvailable` + instead. The main use case for ``FetchContent_Populate()`` is in + :ref:`CMake script mode