c++ - CMake - 未找到链接的静态库的头文件?
问题描述
我的应用程序无法从我尝试使用的单独构建的库中找到头文件。
这是我的项目的文件夹结构:
app/
app.h
app.cpp
CMakeLists.txt
build/
...
lib/
lib.h
lib.cpp
CMakeLists.txt
build/
libtest_lib.a
...
的内容app/CMakeLists.txt
:
project(test_app)
add_executable(test_app app.cpp)
target_link_libraries(test_app ${PROJECT_SOURCE_DIR}/../lib/build/libtest_lib.a)
的内容lib/CMakeLists.txt
:
project(test_lib)
add_library(test_lib lib.cpp)
target_include_directories(test_lib PUBLIC ${PROJECT_SOURCE_DIR})
当我尝试#include "lib.h"
从app.cpp
.
我也尝试添加“导入库”并设置位置属性,但仍然遇到同样的问题。
我知道在这类项目中使用了顶级 CMakeLists,但我试图让这两个组件分别构建。
解决方案
我知道在这类项目中使用了顶级 CMakeLists,但我试图让这两个组件分别构建。
如果你想真正分开构建它们,你将不得不通过一些样板。我假设您处于值得痛苦的情况:也许您必须使用两个不同的工具链。add_subdirectory
否则,只需两次调用即可在顶层创建构建,lib
然后app
使用相同的以下列表文件将起作用(您甚至可以删除包装内容)。
基本上,在 CMake 中,您应该始终使用目标。除非没有其他方法,否则永远不要直接链接到库文件。当您使用目标时,如下所示,它甚至会为您正确设置包含路径。这是因为 CMake 将PUBLIC
/INTERFACE
属性(如由 设置的那些target_include_directories
)传播给链接对象。
CMake 无法神奇地从完全编译的静态库中确定包含路径,它甚至不知道它已构建。这就是这里问题的症结所在。您需要使用目标。
无论如何,样板文件只是声明您要导出哪些目标,然后实际继续导出它们。该GNUInstallDirs
模块为任何系统设置了合理的默认值。这个特殊功能需要 CMake 3.14+,但我放了 3.19,因为这是我测试过的(你永远不应该在 CMake 或其他任何地方声明未经测试的最低版本)。
这是CMakeLists.txt
图书馆的:
cmake_minimum_required(VERSION 3.19)
project(test_lib)
add_library(test_lib lib.cpp)
add_library(test_lib::test_lib ALIAS test_lib)
target_include_directories(test_lib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
## Packaging rules to generate CMake exports
include(GNUInstallDirs)
install(TARGETS test_lib
EXPORT test_lib_targets
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
export(EXPORT test_lib_targets
NAMESPACE test_lib::
FILE "${CMAKE_INSTALL_LIBDIR}/cmake/test_lib/test_lib-config.cmake")
在应用程序的 CMakeLists.txt 中:
cmake_minimum_required(VERSION 3.19)
project(test_app)
find_package(test_lib REQUIRED)
add_executable(test_app app.cpp)
target_link_libraries(test_app PRIVATE test_lib::test_lib)
在命令行中,您可以像这样单独构建它们:
$ cmake -S lib -B lib/build -DCMAKE_BUILD_TYPE=Release
$ cmake --build lib/build
$ cmake -S app -B app/build -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/path/to/lib/build
$ cmake --build app/build
如果您想更进一步并支持安装您的 CMake 目标脚本(而不仅仅是从构建目录中导出它们),请查看install(EXPORT)
命令:https ://cmake.org/cmake/help/latest/command/install.html#出口
推荐阅读
- java - 为什么我的输出没有保存为文件?
- javascript - RoR,Javascript - 计数器在 #show 操作中不起作用
- jquery - 在 Bootstrap 4 范围滑块中使用 Click 功能添加增量/减量
- javascript - 为什么发生 JavaScript 运行时错误:对象不支持属性或方法“getTime”?(getTime 不是函数)
- python - 如何使用 python 获得正确的正面区域?
- firebase - StreamProvider - RangeError(索引):无效值:有效值范围为空:0
- java - Spring JPA - 持久化@ManyToMany实体 - 重复实体错误
- django - 无法在自定义多用户中创建超级用户
- c++ - 使用 AVX2 显着降低功能
- youtube - 在 Discord Bot 中使用 YouTube API