【问题标题】:CMake library dependenciesCMake 库依赖项
【发布时间】:2017-02-10 18:58:15
【问题描述】:

这可能有点难以完整解释。我已经为我正在编写的一系列 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,但没有任何运气。很明显,我用错了,或者根本不明白这些都是做什么的。

【问题讨论】:

    标签: c++ cmake


    【解决方案1】:

    由于您的库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)
    

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

    【讨论】:

    • 这是现代方式!为了保持一致性,您也应该使用 PUBLIC/PRIVATE/INTERFACE 来调用 target_link_libraries!
    【解决方案2】:

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

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

    【讨论】:

    • 可能是"${CMAKE_CURRENT_SOURCE_DIR}/..",因为使用了&lt;libA/core.h&gt;
    • @RedUser,不,其实完整路径是../libA/include/libA/core.h
    猜你喜欢
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多