CMake 源文件找不到头文件

CMake source files cannot find header files

本文关键字:文件 找不到 源文件 CMake      更新时间:2023-10-16

我有一个项目,我使用具有以下结构的CMake:

CMakeLists.txt
├── build
├── include
│   ├── AudioDevice.h
│   ├── Game.h
│   ├── game_objects
│   │   ├── Ball.h
│   │   ├── Brick.h
│   │   ├── GameObject.h
│   │   ├── IndestructibleBrick.h
│   │   ├── MoveableGameObject.h
│   │   ├── Physics.h
│   │   ├── Platform.h
│   │   └── Wall.h
│   ├── GameParameter.h
│   ├── InputHandler.h
│   ├── Level.h
│   ├── Renderer.h
│   └── SDL_RAII.h
├── src
│   ├── AudioDevice.cpp
│   ├── Game.cpp
│   ├── game_objects
│   │   ├── Ball.cpp
│   │   ├── Brick.cpp
│   │   ├── GameObject.cpp
│   │   ├── MoveableGameObject.cpp
│   │   ├── Physics.cpp
│   │   └── Platform.cpp
│   ├── GameParameter.cpp
│   ├── InputHandler.cpp
│   ├── Level.cpp
│   ├── main.cpp
│   ├── Renderer.cpp
│   └── SDL_RAII.cpp
├── test
│   ├── game_objects
│   │   ├── Ball_test.cpp
│   │   ├── Brick_test.cpp
│   │   ├── GameObject_test.cpp
│   │   ├── MoveableGameObject_test.cpp
│   │   ├── Physics_test.cpp
│   │   └── Platform_test.cpp
│   └── Level_test.cpp

现在我想改进使用 CMake 组织项目的方式。目前我在根目录中只有一个CMakeLists.txt。好的做法应该是将其放在每个文件夹中。

我在根目录中的CMakeLists.txt目前如下所示:

