首页 > 解决方案 > 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,但我试图让这两个组件分别构建。

标签: c++cmake

解决方案


我知道在这类项目中使用了顶级 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#出口


推荐阅读