我有一个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级别的CMakeLists方面是错误的,或者整个文件层次结构都缺少某些内容。
答案 0 :(得分:1)
我有一个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路径上。
答案 1 :(得分:0)
确实是从INCLUDE_DIRECTORIES()切换为TARGET_INCLUDE_DIRECTORIES(),无需更改项目结构。