What are the interaction guarantees with find_package and FetchContent_*

Say, in a large library where not all the dependencies are under the explicit control of someone or some standard, I have:

find_package(xxx VERSION 1.0 REQUIRED) followed, say in a very remote library, by a
FetchContent_Declare(xxx SYSTEM OVERRIDE_FIND_PACKAGE)
FetchContent_MakeAvailable(xxx)

target_link_libraries(abc PRIVATE xxx)

What xxx lib will be used for abc, the one first found using find_package or the one via FetchContent_MakeAvailable.

If we append the following lin to the example:

find_package(xxx VERSION 1.0 REQUIRED)
target_link_libraries(efg PRIVATE xxx)

What xxx lib will be used for efg, the one first found using first find_package or the one via FetchContent_MakeAvailable (because we used OVERRIDE_FIND_PACKAGE).

CMake doesn’t support two targets with the same name to exist within a scope. Note that find_package bits will usually check for existence before making their own targets (to avoid errors when called multiple times within a scope). Projects usually assume that nothing else will provide its own target names.

So, the “typical” answer is that find_package first will probably cause a duplicate target error from the FetchContent. Switching the order will make the package script not make targets because they already exist.

The true answer can only be discovered by looking at the code (or using --trace-expand to see where targets are made).

Sorry it took me a while to get to this question. The example in your original post is malformed. If you use the OVERRIDE_FIND_PACKAGE keyword with FetchContent_Declare(), you must ensure that call occurs before any call to find_package() for that same dependency. This isn’t explicitly stated in the FetchContent docs, but those docs do say that when using the OVERRIDE_FIND_PACKAGE keyword, it only affects subsequent calls to find_package() for that dependency.

1 Like