RFC: Deprecating direct calls to FetchContent_Populate()

In the early days of FetchContent (CMake 3.11 – 3.13), projects were required to implement the following pattern to populate a dependency:

if(NOT depname_POPULATED)
  # ...maybe set some variables here...
  add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR})

Since CMake 3.14, FetchContent_MakeAvailable() became available and is the preferred way to populate instead. In recent CMake versions, FetchContent_MakeAvailable() has gained quite a bit more functionality, specifically all the integration with find_package() and the dependency providers features. It is therefore highly desirable for projects to use it instead of the old manual population pattern.

To that end, I propose deprecating direct calls to FetchContent_Populate() in project code. We can still allow it in script mode (cmake -P), since FetchContent_MakeAvailable() doesn’t apply to that use case. The deprecation message will highlight to projects that they should be updated to use FetchContent_MakeAvailable() instead, while not actually causing an error for now. I don’t expect to turn the deprecation into an error for quite a while (likely at least 2 years’ worth of CMake releases, or any other point where CMake drops other already deprecated features as a batch).

If there’s no objection, I propose to add this deprecation for the CMake 3.28 release toward the end of this year (I don’t want to add it for the upcoming 3.27 release, that’s a bit too close for me to get done without bumping other tasks).

1 Like

Looking at GitHub - cpm-cmake/CPM.cmake: 📦 CMake's missing package manager. A small CMake script for setup-free, cross-platform, reproducible dependency management. the move to FetchContent_MakeAvailable wouldn’t be possible intill we can mark a project with EXCLUDE_FROM_ALL

Thanks for pointing that out. Adding support for EXCLUDE_FROM_ALL to FetchContent_Declare() has been actively discussed recently and hopefully it will be implemented for CMake 3.27 3.28. You can find that discussion thread here: https://gitlab.kitware.com/cmake/cmake/-/issues/20167#note_1363010

1 Like

Why “just” a warning and not a policy?

I was thinking more about warning messages being DEPRECATION notices, but the policy mechanism is probably the more appropriate way of handling things. That gives us a clear path forward for future removal, since there’s already precedent for that with things like the FindCUDA module and policy CMP0146.

On a side note, I just noticed that we’ve not mentioned various deprecations in older release notes. We’ve added a deprecation notice to the modules themselves, but I expected corresponding announcements in the release notes too. That didn’t happen for FindCUDA, FindPythonInterp or FindPythonLibs (at least). I’m leaving this as a note to myself to make sure I mention any FetchContent_Populate() deprecation in the release notes too, not just in the FetchContent docs.

@robert.maynard Digging this one up a bit, can you add a bit more info about why CPM needs EXCLUDE_FROM_ALL before direct calls to FetchContent_Populate() can be deprecated?

As an aside, a quick scan through some CPM source code just now revealed that it is messing around with internal properties that are not part of the FetchContent public API. While I have no immediate plans to change those things right now in a way that would break CPM, I also have no intention of preserving any kind of backward compatibility of those strictly internal things. CPM is running the gauntlet of relying on internal implementation details which are free to change at any time. Given some of the longer term ideas and plans for FetchContent, it is very likely those things will change in the future. I take zero responsibility for CPM breaking as a result of those likely future changes, so CPM users should be wary. If there’s a legitimate use case involving just the public API of FetchContent that would be broken, I’m open to discussions, but if we’re talking about use of an internal thing that CPM shouldn’t have been doing or relying on in the first place, that won’t be considered sufficient reason to block deprecating direct calls to FetchContent_Populate().

@robert.maynard Digging this one up a bit, can you add a bit more info about why CPM needs EXCLUDE_FROM_ALL before direct calls to FetchContent_Populate() can be deprecated?

I think in general it is needed since the CPM call ( CPMAddPackage or CPMFindPackage ) is a single ‘atomic’ invocation. So we need a way to state during that invocation that EXCLUDE_FROM_ALL is needed.

Currently CPM is setup to use FetchContent_Populate so that it can manually implement EXCLUDE_FROM_ALL itself by calling add_subdirectory. So if CPM loses the ability to control the add_subdirectory invocation it needs FetchContent to offer the same API that add_subdirectory does.