gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 10:02:14 25 4
gpt4 key购买 nike

我目前正在开发一个软件包,我想为此提供 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com