CMakeLists для большого проекта с несколькими каталогами? - PullRequest
0 голосов
/ 24 октября 2018

Я пишу игровой движок, который работает очень хорошо.Но я сталкиваюсь с проблемой, когда мой CMakeLists.txt слишком грязный, и я не знаю достаточно о CMake.Мой проект использует несколько (CMake) библиотек, которые добавляются с использованием add_subdirectory, а затем target_link_libraries.Мой проект состоит из Engine (исполняемый файл), Editor (библиотека) и некоторых тестов / примеров.Вот моя файловая структура:

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 Ответ

0 голосов
/ 24 октября 2018
  1. Нужен ли каждому каталогу файл CMakeLists

Нет, в этом нет необходимости.

Вероятно, хорошая идея иметь CMakeLists.txt для каждого подмодуля и библиотеки - и один в корне для самого проекта.

Нужно ли указывать каждый каталог, содержащий исходные файлы, или он может автоматически искать исходные файлы и файлы заголовков в каталогах?

Во-первых, см. Ответ на ваш вопрос 3.

Во-вторых, я не понимаю, зачем вам искать файлы заголовков.Просто укажите включаемые каталоги.

Наконец, если вы хотите использовать подстановку вопреки рекомендациям, можно поместить все исходные файлы в один каталог и использовать один глобус.

Я также вижу, что многие другие проекты CMake предоставляют каждый источник ... файл отдельно, почему?

Поскольку CMake имеет проблемы с глобальным кэшированием и не может перекомпилироваться, когдановые файлы добавлены или старые удалены.Документы CMake гласят:

Примечание

Мы не рекомендуем использовать GLOB для сбора списка исходных файлов из дерева исходных текстов.Если файл CMakeLists.txt не изменяется при добавлении или удалении источника, сгенерированная система сборки не может знать, когда попросить CMake сгенерировать заново.Флаг CONFIGURE_DEPENDS может работать не надежно на всех генераторах, или, если в будущем будет добавлен новый генератор, который не сможет его поддерживать, проекты, использующие его, будут заблокированы.Даже если CONFIGURE_DEPENDS работает надежно, проверка каждой перестройки все равно требует затрат.


... каждый заголовочный файл отдельно, почему?

Я никогда не видел этого.

Есть ли что-нибудь еще, что я могу улучшить?

Используйте target_include_directories вместо include_directories.В общем, всегда используйте директивы target_X.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...