Reputation: 337
I have a CMake project with two submodules A
and B
. B
depends on A
. In submodule B
I would like to search for A
using find_package(A CONFIG)
. My minimal (not) working example would be:
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(AB)
add_subdirectory(B)
add_subdirectory(A)
A/CMakeLists.txt:
message(STATUS "CMake: A")
add_library(A SHARED A.hpp A.cpp)
target_include_directories(A PUBLIC "${CURRENT_SOURCE_DIR}")
install(TARGETS A EXPORT AA LIBRARY DESTINATION lib/)
export(TARGETS A NAMESPACE AA:: FILE ${CMAKE_BINARY_DIR}/A/AConfig.cmake)
export(PACKAGE AA)
A/A.hpp (some non-sense code)
A/A.cpp
B/CMakeLists.txt
find_package(A CONFIG)
message(STATUS "---> ${A_FOUND}")
add_library(B B.hpp B.cpp)
target_link_libraries(B AA::A)
B/B.hpp (some non-sense code)
B/B.cpp
A/CMakeList.txt
correctly produces a AConfig.cmake
. But as I understand it does that after(!) find_package(A CONFIG)
is called and therefore AConfig.cmake
is not found.
Any idea how to force find_package()
to run after A
is executed?
Of course I know that in this example find_package
does not make any sense. In my actual project the submodules are external software which I do not want to modify (in my case parallelSTL and TBB).
Upvotes: 3
Views: 1860
Reputation: 337
Indeed cmake currently does not properly support this. A discussion for future plans can be found here. Here is my ugly workaround:
A/CMakeLists.txt:
message(STATUS "CMake: A")
add_library(A SHARED A.hpp A.cpp)
target_include_directories(A PUBLIC "${CURRENT_SOURCE_DIR}")
install(TARGETS A EXPORT AA LIBRARY DESTINATION lib/)
export(TARGETS A NAMESPACE AA:: FILE ${CMAKE_BINARY_DIR}/A/AConfig.cmake)
export(PACKAGE AA)
add_library(AA::A ALIAS A)
file(WRITE ${CMAKE_BINARY_DIR}/A/AConfig.cmake "")
# include(CMakePackageConfigHelpers)
# write_basic_package_version_file(
# ${CMAKE_BINARY_DIR}/A/AConfigVersion.cmake
# VERSION 1.0.0
# COMPATIBILITY AnyNewerVersion)
So the idea is to create a dummy file AConfig.cmake
. This is overwritten later but it ensures that find_package()
does not fail before it is actually created. Then we need to alias the target A
to the name after the import AA::A
. In case that there is a requirement on the version of A
, than a file AConfigVersion.cmake
needs to be created as well.
I created a MWE on github.
Upvotes: 2