“配置样式”cmake find_包在父作用域中不可用

“配置样式”cmake find_包在父作用域中不可用,cmake,Cmake,我有以下结构 project_root/ CMakeLists.txt (A) ext/ CMakeLists.txt (B) apps/ CMakeLists.txt (C) 只有在添加这个新的配置样式库时,设置似乎才是根本问题 TL;DR:当B中的find_packagefoo将foo::foo定义为库时,我如何使foo::foo在父作用域中可用,以便target_link_librariestgt foo同时适用于A和C 列

我有以下结构

project_root/
    CMakeLists.txt     (A)
    ext/
        CMakeLists.txt (B)
    apps/
        CMakeLists.txt (C)
只有在添加这个新的配置样式库时,设置似乎才是根本问题

TL;DR:当B中的find_packagefoo将foo::foo定义为库时,我如何使foo::foo在父作用域中可用,以便target_link_librariestgt foo同时适用于A和C

列表A定义了我的项目的选项,例如编译支持的驱动程序。 添加_子目录ext,并找到所需的外部库。它们是add_子目录和find_包的混合体。列表B填充额外包含目录、库和编译时定义的列表,使A和C都可以使用它们

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)
列表A现在添加我的库,包括这些额外的目录,添加这些额外的定义,最终

target_link_libraries(${MYPROJ_LIB_NAME} ${MYPROJ_EXTRA_LIBS})
当请求构建应用程序时,将执行add_子目录yapps,列表C定义一个简单的宏,该宏使用指定的依赖项创建可执行文件。相关部分

target_link_libraries(${appName} ${MYPROJ_LIB_NAME} ${MYPROJ_EXTRA_LIBS})
长期以来,这种方法一直运作良好。但是,我添加了对使用定义的新库的支持,我不知道如何正确使用它

将此新库依赖项称为foo。它最终定义了一个foo_库,即foo::foo。我的理解是,我需要做target_link_librariestgt foo,它在我的库的列表A中工作。但是,它不适用于应用程序,在宏中,我必须为每个可执行文件再次查找_packagefoo

是否有一种方法可以使用现有的方法listAPPEND MYPROJ_EXTRA_LIBS,而不需要每次运行find_包

我已经用尽了所有合理的选项,如果我只是像我认为应该的那样将foo附加到列表中,那么就没有定义-lfoo,或者导入或别名目标缺少find_包。因为find_packagefoo发生在B中,当我们到达C时,这个目标不可用。我尝试创建别名,但错误是无法将相当于ALIAS的内容创建到导入的库中。

find_package Call的结果CONFIG和MODULE均应在同一目录或以下目录中使用。幸运的是,将变量简单地传播到父对象_范围中可以使父对象使用find_包的结果

添加_子目录ext,并找到所需的外部库

创建CMake文件,例如external.CMake,通过include包含,而不是add_子目录中包含的ext/CMakeLists.txt。因为include命令不引入新变量的作用域,所以它的find_包调用适用于主CMakeLists.txt

许多现有项目在include文件中处理它们的依赖关系

另一种方法是通过创建本身使用这些结果的接口库目标,将find_包调用的结果从子目录传播到父目录:

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})

我明白了,这是一个很好的建议——马上写下来。但是,我设计的库能够作为子项目进行构建。MYPROJ_EXTRA_LIBS和相关文件是母项目所必需的。所以,即使我让它在我的项目中工作,一旦add_子目录ymyproj在父项目中失败,它最终还是会崩溃,对吗?嗯,我已经添加了一种使用接口库的方法。当您的库实际上是一个子项目时,它可能会有所帮助。顺便说一句,set with PARENT_SCOPE仅将变量传播到直接父级。祖父母看不到这个变量。好吧,我还没有让所有的东西都正常工作,但是接口方法肯定是解决这个问题的方法。我以前从来没有用过这个,但它真的非常棒-谢谢!对于那些阅读本文的人来说,随着myproj库的构建和与myproj接口库的链接,一切都会荡漾而过。在父项目中,当我以myproj为目标链接库时,由于myproj链接到myproj接口,父项目甚至不需要知道额外的库正在运行!