I am writing a Game Engine, which is going very well. But I am running into a problem where my CMakeLists.txt is just too messy, and I don't know enough about CMake. My project uses multiple (CMake) libraries, which are added using add_subdirectory and then target_link_libraries. My project consists of the Engine(executable), the Editor(library), and some tests/examples. Here is my file structure:
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
As you can see I have one CMakeLists at the begin, which loads all the projects. Then I have libraries, which have a CMakeLists too. Every directory has only one file to make the tree less big, but there are multiple fies in a directory. Also, here is my current, messy, almost-useless CMakeLists file:
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})
I contains lot's of things that are completely useless, or not needed anymore. So here are my questions:
- Does every directory NEED a CMakeLists file, like I see in a lot of projects?
- Do I need to provide every directory containing source files, or can I have it search automatically for source and header files in directories?
- I also see that a lot of other CMake projects provide each source/header file seperately, why? Isn't that a lot of work every time you add a file?
- Does anyone have examples of large CMake projects that I can use as a guide?
- Is there ANYTHING else I can improve?
Thanks!