I have a hierarchy like this:
CMakeLists.txt # calls add_subdirectory() for subdirs in the listed order
+-deps
| +-CMakeLists.txt # calls find_package(Vulkan), a 3rd party lib, present on my system
+-mylib
| +-CMakeLists.txt # depends on Vulkan::Vulkan
| +-mylib.cpp
+-example
+-CMakeLists.txt # depends on Vulkan::Vulkan
+-example.cpp
The problem is that in mylib/CMakeLists.txt and example/CMakeLists.txt for the following command:
target_link_libraries(mylib PRIVATE Vulkan::Vulkan)
I got the following error:
CMake Error at mylib/CMakeLists.txt:2 (target_link_libraries):
Target "mylib" links to:
Vulkan::Vulkan
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
And the same goes for example/CMakeLists.txt.
My question: How can I make those CMakeLists.txt files see the targets found by find_package() in their sibling CMakeLists.txt files?
What I tried:
I moved the find_package() to the root CMakeLists.txt, and then everything worked. But I want to neatly organize my files. This is a strongly simplified version. The real hierarchy is much more complicated.
I found set(PARENT_SCOPE) and was able to propagate the TRUE value of ${Vulkan_FOUND} from deps to root and then to example. Maybe something similar is needed but for targets instead of variables?
Details:
./CMakeLists.txt:
cmake_minimum_required(VERSION 3.6...3.22)
project(mylib VERSION 0.0.1)
add_subdirectory(deps)
add_subdirectory(mylib)
add_subdirectory(example)
./deps/CMakeLists.txt:
find_package(Vulkan)
./mylib/CMakeLists.txt:
add_library(mylib mylib.cpp)
target_link_libraries(mylib PUBLIC Vulkan::Vulkan)
./example/CMakeLists.txt:
add_executable(example example.cpp)
target_link_libraries(example PUBLIC mylib Vulkan::Vulkan)
In CMake
find_packageusage is expected to be local to the directory and its descendants. If some other directory (from other hierarchy) needs the same package, then it should repeatfind_packagecall.Concerning specifically "deps" functionality, I saw many projects which move this functionality into a separate
.cmakescript, and include that script viainclude()command in the rootCMakeLists.txt. Wherever the included.cmakescript is located, theincludecommand does NOT introduce a directory scope. So, everyfind_packagecall from that script is scoped to the rootCMakeLists.txt, so its results can be used in any subdirectory../cmake/deps.cmake:./CMakeLists.txt: