Reputation:
I have static library Foo
, static library Bar
that depends on Foo
and executable Baz
that depends on Bar
.
Relevant sections from Foo
CMakeLists.txt
:
# Specifying files to copy during "make install" command.
install(TARGETS Foo EXPORT FooConfig
INCLUDES DESTINATION include
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
# Specifying config file that will be used to find a library using find_package().
install(EXPORT FooConfig
FILE FooConfig.cmake
NAMESPACE Foo::
DESTINATION lib/cmake/Foo)
export(TARGETS Foo
NAMESPACE Foo::
FILE FooConfig.cmake)
Relevant sections from Bar
CMakeLists.txt
:
# Specifying libraries that are required for build.
find_package(Foo REQUIRED)
# Specifying libraries to link to for the users of the library.
target_link_libraries(Bar PUBLIC Foo::Foo)
# Specifying files to copy during "make install" command.
install(TARGETS Bar EXPORT BarConfig
INCLUDES DESTINATION include
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
# Specifying config file that will be used to find a library using find_package().
install(EXPORT BarConfig
FILE BarConfig.cmake
NAMESPACE Bar::
DESTINATION lib/cmake/Bar)
export(TARGETS Bar
NAMESPACE Bar::
FILE BarConfig.cmake)
And finally Baz
CmakeLists.txt
:
find_package(Bar REQUIRED)
target_link_libraries(Baz PRIVATE Bar::Bar)
Now when building Baz
I get:
CMake Error at CMakeLists.txt:19 (add_executable):
Target "Baz" links to target "Foo::Foo" but the
target was not found. Perhaps a find_package() call is missing for an
IMPORTED target, or an ALIAS target is missing?
So build finds Bar
and correctly determines that it depends on Foo
but can't find Foo
. I have another test project that directly depends on Foo
and it builds fine. How to fix this?
Upvotes: 12
Views: 2890
Reputation:
Unfortunately, BarConfig.cmake
generated like this does not handle finding dependencies, I had to modify Bar
CMakeLists.txt
to this:
# Specifying files to copy during "make install" command.
install(TARGETS Bar EXPORT BarTargets
INCLUDES DESTINATION include
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
install(FILES CMake/BarConfig.cmake DESTINATION lib/cmake/Bar)
# Specifying config file that will be used to find a library using find_package().
install(EXPORT BarTargets
FILE BarTargets.cmake
NAMESPACE Bar::
DESTINATION lib/cmake/Bar)
export(TARGETS Bar
NAMESPACE Bar::
FILE BarTargets.cmake)
Then I created a file CMake/BarConfig.cmake
with this:
include("${CMAKE_CURRENT_LIST_DIR}/BarTargets.cmake")
find_package(Foo REQUIRED)
Now this BarConfig.cmake
gets installed globally and calls find_package
that finds Foo
.
Upvotes: 12