I am trying to wrap my head around the interplay between find_package and fetchContent.
Firstly: I need to support 2 use cases:
- On my laptop I develop locally in WSL. So I have full internet available and I can use FetchContent to download stuff.
- When building on our embedded target we use ssh to remotely copy the source files and run cmake on the embedded target. No internet connection.
As such, I would like to create a scenario (if possible) where locally I can use the fetchContent to download the dependencies, but on the embedded target I will have to provide them manually. The concept of FetchContent_Declare with âFIND_PACKAGE_ARGSâ (as described in chapter 39.5.1 from Scotts book and in the online manual) seemed perfect.
But, I also want to optimize my workstation and build times. So preferably I download and build it only once and that is that. But strangely that seems not to work.
Information: using cmake 4.0.3, and WSL.
Question 1:
If I use this (which is just the online example)
cmake_minimum_required(VERSION 3.24)
# Use new FetchContent behavior if supported
set(CMAKE_POLICY_DEFAULT_CMP0168 NEW)
include(FetchContent)
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG 2b60af89e23d28eefc081bc930831ee9d45ea58b #v3.8.1
FIND_PACKAGE_ARGS
)
FetchContent_MakeAvailable(Catch2)
find_package(Catch2)
Then indeed I see in my out/builds/<config>/_deps
folder the download of the 3 catch2 projects:
- catch2-build
- catch2-src
- catch2-subbuild
(No idea why 3 and where they come from. In no way do I recognize anything from the git repo you get when visiting github.) I also see config files appearing in the CMakeFiles/pkgRedirects folder, as expected.
Cmake reports that this took around 7s to do (can vary up to 10s). What I donât understand is why it takes 7 seconds every time? If I just rerun cmake without cleaning, I would expect it to go much faster the second time since there is no need to download again.
Question 2:
How does this now connect to find_package?
I would expect that at some point the downloaded source files get compiled into the output that find_package needs. So that in subsequent runs it is using the find_package to link directly to the most optimized version of the dependencies. If so, where is that output being stored? How should I refer to this so that my second run gets faster?
Question 3:
I think I understand why it chooses a folder so deep, but the fact that it is a subfolder of the project and the config means that it is downloading catch2 for every project-config combination. As you can imagine we use testing in almost any projects, so probably I have a dozen copies of catch2 on my drive (obviously catch2 is just an example, but not the only dependency that is used a lot).
What is the good way to deal with this?
I was thinking of changing (in my CMakeUserPresets) the FETCHCONTENT_BASE_DIR to be outside my project and refer all my local builds to the same base dir. This could be like my local dependency repo.
But as I experiment with this, It seems that fetchcontent is not the good way to populate this repo as it does not compile. So the find_package is still unable to find the things fetchcontent downloaded.