CMake库依赖项

CMake library dependencies

本文关键字:依赖 CMake      更新时间:2023-10-16

这可能有点难以完全解释。我已经为我正在编写的一系列C++库设置了一个目录结构。我打算使用CMake来构建这些库。在大多数情况下,这些库是完全独立的"子系统",但在一些奇怪的地方,一个库需要访问另一个库中包含的头文件。这是我的目录结构。

base
├─ cmake
├─ docs
├─ examples
└─ sources
├─ libA
│   ├─ include
│   │   └─ libA
│   │       ├─ core.h
│   │       └─ *.h
│   ├─ source
│   │   └─*.cpp
└─ libB
├─ include
│   └─ libB
│       ├─ message.h
│       └─ *.h
└─ source
└─ *.cpp

有几个地方有CMakeLists.txt文件。主目录位于根目录base中,它设置了一组变量和选项,最后调用add_subdirectory(sources)。在sources中,CMakeLists.txt文件简单地调用:

add_subdirectory(libA)
add_subdirectory(libB)

最后,libAlibB目录中都有CMakeLists.txt文件。除了目标名称之外,它们基本上是相同的。其中一个文件的例子是:

set(target libA)
# Sources
set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}")
set(source_path  "${CMAKE_CURRENT_SOURCE_DIR}/source")
# Add include directories
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
# Set the source files to compile
file(GLOB_RECURSE sources ${source_path}/**/*.cpp)
# Build library
add_library(${target} ${sources})

现在,这两个库都可以单独构建而不会出现问题,但我需要能够在libB中的源文件中包含来自libA的头

// base/sources/libB/source/message.cpp
#include <ctime>
#include <iostream>
#include <libA/core.h>
#include <libB/message.h>

然而,当我构建这个时,我会得到以下错误:

fatal error: 'libA/core.h' file not found

我尝试过使用target_link_librariestarget_include_directories,但没有任何运气。很明显,我用错了这些,或者根本不明白它们的作用

由于您的库libB需要来自libA的头进行编译,因此假设libAlibB的依赖项。幸运的是,CMake在处理依赖关系方面非常聪明,所以你的工作很容易:

libA

代替

# Add include directories
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")

添加到最终

target_include_directories(${target} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")

这将告诉CMake,它还必须包括libA到其他需要它的项目的头

libB

只需告诉CMake libB需要libA:

target_link_libraries(${target} libA)

请注意,这与编译时的链接步骤没有直接关系。对于库,它主要告诉存在这种依赖关系,在这种情况下,它将自动添加头的路径。

您可以为libB添加CMakeLists.txt,另一个包含目录:

include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../libA/include")