Provide a hint to find_package to use a CMake target from the build tree

Hello,

I am having trouble with CMake in a use case that I would have thought to be fairly common. I am not entirely sure what to search for which is why I’m trying the mailing list.

Let’s say I am building a C++ project using CMake, consisting of an executable (A) and a library (B), where A links to B. The way we do this using CMake is straightforward, define targets A and B and link them together, like so (I am skipping source listing for brevity):

add_executable(A)

add_library(B)

target_link_libraries(A PUBLIC B)

This works fine, no problem. Now let’s picture that when expanding on B, I grabbed a thirdyparty library that also uses CMake as a dependency for B. I would prefer to have this thirdparty as part of my build tree so I add it like so:

add_subdirectory(thirdparty/zlib)

add_executable(A)

add_library(B)

target_link_libraries(B PRIVATE zlib)

target_link_libraries(A PUBLIC B)

Again, works fine, no problem. Now, my problem, is if I decided to add another thirdparty library that also depends on the first thirdparty library I added (I’m using DCMTK and zlib as examples here). The way I would like this to work is:

add_subdirectory(thirdparty/dcmtk)

add_subdirectory(thirdparty/zlib)

add_executable(A)

add_library(B)

target_link_libraries(B PRIVATE zlib dcmtk)

target_link_libraries(A PUBLIC B)

Where dcmtk links internally to zlib. The problem I am having is that dcmtk uses find_package to find an installed version of zlib, where as I would like dcmtk to pickup the zlib target from my build tree instead. Is there a way to somehow hint find_package to try to find the targets in the build tree first and then if that fails, fall back to normal find_package behaviour which is search the system for an installed version? Thanks.

Regards,

Hesham

What you suggest is not possible because CMake does not do the build itself.
When CMake process the CMakeLists.txt, the result is the build scripts, not the built artifacts.

To solve your problem, you have to use the concept of super-build by using one of modules ExternalProject or FetchContent.

The second one seems the more appropriate to implement something close to your described workflow.