我有以下结构
project_root/
CMakeLists.txt (A)
ext/
CMakeLists.txt (B)
apps/
CMakeLists.txt (C)
设置似乎是根本问题,只有在添加这个新的" config-style"库。
TL; DR:当(B)中的find_package(foo)
将foo::foo
定义为库时,如何在父作用域中使foo::foo
可用,以便{{1}将适用于(A)和(C)?
target_link_libraries(tgt foo)
发生,找到所需的外部库。它们是add_subdirectory(ext)
和add_subdirectory
的混合体。列表(B)填充额外包含目录,库和编译时定义的列表,使其可用于(A)(以及随后(C))
find_package
List(A)现在添加我的库,包括这些额外的目录,添加这些额外的定义,最终
set(MYPROJ_EXTRA_INC_DIRS "${MYPROJ_EXTRA_INC_DIRS}" PARENT_SCOPE)
set(MYPROJ_EXTRA_LIBS "${MYPROJ_EXTRA_LIBS}" PARENT_SCOPE)
set(MYPROJ_EXTRA_DEFINES "${MYPROJ_EXTRA_DEFINES}" PARENT_SCOPE)
当请求构建应用程序时,target_link_libraries(${MYPROJ_LIB_NAME} ${MYPROJ_EXTRA_LIBS})
发生,列表(C)定义一个使用指定依赖项创建可执行文件的简单宏。相关部分
add_subdirectory(apps)
很长一段时间以来一直很好用。但是,我添加了对使用config-style find_package
定义的新库的支持,而我无法弄清楚如何正确使用它。
调用此新库依赖项target_link_libraries(${appName} ${MYPROJ_LIB_NAME} ${MYPROJ_EXTRA_LIBS})
。它最终定义了一个foo
foo_LIBRARY
。我的理解是我需要做foo::foo
,它在我的库的列表(A)中工作。但是,它不适用于应用程序,并且在宏中我必须为每个可执行文件再次执行target_link_libraries(tgt foo)
。
有没有办法使用不每次都需要运行find_package(foo)
的现有方法(list(APPEND MYPROJ_EXTRA_LIBS <something>)
)?
我已经用尽了所有合理的选项,并且未定义find_package
(如果我只是将-lfoo
添加到列表中,就像我认为的那样),或{{1 IMPORTED或ALIAS目标缺少。}自foo
发生在(B)以来,当我们达到(C)时,该目标不可用。我尝试制作一个ALIAS,但错误是相当于ALIAS的东西无法创建到IMPORTED库。
答案 0 :(得分:3)
find_package
调用的结果( CONFIG 和 MODULE )旨在用于同一目录或以下目录。您很幸运,将变量简单地传播到 PARENT_SCOPE 会使父项可以使用find_package
的结果。
add_subdirectory(ext)
发生,找到所需的外部库。
而不是ext/CMakeLists.txt
中包含的add_subdirectory
,而是通过external.cmake
创建CMake文件(例如include
)。由于include
命令不会引入新变量的范围,因此find_package
调用适用于主CMakeLists.txt
。
许多现有项目处理include
文件中的依赖项。
另一种方法是通过创建本身使用这些结果的 INTERFACE 库目标,将find_package
调用的结果从子目录传播到父目录:
add_library(MyLibExtra INTERFACE)
target_link_libraries(MyLibExtra INTERFACE ${MYPROJ_EXTRA_LIBS})
target_include_directories(MyLibExtra INTERFACE ${MYPROJ_EXTRA_INC_DIRS})
target_compile_definitions(MyLibExtra INTERFACE ${MYPROJ_EXTRA_DEFINES})