CMake库依赖项

tom*_*ham 6 c++ cmake

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

base
 ?? cmake
 ?? docs
 ?? examples
 ?? sources
    ?? libA
    ?   ?? include
    ?   ?   ?? libA
    ?   ?       ?? core.h
    ?   ?       ?? *.h
    ?   ?? source
    ?   ?   ??*.cpp
    ?? libB
        ?? include
        ?   ?? libB
        ?       ?? message.h
        ?       ?? *.h
        ?? source
            ?? *.cpp
Run Code Online (Sandbox Code Playgroud)

CMakeLists.txt几个地方有文件.主要的是在根目录中base,它设置了一堆变量和选项,最后调用add_subdirectory(sources).在sourcesCMakeLists.txt文件只是简单地调用:

add_subdirectory(libA)
add_subdirectory(libB)
Run Code Online (Sandbox Code Playgroud)

最后有CMakeLists.txt两个文件libAlibB目录.除目标名称外,它们大致相同.其中一个文件的示例是:

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})
Run Code Online (Sandbox Code Playgroud)

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

// base/sources/libB/source/message.cpp

#include <ctime>
#include <iostream>

#include <libA/core.h>
#include <libB/message.h>
Run Code Online (Sandbox Code Playgroud)

但是当我构建它时,我收到以下错误:

fatal error: 'libA/core.h' file not found
Run Code Online (Sandbox Code Playgroud)

我尝试过使用target_link_libraries,target_include_directories没有任何运气.显然我使用这些错误或根本不明白这些做了什么.

oLe*_*Len 6

因为你的库libB需要一个头来libA编译,所以假设libA是一个依赖libB.幸运的是,CMake非常聪明地处理依赖关系,所以你的工作很简单:

力霸

代替

# Add include directories
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include")
Run Code Online (Sandbox Code Playgroud)

添加到最后

target_include_directories(${target} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
Run Code Online (Sandbox Code Playgroud)

这将告诉CMake它还必须包含libA其他需要它的项目的标题.

libB

告诉CMake libB需要libA:

target_link_libraries(${target} libA)
Run Code Online (Sandbox Code Playgroud)

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

  • 这就是现代的方式!为了保持一致性,您也应该使用 PUBLIC/PRIVATE/INTERFACE 进行 target_link_libraries 调用! (2认同)

Ram*_*ama 4

您可以将另一个包含目录添加到CMakeLists.txtfor中libB

include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../libA/include")
Run Code Online (Sandbox Code Playgroud)