在CMake中包含带库的标头

时间:2017-09-19 09:17:51

标签: c++ cmake

我的项目中有两个实用程序库。我正在寻找为库编写CMake配置的最佳方法。

/my_project
 --> CMakeLists.txt
 --> main.cpp
 --> /utils
      --> CMakeLists.txt
      --> common.h
      --> /base_c
           --> CMakeLists.txt
           --> base_c.c
           --> base_c.h
      --> /base_cpp
           --> CMakeLists.txt
           --> base_cpp.cpp
           --> base_cpp.hpp

我目前的CMake文件:

/my_project/CMakeLists.txt

cmake_minimum_requared(VERSION 3.8)
project(my_project)

add_subdirectory(utils)

add_executable(main main.c)
target_link_libraries(main utils base_c base_cpp)

/my_project/utils/CMakeLists.txt

add_subdirectory(base_c)
add_subdirectory(base_cpp)

add_library(utils)
target_sources(utils PUBLIC common.h)

/my_project/utils/base_c/CMakeLists.txt

add_library(base_c base_c.c)
target_sources(base_c PUBLIC base_c.h)

/my_project/utils/base_cpp/CMakeLists.txt

add_library(base_cpp base_cpp.cpp)
target_sources(base_cpp PUBLIC base_cpp.hpp)

find_library(BASEC base_c ../base_c)
target_link_libraries(base_cpp BASEC)

问题是base_cpp找不到来自base_c的内容。我该如何修复配置?

我设法使其与target_include_directories(base_cpp PRIVATE ../base_c)一起使用,但根据INTERFACE_INCLUDE_DIRECTORIES documentation,这很难看,并且不应该是必要的。

2 个答案:

答案 0 :(得分:1)

target_include_directories)正是您要找的,而不是PRIVATE选项。

根据 target_include_directories() documentation PRIVATE选项仅适用于该目标中使用的目录,INTERFACE适用于仅由相关目标使用的目录,而PUBLIC适用于两者。

我建议在/my_project/utils/base_c/CMakeLists.txt中使用

target_include_directories(base_c INTERFACE ${CMAKE_CURRENT_LIST_DIR})

这样你就可以链接"它所属目标的include目录以及依赖它的所有目标都自动包含目录。

此外,您可能希望将公开标头移至自己的子文件夹/my_project/utils/base_c/base_c/,然后将其包含为#include "base_c/base_c.h"。这引入了一种"命名空间" to header,防止来自不同项目的具有相同名称的标题出现问题。

答案 1 :(得分:1)

正如@Anedar所提到的,要解决这种情况,需要target_include_directories PUBLICINTERFACE库中的CMakeLists.txt选项。填充库目标的INTERFACE_INCLUDE_DIRECTORIEStarget_link_libraries在消费方使用。

我的工作配置:

/my_project/CMakeLists.txt

cmake_minimum_requared(VERSION 3.8)
project(my_project)

add_subdirectory(utils)

add_executable(main main.c)
target_link_libraries(main utils base_c base_cpp)

/my_project/utils/CMakeLists.txt

add_subdirectory(base_c)
add_subdirectory(base_cpp)

add_library(utils)
target_sources(utils PUBLIC common.h)
target_include_directories(utils INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

/my_project/utils/base_c/CMakeLists.txt

add_library(base_c base_c.c)
target_sources(base_c PUBLIC base_c.h)
target_include_directories(base_c INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

/my_project/utils/base_cpp/CMakeLists.txt

add_library(base_cpp base_cpp.cpp)
target_sources(base_cpp PUBLIC base_cpp.hpp)
target_include_directories(base_cpp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})

target_link_libraries(base_cpp base_c)