Built in package manager for CMake modules

The Dependency Providers feature added in CMake 3.24 is the intended way forward for package managers to integrate with CMake. Package managers would provide a file that users can specify in their CMAKE_PROJECT_TOP_LEVEL_INCLUDES variable. This intentionally avoids having to hard-code anything in the project related to any particular package manager to use or not use.

It does work well before the first project call for some use cases. I do this all the time in client projects to bring in a repo that defines common CMake build logic, provides toolchain files, etc. before the first project() call. At the moment, it is less suitable if the repo you want to bring in is large because, as identified in the linked issues, a copy is downloaded in each build directory you use. If you blow away the build directory, you will have to download that repo again the next time you run CMake on your project.

Caching of downloaded things has come up before a few times. I’ve resisted this in the past on the basis of not wanting CMake to grow beyond its primary focus. It shouldn’t attempt to become a package manager in its own right. But recently I’ve been reassessing my position on the caching side specifically. I am cautious about how we might provide some sort of caching, seeing the problems that I’ve encountered with this in my own use of package managers and employing certain patterns with client projects. It is clear that having a cache that sits outside the build directory would solve some increasingly common problems users are facing.

I’ve indeed done exactly that in at least one client project that uses vcpkg. It requires an assumption about where you want to put your vcpkg directory, and you have to think about who/what is going to manage that repo after it is first populated, but it can be made to work if your constraints and assumptions are compatible with that approach. If the caching I mentioned above was implemented, that caching would be a better longer term solution though.

I agree, but my view is even stronger than that. As a general comment, we’d like to avoid introducing yet another new command for specifying the packages/dependencies to bring into a project. We already have find_package() and FetchContent_MakeAvailable(), with the former being the most canonical way to do it. Any new functionality should be able to continue using those. Projects should not need to be updated to take advantage of new ways of providing dependencies. The Dependency Providers feature was developed to carefully follow that principle.

What’s missing at the moment is a way to define details of a dependency in a way that is independent of the implementation used to provide the dependencies. CMake currently provides that capability only for FetchContent via FetchContent_Declare(). Vcpkg uses manifests. Conan has its own approach. CPM defines new commands which use FetchContent under the hood. I tried to capture a unified way of specifying dependencies in issue 22686, but I am not optimistic it will gain the necessary support by the major package managers. Private feedback I’ve received expressed concern that it wouldn’t allow implementation-specific details to be specified. I haven’t pursued that discussion any further due to lack of time, but also from having the will to engage with it sucked out of me by the effort it took to get the dependency-related features finally implemented in CMake 3.24.

7 Likes