CMake子模块依赖关系

3

我有一个CMake项目,其中包含两个子模块ABB依赖于A。在子模块B中,我想使用find_package(A CONFIG)查找A。我的最小(不)工作示例如下:

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 文件。但是据我了解,它是在调用 find_package(A CONFIG) 之后才这样做的,因此无法找到 AConfig.cmake 文件。 你有什么想法可以强制让 find_package() 在执行 A 之后运行吗?

当然,我知道在这个例子中使用 find_package 没有任何意义。在我的实际项目中,子模块是外部软件,我不想修改它们(在我的情况下是 parallelSTL 和 TBB)。


在使用 find_package(A) 前,您需要安装或者构建项目 A。由于构建是在配置阶段完成后进行的,即在处理 CMakeLists.txt 脚本时,您不能同时使用 add_subdirectory 包含两个项目并期望它们能正常工作。要立即构建项目 A,您可以使用 execute_process 命令。 - Tsyvarev
我没有完全理解您的意思,您能否将 add_subdirectory(B)add_subdirectory(A) 的顺序调换一下? - Bingoabs
1个回答

2

实际上,目前cmake并不支持此功能。有关未来计划的讨论可以在这里找到。以下是我丑陋的解决方法:

最初的回答:

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。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接