CMake 包支持 - 找不到包含和库

CMake Package Support - Includes and Libraries not found

本文关键字:找不到 包含 包支持 支持 CMake      更新时间:2023-10-16

我目前正在开发一个软件包,我想为此提供cmake软件包支持(以便用户可以通过find_package(...)找到它(。问题是,找到包,但FOO_INCLUDE_DIR并且FOO_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"
)

库的标头包含在如下所示的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?这可能是旧的查找模块的工作方式,但不是配置文件的工作方式。甚至更新的查找模块也会公开目标而不是目录变量。

生成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(时,其公共接口将传递传输给其用户。在上面的示例中,bar将从链接目标继承属性。

所以Foo::FooLib1Foo::FooLib2INTERFACE_INCLUDE_DIRECTORIES将被附加到barINCLUDE_DIRECTORIES中。LINK_LIBRARIES也一样。

对于baz,不仅它的INCLUDE_DIRECTORIES将包含Foo::FooLib2条目,而且它自己的INTERFACE_INCLUDE_DIRECTORIES将传递传输Foo::FooLib2的使用需求