cmakefetchcontent

CMake FetchContent with header-only project


I am trying to use FetchContent to include a dependency that is a header-only C++ project. It does not need to be built. However, it contains a CMakeLists.txt file that builds its tests, and it is not doing it in a standard way. I would like to bypass the make step entirely, so as not to build the extraneous binary and not to see the warnings that it emits.

My code is currently:

FetchContent_Declare(
  TheProject
  GIT_REPOSITORY <the git repo>
  GIT_TAG <the git commit>
)
FetchContent_MakeAvailable(TheProject)

This correctly downloads the project, but it invokes the make system on it, which is what I don't want. I can fix the problem by changing it to this:

FetchContent_Declare(
  TheProject
  GIT_REPOSITORY <the git repo>
  GIT_TAG <the git commit>
)
FetchContent_Populate(TheProject)

This works, and it does not invoke the build system. Fabulous. But it emits a cursed warning stating that calling FetchContent_Populate by itself is deprecated and will be removed from a future version of cmake. Is there a proper way to accomplish what I want without using a deprecated feature?


Solution

  • The current suggested workaround is to use the SOURCE_SUBDIR option and set it to a path that doesn’t exist.

    There is an open issue on the CMake gitlab to handle this situation better: https://gitlab.kitware.com/cmake/cmake/-/issues/26220

    It is also discussed here: https://discourse.cmake.org/t/prevent-fetchcontent-makeavailable-to-execute-cmakelists-txt/12704

    You can use FETCHCONTENT_BASE_DIR to then add the include directory.

    Example:

    include(FetchContent)
    
    FetchContent_Declare(the-project
      GIT_REPOSITORY <the git repo>
      GIT_TAG <the git commit>
      SOURCE_SUBDIR "MADE-UP-DIRECTORY"
    )
    
    FetchContent_MakeAvailable(the-project)
    
    # I recommend using SYSTEM when dealing with 3rd party code.
    # Avoids the hassle of warnings from a library you don't own.
    target_include_directories(foo SYSTEM PRIVATE
      "${FETCHCONTENT_BASE_DIR}/the-project-src/include"
    )
    

    NOTE: The directories under FETCHCONTENT_BASE_DIR are lower case. This is a documented detail of fetch content so it should be reliable. See https://cmake.org/cmake/help/latest/module/FetchContent.html#populating-content-without-adding-it-to-the-build