库标题在标题中不可见,但在 cmake build 下.cpp文件中完全可见.为什么?

Library headers not visible in headers but perfectly visible inside .cpp file under cmake build. Why?

本文关键字:标题 文件 cpp 为什么 但在 cmake build      更新时间:2023-10-16

我有一个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)

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 头文件中包含来自"SomePackage"的头文件(即 FileA1.h 中的 SomePackageFile.hpp 时,我在使用 make 运行构建时出现错误:

致命错误:SomePackageFile.hpp:没有这样的文件或目录

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

我有一个 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 将位于包含路径上。

从 INCLUDE_DIRECTORIES(( 切换到 TARGET_INCLUDE_DIRECTORIES(( 是这种情况,不需要更改项目的结构。