我有一个包含多个模块的 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/