我有一个带有两个子模块A
和B
的CMake项目。 B
取决于A
。在子模块B
中,我想使用A
搜索find_package(A CONFIG)
。我的最小(不可行)示例是:
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
正确产生一个AConfig.cmake
。但是据我所知,它是在after(!)find_package(A CONFIG)
被调用之后因此找不到AConfig.cmake
。
知道如何在执行find_package()
之后强制A
运行吗?
我当然知道在此示例中,find_package
没有任何意义。在我的实际项目中,子模块是我不想修改的外部软件(在我的情况下为parallelSTL和TBB)。
答案 0 :(得分:1)
独立的cmake当前不正确支持此功能。可以在here中找到有关未来计划的讨论。这是我的丑陋解决方法:
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)
因此,想法是创建一个虚拟文件AConfig.cmake
。稍后将覆盖此内容,但可确保find_package()
在实际创建之前不会失败。然后,我们需要将目标A
别名为导入AA::A
之后的名称。如果对A
的版本有要求,则还需要创建文件AConfigVersion.cmake
。
我在github上创建了MWE。