FetchContent with loose .cmake files

Calling @craig.scott :slight_smile:

I’ve been reading your excellent Professional CMake book and have got to the section about other uses for FetchContent (27.2.2). It talks about being able to pull down individual .cmake files for use across a number of projects. I have created a repo with a simple .cmake file I’d like to reuse (https://github.com/pr0g/cmake-helpers) and have copied the commands required but I don’t quite understand how to reference that given file in my CMakeLists.txt file.

I see that it appears here build/_deps/cmake-helpers-src/simple-install.cmake but when I try and use include(simple-install.cmake) in the root CMakeLists.txt file it can’t be found. I’ve tried with a relative path but that doesn’t seem to work either.

An example of how to actually reference the file would be incredibly useful!

Thanks very much for your time,

Tom

cmake_minimum_required(VERSION 3.14)
project(fcpr0g)

include(FetchContent)
FetchContent_Declare(pr0g-cmake-helpers
    GIT_REPOSITORY https://github.com/pr0g/cmake-helpers.git
    GIT_TAG 35e7d1ad7b4f21e12d225964f2561d3eb38b49f5
)
FetchContent_MakeAvailable(pr0g-cmake-helpers)
list(APPEND CMAKE_MODULE_PATH ${pr0g-cmake-helpers_SOURCE_DIR})

# Now you should be able to do this (note the dropped file extension):
include(simple-install)

# Or if you don't want to touch CMAKE_MODULE_PATH:
include(${pr0g-cmake-helpers_SOURCE_DIR}/simple-install.cmake)
3 Likes

Amazing! :grinning_face_with_smiling_eyes: Thank you so much :blush:

Thanks again for your help, much appreciated!

(sorry I misread the initial response and missed MakeAvailable - I was using the longer-form example from the book)

One caveat with FetchContent_MakeAvailable() for a use case like this is that it will look for a CMakeLists.txt file in the top level directory of the fetched content, and if it finds one, it will automatically bring it into the main project with add_subdirectory(). That might not always be what you want, in which case you may want to use the more verbose form instead:

FetchContent_GetProperties(pr0g-cmake-helpers)
if(NOT pr0g-cmake-helpers_POPULATED)
    FetchContent_Populate(pr0g-cmake-helpers)
endif()

If you know that the project you’re fetching does not have such a CMakeLists.txt file at its top level, then either approach should be okay, it’s just that FetchContent_MakeAvailable() is much more concise.

1 Like

Ah I see, got you! :slight_smile:

Helpful to know about both options. I’ll stick with FetchContent_MakeAvailable for this particular use-case as I don’t intend to add a root level CMakeLists.txt file to the cmake-helpers repo.

Tested it out just now and it worked like a charm :grinning_face_with_smiling_eyes: Thanks again!