This might be an x y problem, so here's my situation.
I have the following project structure:
-project
-examples
-example_that_uses_mylib_1
* CMakeLists.txt
* main.cpp
-example_that_uses_mylib_2
* CMakeLists.txt
* main.cpp
-external
-notmylib_a
* CMakeLists.txt
* ... (other stuff)
-notmylib_b
* CMakeLists.txt
* ... (other stuff)
-src
-mylib_stuff
* file1.cpp
* file1.h
*CMakeLists.txt
CMakeLists.txt
I'm attempting to make a cmake file that does the following:
allows mylib
to depend on targets in 3rd party libraries found in external
with out using add_subdirectory
given that they aren't actually sub directories and that is bad practice.
allows example_that_uses_mylib
executables that depend on mylib
target with out adding it as a sub directory.
I was unsure of how to do this until I saw this project whos top level cmake does this:
add_subdirectory(lib/foo)
add_subdirectory(src/bar)
add_subdirectory(src/baz)
and bar and baz CMakeLists.txt
do this:
#Bar
find_package(foo 0.1.2 CONFIG REQUIRED)
#Baz
find_package(bar CONFIG REQUIRED)
Which made me think I could do the same with my libraries. I couldn't.
Originally the single top level CMakeLists.txt built all targets, I wanted to move away from this, and split up building with add_subdirectories, starting with mylib
.
Originally my top level CMakeLists.txt looked a lot like this (which previously worked):
add_subdirectory(external/notmylib_a)
add_library(mylib STATIC src/mylib_stuff/file1.cpp)
target_include_directories(mylib PUBLIC src/)
target_link_libraries(mylib PRIVATE notmylib_a::notmylib_a)
when I decided to split things up so originally I did this (which also works):
#CMakeLists.txt
add_subdirectory(external/notmylib_a)
#src/CMakeLists.txt
add_library(mylib STATIC src/mylib_stuff/file1.cpp)
target_include_directories(mylib PUBLIC src/)
target_link_libraries(mylib PRIVATE notmylib_a::notmylib_a)
Then to follow the other project I decided to do this:
#CMakeLists.txt
add_subdirectory(external/notmylib_a)
#src/CMakeLists.txt
find_package(notmylib_a CONFIG REQUIRED) #NEW LINE!!
add_library(mylib STATIC src/mylib_stuff/file1.cpp)
target_include_directories(mylib PUBLIC src/)
target_link_libraries(mylib PRIVATE notmylib_a::notmylib_a)
and I got an error in CMAKE
CMake Error at src/CMakeLists.txt:25 (find_package):
Could not find a package configuration file provided by "notmylib_a"
with any of the following names:
notmylib_aConfig.cmake
notmylib_a-config.cmake
Add the installation prefix of "notmylib_a" to CMAKE_PREFIX_PATH or set
"notmylib_a_DIR" to a directory containing one of the above files. If
"notmylib_a" provides a separate development package or SDK, be sure it
has been installed.
How was the other project able to utilize find_package
in such a way?
How was the other project able to utilize
find_package
in such a way?
Config file for other foo
project has these lines checking for the target's existence :
if(NOT TARGET foo::foo)
include("${foo_CMAKE_DIR}/foo-targets.cmake")
endif()
That is, when the foo
is included with add_subdirectory
approach or via another method, and creates foo::foo
target, find_package(foo)
actually ignores its configuration file.
This is noted in the foo's CMakeLists.txt:
# We also add an alias definition so that we shadow
# the export namespace when using add_subdirectory() instead.
add_library(foo::foo ALIAS foo)
In other words, with given foo
package included with add_subdirectory
approach, using find_package(foo)
is possible, but optional: One may directly use foo
or foo::foo
target without any find_package()
.