Reputation: 16272
I am trying to use a certain library with FetchContent:
FetchContent_Declare(
Catch2
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
GIT_TAG 3f0283de7a9c43200033da996ff9093be3ac84dc
GIT_PROGRESS TRUE
GIT_SHALLOW FALSE
)
FetchContent_MakeAvailable(Catch2)
According to practice I am specifying a particular tag.
However when I look at the files that cmake downloads, the tag is 7cf2f88e50f0d1de324489c31db0314188423b6d
instead, and it is older (Feb 14 2023).
If I manually got to _deps/catch2-src
and do git checkout 3f0283de7a9c43200033da996ff9093be3ac84dc
, I get the correct version (Jun 21 2023).
What is wrong with the FetchContent block above? Why would CMake download the incorrect or older version of the library?
Upvotes: 1
Views: 1764
Reputation: 51055
From the FetchContent docs:
The
FetchContent_Declare()
function records the options that describe how to populate the specified content. If such details have already been recorded earlier in this project (regardless of where in the project hierarchy), this and all later calls for the same content are ignored.
If a previous call to FetchContent_Declare
for the same name (in this case Catch2
) chose a different TAG
, the first one of those calls that sets TAG
will "win". Are there any other calls to FetchContent_Declare
for Catch2 anywhere in the configuration? Perhaps in one of your dependencies (if you have any)? If you don't want to search manually, you can use cmake --trace
and then grep
or jq
for FetchContent_Declare
calls.
This whole business is by design. From the same docs:
Projects should aim to declare the details of all dependencies they might use before they call
FetchContent_MakeAvailable()
for any of them. This ensures that if any of the dependencies are also sub-dependencies of one or more of the others, the main project still controls the details that will be used (because it will declare them first before the dependencies get a chance to)
Once you find the thing that's taking precendence, just move things around in your CMakeLists.txt so that your call to FetchContent_Declare
goes first so it "wins".
If your call to FetchContent_Declare
for a given name is the only one for that name, then you shouldn't have this problem. Even if you change the commitish being referenced in the TAG
argument of your call, the next time your run configuration, CMake will update the checkout to that new commitish. And if you run build without reconfiguring, CMake is usually smart enough at knowing when it needs to reconfigure to do it automatically.
Upvotes: 1
Reputation: 60443
My top suspect is
The
FetchContent_Declare()
function records the options that describe how to populate the specified content. If such details have already been recorded earlier in this project (regardless of where in the project hierarchy), this and all later calls for the same content are ignored.
Upvotes: 2