c++ - CMake 包支持 - 未找到包含和库

标签 c++ cmake

我目前正在开发一个软件包,我想为此提供 cmake 软件包支持(以便用户可以通过 find_package(...) 找到它)。问题是,找到了包,但是 FOO_INCLUDE_DIRFOO_LIBRARIES是空的。

在我的包中,我有几个模块,每个模块都有一个 CMakeLists 文件,该文件安装相应的库和头文件:

install(TARGETS ${LIBRARY_NAME} EXPORT FooTargets
    RUNTIME       DESTINATION ${Foo_RUNTIME_INSTALL_DIR}
    LIBRARY       DESTINATION ${Foo_LIBRARY_INSTALL_DIR}
    ARCHIVE       DESTINATION ${Foo_ARCHIVE_INSTALL_DIR}
    FRAMEWORK     DESTINATION ${Foo_FRAMEWORK_INSTALL_DIR})

# Headers
install(
        DIRECTORY include/${LIBRARY_NAME}
        DESTINATION include/${PROJECT_NAME}
        FILES_MATCHING
            PATTERN "*.h"
            PATTERN "*.hpp"
)

库的 header 包含在 target_include_directories 中,如下所示:
target_include_directories(${LIBRARY_NAME} PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> # for headers when building
        $<INSTALL_INTERFACE:${Foo_INC_INSTALL_DIR}> # for client in install mode
)

我检查了文件夹,所有库和头文件都已正确安装。在我的顶级 CMakeLists 中,我使用以下命令导出目标:
install(
        EXPORT FooTargets
        DESTINATION ${Foo_CMAKE_CONFIG_INSTALL_DIR}
        FILE FooConfig.cmake
)

配置是我假设的位置( usr/local/lib/cmake/Foo )。所以一切似乎都是正确的。当我查看我的 FooConfig.cmake它说:
# Create imported target realm_densifier_base
add_library(FooLib1 SHARED IMPORTED)

set_target_properties(FooLib1 PROPERTIES
  INTERFACE_INCLUDE_DIRECTORIES "/usr/local/include/Foo"
  INTERFACE_LINK_LIBRARIES "...several libraries..."
)

...这是绝对正确的,正是我所期望的。谜题的哪一部分缺失了?是 INTERFACE_INCLUDE_DIRECTORIESINTERFACE_LINK_LIBRARIES不是要设置的正确标志?

感谢您的帮助和最好的问候,

亚历克斯

编辑:

@Guillaume Racicot 已经清理了大部分事情,我只知道向我的项目添加标题的“非目标”方式,即使用 include_directories(Foo_INCLUDE_DIRS)。但是,在目标世界中,链接到我的库 Foo 就足够了。另一件事是我弄乱了 target_include_directories(...) 中的一些目录。命令,所以目录错误,因此在我的其他项目中找不到。谢谢您的帮助!

最佳答案

为什么会FOO_INCLUDE_DIRFOO_LIBRARIES设置?这可能是查找模块的工作方式,但不是配置文件的工作方式。甚至较新的 find 模块会公开目标而不是目录变量。

生成 XYZConfig.cmake 时文件,有关目标的信息将被导出,而不是目录信息。

有了这样的导出:

install(
    EXPORT FooTargets
    NAMESPACE Foo::
    DESTINATION ${Foo_CMAKE_CONFIG_INSTALL_DIR}
    FILE FooConfig.cmake
)

您会期望该软件包的用户像这样使用它:
find_package(Foo REQUIRED)

#         or PUBLIC ------v
target_link_libraries(bar PRIVATE Foo::FooLib1)

如果您的包在导出集中有多个目标,那么您可以链接到两个或仅一个
target_link_libraries(bar PRIVATE Foo::FooLib1 Foo::FooLib2)
target_link_libraries(baz PUBLIC  Foo::FooLib2) # link to lib2 only

当您链接到导出的目标时,如 Foo::FooLib1 ,它的公共(public)接口(interface)将传递给它的用户。在上面的示例中,bar将从链接目标继承属性。

所以INTERFACE_INCLUDE_DIRECTORIESFoo::FooLib1Foo::FooLib2将附加到 barINCLUDE_DIRECTORIES . LINK_LIBRARIES 相同.

对于 baz ,不仅是它的INCLUDE_DIRECTORIES将包含 Foo::FooLib2条目,还有它自己的INTERFACE_INCLUDE_DIRECTORIES将传递 Foo::FooLib2 的使用要求

关于c++ - CMake 包支持 - 未找到包含和库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62070997/

相关文章:

c++ - 附加到文本文件在循环中无法正常工作

c++ - #includes 在命名空间中,到 "embed"命名空间中的预写内容

c++ - 使用 C++ 和 OpenGL 拖动 3 维对象

cmake - 链接第 3 方库

cmake - 基于catkin_tools的IDE打开项目

在字符串中打印出 C++ 整数数字?

c++ - 为什么删除复制构造函数会影响用户定义的默认构造函数?

mongodb - 使用 cmake 的 Yocto 食谱找不到 git

c++ - 为什么在构建依赖库之前目标可执行文件的编译还没有开始?

c++ - 在 CMake 中处理多个 FIND_PACKAGE 调用