cmake_minimum_required(VERSION 3.7)
add_definitions(-std=c++17)
set(CXX_FLAGS "-Wall")
set(CMAKE_CXX_FLAGS, "${CXX_FLAGS}")
set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,readability-*)
project(bricks)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
set(LIBRARY_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/lib")
#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
find_package(SDL2 REQUIRED)
find_package(SDL2_mixer REQUIRED)
include_directories(
${SDL2_INCLUDE_DIRS} 
${SDL2_mixer_INCLUDE_DIRS} 
include 
include/game_objects
include/types
include/utility 
)
add_subdirectory(thirdparty/googletest)
add_executable(bricks 
src/game_objects/Ball.cpp
src/game_objects/Brick.cpp
src/game_objects/GameObject.cpp
src/game_objects/MoveableGameObject.cpp
src/game_objects/Physics.cpp
src/game_objects/Platform.cpp
src/AudioDevice.cpp
src/Game.cpp
src/GameParameter.cpp
src/InputHandler.cpp
src/Level.cpp
src/main.cpp
src/Renderer.cpp
src/SDL_RAII.cpp
)
target_link_libraries(
bricks 
SDL2::Main
SDL2::Mixer
)
add_executable(test 
test/game_objects/Ball_test.cpp
src/game_objects/Ball.cpp
test/game_objects/Brick_test.cpp
src/game_objects/Brick.cpp
test/game_objects/GameObject_test.cpp
src/game_objects/GameObject.cpp
test/game_objects/MoveableGameObject_test.cpp
src/game_objects/MoveableGameObject.cpp
test/game_objects/Physics_test.cpp
src/game_objects/Physics.cpp
test/game_objects/Platform_test.cpp
src/game_objects/Platform.cpp
# needs to be added so linker works with level
src/GameParameter.cpp
test/Level_test.cpp
src/Level.cpp
)
target_link_libraries(test 
gtest_main 
)

现在我认为作为第一步,最好将文件夹中的内容放在自己的CMakeLists.txtsrc

所以我的根文件变成了这个:

cmake_minimum_required(VERSION 3.7)
add_definitions(-std=c++17)
set(CXX_FLAGS "-Wall")
set(CMAKE_CXX_FLAGS, "${CXX_FLAGS}")
set(CMAKE_CXX_CLANG_TIDY clang-tidy -checks=-*,readability-* -fix)
project(bricks)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
set(LIBRARY_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/lib")
#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
find_package(SDL2 REQUIRED)
find_package(SDL2_mixer REQUIRED)
add_subdirectory(src)
add_subdirectory(thirdparty/googletest)
add_executable(test 
test/game_objects/Ball_test.cpp
src/game_objects/Ball.cpp
test/game_objects/Brick_test.cpp
src/game_objects/Brick.cpp
test/game_objects/GameObject_test.cpp
src/game_objects/GameObject.cpp
test/game_objects/MoveableGameObject_test.cpp
src/game_objects/MoveableGameObject.cpp
test/game_objects/Physics_test.cpp
src/game_objects/Physics.cpp
test/game_objects/Platform_test.cpp
src/game_objects/Platform.cpp
src/GameParameter.cpp
test/Level_test.cpp
src/Level.cpp
)
target_link_libraries(test 
gtest_main 
)

我在src创建了这个文件:

include_directories(
${SDL2_INCLUDE_DIRS} 
${SDL2_mixer_INCLUDE_DIRS} 
../include 
../include/game_objects
../include/types
../include/utility 
)
add_executable(bricks 
game_objects/Ball.cpp
game_objects/Brick.cpp
game_objects/GameObject.cpp
game_objects/MoveableGameObject.cpp
game_objects/Physics.cpp
game_objects/Platform.cpp

AudioDevice.cpp
Game.cpp
GameParameter.cpp
InputHandler.cpp
Level.cpp
main.cpp
Renderer.cpp
SDL_RAII.cpp
)
target_link_libraries(
bricks 
SDL2::Main
SDL2::Mixer
)

现在当我运行 CMake 时,它不起作用。我在Ball.cpp和其他文件中收到投诉,说它找不到头文件。我以为我用include_directories添加了它们.

我真的不知道这里发生了什么。我已经在谷歌上搜索了这个问题,但找不到解决方案。

如果有人能给我一个提示如何很好地重组,我将不胜感激。

include_directories()命令将列出的包含目录应用于当前 CMake 文件中的目标以及子目录中的目标。因此,include_directories()命令不会将包含目录应用于顶级 CMake 文件中的test目标。因此,为test可执行文件列出的源将不知道您列出的包含目录。一个简单的解决方法是简单地将include_directories()调用移动到顶级 CMake 文件:

... 
include_directories(
${SDL2_INCLUDE_DIRS} 
${SDL2_mixer_INCLUDE_DIRS} 
${CMAKE_SOURCE_DIR}/include 
${CMAKE_SOURCE_DIR}/include/game_objects
${CMAKE_SOURCE_DIR}/include/types
${CMAKE_SOURCE_DIR}/include/utility 
)
add_subdirectory(src)
add_subdirectory(thirdparty/googletest)
add_executable(test 
test/game_objects/Ball_test.cpp
src/game_objects/Ball.cpp
test/game_objects/Brick_test.cpp
src/game_objects/Brick.cpp
test/game_objects/GameObject_test.cpp
src/game_objects/GameObject.cpp
test/game_objects/MoveableGameObject_test.cpp
src/game_objects/MoveableGameObject.cpp
test/game_objects/Physics_test.cpp
src/game_objects/Physics.cpp
test/game_objects/Platform_test.cpp
src/game_objects/Platform.cpp
src/GameParameter.cpp
test/Level_test.cpp
src/Level.cpp
)
target_link_libraries(test 
gtest_main 
)

还应使用变量CMAKE_SOURCE_DIR获取顶级 CMake 文件的完整路径,以避免使用相对路径。


FWIW,我不知道有任何指南声称您应该在项目的每个子目录中都有一个CMakeLists.txt文件。在项目层次结构中构建 CMakeLists.txt 文件的方式显然取决于文件在文件系统中的布局方式、您希望每个 CMakeLists.txt文件的长度以及其他设计决策。对于大型项目,我已经看到每个目标有一个CMakeLists.txt文件是很常见的。