c++ - 库 header 在 header 中不可见,但在 cmake 构建下的 .cpp 文件中完全可见。为什么?

标签 c++ cmake

我有一个包含多个模块的 C++ 项目,其中一些构建为库,具有这样的结构:

/MyProject
 +---/build 
     /ModuleA 
      +---CMakeLists.txt        <- module level CMakeLists
      +---/src
      |     +--CMakeLists.txt   <- src level CMakeLists
      |     +--FileA1.cpp
      |     +--FileA2.cpp
      +---/include
      |     +--FileA1.h
      |     +--FileA2.h
      |     +--FileA3.h
      /ModuleB
      +---CMakeLists.txt
      +---/src
      |     +--CMakeLists.txt
      |     +--FileB1.cpp
      |     +--FileB2.cpp
      +---/include
      |     +--FileB1.h
      |     +--FileB2.h
      |     +--FileB3.h
      main.cpp
      CMakeLists.txt            <- project level CMakeLists

CMakeLists.txt 文件如下所示:

项目级别:

cmake_minimum_required(VERSION 3.05)
project(MyProject)
subdirs(ModuleA ModuleB)   
set(CMAKE_CXX_STANDARD 11) 
add_executable(MyProject main.cpp)
target_link_libraries(MyProject ModuleA ModuleB)

模块级别:

subdirs(src)

源级别:

FIND_PACKAGE(SomePackage REQUIRED) 
INCLUDE_DIRECTORIES(
        ${SomePackage_INCLUDE_DIR}
        ${MyProject_SOURCE_DIR}/ModuleA/include
)       
SET(SOURCE_FILES <all files from ModuleA/src goes here>)
ADD_LIBRARY(ModuleA STATIC ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(ModuleA
        ${SomePackage_LIBRARIES}
)

问题是:当我在我的 ModuleA 头文件(即 FileA1.h 中的 SomePackageFile.hpp)中包含来自“SomePackage”的头文件时,我在使用 make 运行构建时遇到错误:

fatal error :SomePackageFile.hpp:没有那个文件或目录

当我将它们包含在 cpp 文件中时,它们是可见的并且项目可以正确编译。我认为 CMakeLists 在 src 级别或整个文件层次结构中缺少某些东西是错误的。

最佳答案

我有一个 github 项目用作其他项目的骨架:

https://github.com/gnyiri/cmake-sandbox

如果您遵循此布局,则无需将 ${SomePackage_INCLUDE_DIR} 添加到 INCLUDE_DIRECTORIES,否则这不是将目录添加到包含路径的最佳方式。

简而言之,您应该像这样定义一个新库:

project(module_a)

set(sources
  src/source_a_1.cc
)

add_library(library_a
  ${sources}
)

target_include_directories(library_a
  PUBLIC
    $<INSTALL_INTERFACE:include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

那么,如果再定义一个库(library_b),只需要在target_link_libraries中加入library_a即可:

project(module_b)

# set list of sources, needs to be extended when new source arrives
set(sources
  src/source_b_1.cc
)

# define a library (static by default -> liblibrary_b.a or library_a.lib will be generated)
add_library(library_b
  ${sources}
)

# include directories
target_include_directories(library_b
  PUBLIC
    $<INSTALL_INTERFACE:include>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
)

# link library_b
target_link_libraries(library_b
  library_a
)

注意在这个源码树中,所有的头文件都位于

<module>/include/<module>

这样您将包含一个头文件,如下所示:

#include "<module>/<module_header.h>"

这只是因为/include 将在包含路径上。

关于c++ - 库 header 在 header 中不可见,但在 cmake 构建下的 .cpp 文件中完全可见。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52974633/

相关文章:

c++ - 使用 Cmake 和 QtCreator 时 undefined reference

cmake - 我如何使用cmake --build建立多个目标

c - 自动生成自定义C库的头文件

c++ - 线程安全的 FIFO/队列(多个生产者,一个消费者)

C++设置以对为键的排序

c++ - 在 ubuntu 16.04 中安装 Caffe 时遇到困难

c++ - 我想知道这个原因和解决方法

c++ - 使用 CMake 在可执行文件中嵌入二进制数据

c++ - 使用 Boost Hana 反射(reflect) C 风格数组

c++ - 如何读取用 std::ofstream 保存的 OpenCV 矩阵数据?