Logo

dev-resources.site

for different kinds of informations.

CPM.cmake to make CMake's FetchContent easier

Published at
12/28/2022
Categories
cpp
programming
todayilearned
cmake
Author
pgradot
Author
7 person written this
pgradot
open
CPM.cmake to make CMake's FetchContent easier

Scrolling at my list of starred projets of GitHub, I saw a tool I had forgotten, CPM.cmake, and decided that it was time to try it!

CPM.cmake (or just CPM) describes itself as "a cross-platform CMake script that adds dependency management capabilities to CMake". It's in fact a wrapper around CMake's FetchContent module that makes must easier to download packages.

Do demonstrate its usage, I will build a project that depends on 3 libraries from GitHub: the famous Catch2 and fmt, and the probably not-as-famous-as-it-deserves scnlib.

If you want to try the code below, here is a main.cpp that uses these libraries:

#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <scn/scn.h>
#include <string>

TEST_CASE("My test case") {

    // Scan with scn
    std::string firstName;
    std::string lastName;
    unsigned int number;
    const auto result = scn::scan("Bill Clinton was the 42nd president of the United States",
                            "{} {} was the {}",
                            firstName, lastName, number);

    // Format with fmt
    const auto output = fmt::format("{} {} {}", firstName, lastName, number);

    // Test with Catch2
    CHECK(result);
    CHECK(output == "Bill Clinton 42");
}
Enter fullscreen mode Exit fullscreen mode

Fetching the libraries from GitHub wihtout CPM

Here is how you declare and download the libraries from GitHub without CPM, directly with FetchContent:

include(FetchContent)

FetchContent_Declare(
        Catch2
        GIT_REPOSITORY https://github.com/catchorg/Catch2.git
        GIT_TAG v3.0.0-preview4
)

FetchContent_Declare(
        fmt
        GIT_REPOSITORY https://github.com/fmtlib/fmt.git
        GIT_TAG 9.1.0
)

FetchContent_Declare(
        scnlib
        GIT_REPOSITORY https://github.com/eliaskosunen/scnlib.git
        GIT_TAG v1.1.2
)

FetchContent_MakeAvailable(Catch2 fmt scnlib)
Enter fullscreen mode Exit fullscreen mode

If you have never used FetchContent before:

  1. You include the script, which is provided natively by CMake.
  2. You declare your dependencies.
  3. You download them.

The targets from these libraries are then available and can be used with our own targets:

add_executable(${PROJECT_NAME}
        sources/main.cpp)

target_link_libraries(${PROJECT_NAME}
        PRIVATE
            Catch2::Catch2WithMain
            fmt
            scn)
Enter fullscreen mode Exit fullscreen mode

With CPM instead

CPM is just a single .cmake file but it is not provided out-of-the-box by CMake. You have to download it from GitHub.

The simplest solution is to browse the release page, download CPM.cmake from the desired release, and copy it to your project's directory.

Another nice solution is to ask CMake to download the file for you. To do so, you can simply add the following lines at the beginning of your CMakeLists.txt :

set(CPM_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR}/CPM.cmake)

file(DOWNLOAD
        https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/cpm.cmake
        ${CPM_DOWNLOAD_LOCATION})

include(${CPM_DOWNLOAD_LOCATION})
Enter fullscreen mode Exit fullscreen mode

And then, it's so really simple to get our libraries from GitHub! We just have to replace all calls to FetchContent_xxx() functions with:

CPMAddPackage("gh:catchorg/Catch2#v3.0.0-preview4")
CPMAddPackage("gh:eliaskosunen/scnlib#v1.1.2")
CPMAddPackage("gh:fmtlib/fmt#9.1.0")
Enter fullscreen mode Exit fullscreen mode

There is no equivalent call to FetchContent_MakeAvailable().

The call to target_link_libraries() is unchanged.

The SYSTEM property

In my previous article "The SYSTEM property from CMake 3.25", I talked about the SYSTEM option for the function FetchContent_Declare(). As of Decembre 28th 2022, there is unfortunately no matching option in CPM... An issue has been created in July but it's still open.

Conclusion

CPM can do more than just simplifying calls to FetchContent_Declare(). For instance, it has a cache so that dependencies used by several projects can be downloaded only once.

But honnestly, the simplicity of CPMAddPackage() compared to FetchContent_Declare() seems enough to use CPM ๐Ÿฅณ

cmake Article's
30 articles in total
Favicon
Fixing libdc1394.so.22: cannot open shared object file (ใ… ๏นใ… )
Favicon
Automate Versioning with Git and CMake
Favicon
vcpkg - how to modify dependencies
Favicon
Getting started with GoogleTest and CMake
Favicon
Building a Desktop C++ Barcode Scanner with Slimmed-Down OpenCV and Webcam
Favicon
Use cosmocc to crossโ€compile a CMake project
Favicon
Improve Productivity with CMake and Compiler Cache Integration
Favicon
Conan: Your Embedded Cross-Compilation Champion
Favicon
Streamlining STM32 Projects: VS Code, CMake and clangd
Favicon
Easily add packages to CMake with CPM
Favicon
Jolt Physics raylib: trying 3D C++ Game Physics Engine
Favicon
Using raylib with Dear ImGui: Game Dev Debugging UI
Favicon
Using Jolt with flecs & Dear ImGui: Game Physics Introspection
Favicon
codemapper: join dev team of this sources analysis tool (C++/Qt5)
Favicon
CMake on SMT32 | Episode 8: build with Docker
Favicon
CMake on SMT32 | Episode 7: unit tests
Favicon
[04/52] MOAR CMAKEZ!
Favicon
How to use Flatbuffers in a C++ project with Conan?
Favicon
[03/52] - CMake and Git Submodules: More Advanced Cases
Favicon
get_cmake_version raise SKBuildError(msg) from err
Favicon
Basic C++ Unit Testing with GTest, CMake, and Submodules
Favicon
Felt Cute, Might git rm --rf
Favicon
Install CMake on Windows
Favicon
Maximizing Automation and Scripting in CMake for Efficient Software Development
Favicon
Include custom CMake modules
Favicon
Build a project on Windows 11 using MinGW
Favicon
Cleanup my dependency management with vcpkg
Favicon
CMake cheat sheet!
Favicon
CPM.cmake to make CMake's FetchContent easier
Favicon
The SYSTEM property from CMake 3.25

Featured ones: