繁体   English   中英

具有多个目录的大型项目的 CMakeLists?

[英]CMakeLists for large project with multiple directories?

我正在编写一个游戏引擎,进展非常顺利。 但是我遇到了一个问题,我的 CMakeLists.txt 太乱了,而且我对 CMake 还不够了解。 我的项目使用多个(CMake)库,这些库是使用 add_subdirectory 和 target_link_libraries 添加的。 我的项目由引擎(可执行文件)、编辑器(库)和一些测试/示例组成。 这是我的文件结构:

C:.
|   CMakeLists.txt
|   tree.txt
|   
+---Editor
|   |   README.md
|   |   
|   \---src
|           main.cpp
|           
+---Engine
|   |   README.md
|   |   
|   +---src
|   |   |   main.cpp
|   |   |   
|   |   +---API
|   |   |       Core.h
|   |   |       
|   |   +---App
|   |   |       Application.cpp
|   |   |       
|   |   +---ExtApp
|   |   |   |   AppInterface.cpp
|   |   |   |   
|   |   |   +---Engine
|   |   |   |       ExtAppLoader.cpp
|   |   |   |       
|   |   |   \---Game
|   |   |           InfoExport.cpp
|   |   |           
|   |   +---Framework
|   |   |       Asset.cpp
|   |   |       
|   |   +---Managing
|   |   |       AssetLoader.cpp
|   |   |       
|   |   +---Rendering
|   |   |   |   Renderer.cpp
|   |   |   |   
|   |   |   \---Renderables
|   |   |           Canvas2DRenderable.cpp
|   |   |           
|   |   \---Types
|   |           Vector3f.cpp
|   |           
|   \---TestResources
|       \---Shaders
|               Canvas2DTexturedTriangle.f
|               Canvas2DTexturedTriangle.v
|               Canvas2DUntexturedTriangle.f
|               Canvas2DUntexturedTriangle.v
|               ImTest.f
|               ImTest.v
|               
+---Libraries
|   +---glfw
|   |       CMakeLists.txt
|   |       
|   \---glm
|           CMakeLists.txt
|           
\---Tests
    \---TestGame
        \---src
                main.cpp

正如你所看到的,我在开始时有一个 CMakeLists,它加载了所有的项目。 然后我有库,其中也有 CMakeLists。 每个目录只有一个文件,使树变小,但一个目录中有多个文件。 另外,这是我当前的、凌乱的、几乎无用的 CMakeLists 文件:

    cmake_minimum_required(VERSION 3.6)

#project(3DEngine)



add_subdirectory(Libraries/glfw) #Add glfw to the project

# Make sure we're running C++17 so all features(like std::filesystem) are present.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

option(BUILD_ENGINE_FOR_EDITOR "Build the engine as DLL/SO for the editor and add editor specific things. Otherwise build engine as game exec" OFF)
option(BUILD_ENGINE_FOR_DLL_APPS "Have the Engine load the game(and plugins) from dll's." ON)
project (Engine)#project engine
include_directories(Libraries/whereami/src)
include_directories(Engine/src/)
include_directories(Libraries/glfw/include)
include_directories(Libraries/glm)
include_directories(Libraries/glad/include)
include_directories(Libraries/stb)
file(GLOB EngineRootSOURCES  "Engine/src/*.cpp" "Engine/src/*.h")
file(GLOB EngineRenderingSOURCES  "Engine/src/Rendering/*.cpp" "Engine/src/Rendering/*.h")
file(GLOB EngineAppSOURCES  "Engine/src/App/*.cpp" "Engine/src/App/*.h")
file(GLOB EngineRenderingRenderablesSOURCES  "Engine/src/Rendering/Renderables/*.cpp" "Engine/src/Rendering/Renderables/*.h")
file(GLOB EngineManagingSOURCES  "Engine/src/Managing/*.cpp" "Engine/src/Managing/*.h")
file(GLOB EngineTypesSOURCES  "Engine/src/Types/*.cpp" "Engine/src/Types/*.h")
file(GLOB EngineGameEssentialsSOURCES  "Engine/src/GameEssentials/*.cpp" "Engine/src/GameEssentials/*.h")
file(GLOB EngineLibsSOURCES  "Libraries/whereami/src/whereami.c" "Libraries/glad/src/glad.c")
file(GLOB EngineFrameworkSOURCES  "Engine/src/Framework/*.h" "Engine/src/Framework/*.cpp")
file(GLOB APISOURCES  "Engine/src/API/*.cpp" "Engine/src/API/*.h")

file(GLOB EngineExtAppSOURCES "Engine/src/ExtApp/*.cpp" "Engine/src/ExtApp/*.h"
 "Engine/src/ExtApp/Interface/*.cpp" "Engine/src/ExtApp/Interface/*.h")

 file(GLOB EngineExtAppGameSOURCES "Engine/src/ExtApp/Game/*.cpp" "Engine/src/ExtApp/Game/*.h")
 source_group("ExtApp"  FILES ${EngineExtAppGameSOURCES})

 file(GLOB EngineExtAppEngineSOURCES "Engine/src/ExtApp/Engine/*.cpp" "Engine/src/ExtApp/Engine/*.h")
 source_group("ExtApp"  FILES ${EngineExtAppEngineSOURCES})

if(BUILD_ENGINE_FOR_EDITOR)
file(GLOB EngineEditorSOURCES "Engine/src/ExtApp/*.cpp" "Engine/src/ExtApp/*.h"
 "Engine/src/ExtApp/Interface/*.cpp" "Engine/src/ExtApp/Interface/*.h")


 if(BUILD_ENGINE_FOR_DLL_APPS)

 add_library(Engine SHARED ${EngineRootSOURCES} ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineEditorSOURCES} ${EngineExtAppSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppEngineSOURCES} ${EngineFrameworkSOURCES})
 source_group("ExtApp"  FILES ${EngineExtAppSOURCES})
elseif(NOT BUILD_ENGINE_FOR_DLL_APPS)
add_library(Engine SHARED ${EngineRootSOURCES} ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineEditorSOURCES} ${EngineExtAppSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppEngineSOURCES} ${EngineFrameworkSOURCES})
endif()



target_link_libraries(Engine glfw)
source_group("Rendering"  FILES ${EngineRenderingSOURCES})
source_group("Rendering/Renderables"  FILES ${EngineRenderingRenderablesSOURCES})
source_group("Managing"  FILES ${EngineManagingSOURCES})
source_group("App"  FILES ${EngineAppSOURCES})
source_group("Types"  FILES ${EngineTypesSOURCES})
source_group("GameEssentials"  FILES ${EngineGameEssentialsSOURCES})
source_group("Libs"  FILES ${EngineLibsSOURCES})
source_group("ExtApp"  FILES ${EngineEditorSOURCES})
source_group("API"  FILES ${APISOURCES})
source_group("Framework"  FILES ${EngineFrameworkSOURCES})
elseif(NOT BUILD_ENGINE_FOR_EDITOR)


if(BUILD_ENGINE_FOR_DLL_APPS)
file(GLOB EngineExtAppSOURCES "Engine/src/ExtApp/*.cpp" "Engine/src/ExtApp/*.h"
 "Engine/src/ExtApp/Interface/*.cpp" "Engine/src/ExtApp/Interface/*.h")
 add_executable(Engine ${EngineRootSOURCES} ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineExtAppSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppEngineSOURCES} ${EngineFrameworkSOURCES})
 source_group("ExtApp"  FILES ${EngineExtAppSOURCES})
elseif(NOT BUILD_ENGINE_FOR_DLL_APPS)
add_executable(Engine ${EngineRootSOURCES} ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineExtAppSOURCES} ${EngineAppSOURCES} ${APISOURCES} ${EngineExtAppEngineSOURCES} ${EngineFrameworkSOURCES})
endif()



target_link_libraries(Engine glfw)
source_group("Rendering"  FILES ${EngineRenderingSOURCES})
source_group("Rendering/Renderables"  FILES ${EngineRenderingRenderablesSOURCES})
source_group("Managing"  FILES ${EngineManagingSOURCES})
source_group("App"  FILES ${EngineAppSOURCES})
source_group("Types"  FILES ${EngineTypesSOURCES})
source_group("GameEssentials"  FILES ${EngineGameEssentialsSOURCES})
source_group("Libs"  FILES ${EngineLibsSOURCES})
source_group("API"  FILES ${APISOURCES})
source_group("Framework"  FILES ${EngineFrameworkSOURCES})
endif()

