Thirdparty dependencies with FetchContent


Welcome to the next pikoTutorial !

FetchContent module tries to be the solution to never-ending discussion about the package management in C++ (I wrote a bit about it in one of the articles of Make C++ a better place series). It’s not a package manager by itself, but it integrates natively with CMake which the big part of C++ community uses anyway.

FetchContent promises also easy integration even with legacy project, especially given the fact that it doesn’t require any propriety format of the dependency, but re-uses what is already widely used – GitHub repositories and tar.gz archives stored in project-specific artifactories.

Dependency as a GitHub repository

Let’s say I want to add my command line parsing library as a dependency to a new project. I can use FetchContent to clone the repository:

CMake
cmake_minimum_required(VERSION 3.28)
project(FetchContentExample)
# include FetchContent module
include(FetchContent)
# fetch Comlint library
FetchContent_Declare(
    # specify library name
    ComlintCpp
    # specify GitHub repository
    GIT_REPOSITORY https://github.com/pasparsw/comlint_cpp
    # specify tag or commit hash
    GIT_TAG v0.3
)
# make the content available
FetchContent_MakeAvailable(ComlintCpp)
# add executable target
add_executable(${PROJECT_NAME} main.cpp)
# link the fetched library
target_link_libraries(${PROJECT_NAME} PRIVATE
    ComlintCpp
)

The repository is downloaded to build/_deps folder and sources are available in build/_deps/comlintcpp-src folder.

Dependency as a pre-built release package

Of course, in many projects building from source is out of question because of e.g. build time. Fortunately, FetchContent allows for downloading a tar.gz files from the given URL. Comlint comes in in a form of a release package containing public headers and .so dynamic library file, so let’s use it:

CMake
minimum_required(VERSION 3.28)
project(FetchContentExample)
# include FetchContent module
include(FetchContent)
# fetch ComlintCpp library
FetchContent_Declare(
    ComlintCpp
    URL https://github.com/pasparsw/comlint_cpp/releases/download/v0.3/comlint_cpp_v0.3.tar.gz
)
FetchContent_MakeAvailable(ComlintCpp)
# add executable target
add_executable(${PROJECT_NAME} main.cpp)
# include headers
target_include_directories(${PROJECT_NAME} PRIVATE
    ${comlintcpp_SOURCE_DIR}/include
)
# link library
target_link_libraries(${PROJECT_NAME} PRIVATE
    ${comlintcpp_SOURCE_DIR}/libComlintCpp.so
)