#add_library(Engine SHARED ${EngineSOURCES})
## END project engine

project (Module_OpenGL_Renderer_Input)#project module_renderer_opengl3
include_directories(Libraries/glfw/include)
include_directories(Libraries/glm)
include_directories(Libraries/glad/include)
include_directories(Libraries/stb)
file(GLOB Module_OpenGL_Renderer_InputSOURCES "Modules/Module_OpenGL_Renderer_Input/src/*.cpp" "Modules/Module_OpenGL_Renderer_Input/src/*.h" "Libraries/glad/src/glad.c")
add_library(Module_OpenGL_Renderer_Input SHARED ${Module_OpenGL_Renderer_InputSOURCES})
target_link_libraries(glfw)
##END project module_renderer_opengl3

project (Test1)#project test  |  This project is used to test the engine functionality.
include_directories(Libraries/imgui)
file(GLOB Test1SOURCES "Tests/Test1/src/*.cpp" "Tests/Test1/src/*.h" "Libraries/imgui/imgui*.cpp"  ${APISOURCES})
add_executable(Test1 ${Test1SOURCES})
target_link_libraries(Test1 ${CMAKE_DL_LIBS})

project (TestGame)#project test  |  This project is used to test the engine functionality.
include_directories(Libraries/imgui)
file(GLOB TestGameSOURCES "Tests/TestGame/src/*.cpp" "Tests/TestGame/src/*.h" "Libraries/imgui/imgui*.cpp" ${EngineRenderingSOURCES} ${EngineTypesSOURCES} ${EngineRenderingRenderablesSOURCES} ${EngineManagingSOURCES} ${EngineGameEssentialsSOURCES} ${EngineLibsSOURCES} ${EngineAppSOURCES}  ${APISOURCES} ${EngineExtAppSOURCES} ${EngineExtAppGameSOURCES}  ${EngineFrameworkSOURCES})
add_library(TestGame SHARED ${TestGameSOURCES})
target_link_libraries(TestGame glfw)

project (Editor)#project editor  |  This is used to make projects and build projects(using the engine)
include_directories(Libraries/imgui)
file(GLOB EditorSOURCES "Editor/src/*.cpp" "Editor/src/*.h" "Libraries/imgui/imgui*.cpp"  ${APISOURCES})
add_executable(Editor ${EditorSOURCES})

我包含了很多完全没用或不再需要的东西。 所以这里是我的问题:

  1. 是否每个目录都需要一个 CMakeLists 文件,就像我在很多项目中看到的那样?
  2. 我是否需要提供包含源文件的每个目录,还是可以让它自动搜索目录中的源文件和头文件?
  3. 我还看到很多其他 CMake 项目分别提供每个源/头文件,为什么? 每次添加文件时,这不是很多工作吗?
  4. 有没有人有我可以用作指南的大型 CMake 项目的示例?
  5. 还有什么我可以改进的吗?

谢谢!

  1. 是否每个目录都需要一个 CMakeLists 文件

不,那没有必要。

为每个子模块和库创建一个 CMakeLists.txt 可能是一个好主意 - 并在项目本身的根目录中创建一个。

  1. 我是否需要提供包含源文件的每个目录,还是可以让它自动搜索目录中的源文件和头文件?

首先,请参阅您的问题 3 的答案。

其次,我不明白您为什么要搜索头文件。 只需指定包含目录。

最后,如果您想使用 globbing,可以将所有源文件放在一个目录下,并使用单个 glob。

  1. 我还看到许多其他 CMake 项目分别提供每个源...文件,为什么?

这是文档所说的:

笔记

我们不建议使用 GLOB 从源树中收集源文件列表。 如果在添加或删除源时没有 CMakeLists.txt 文件更改,则生成的构建系统无法知道何时要求 CMake 重新生成。 CONFIGURE_DEPENDS 标志可能无法在所有生成器上可靠地工作,或者如果将来添加了不能支持它的新生成器,使用它的项目将被卡住。 即使 CONFIGURE_DEPENDS 工作可靠,在每次重建时执行检查仍然存在成本。


  1. ...每个头文件分开,为什么?

我从来没有见过这个。

  1. 还有什么我可以改进的吗?

使用target_include_directories而不是include_directories 通常,始终使用target_X指令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM