-
Notifications
You must be signed in to change notification settings - Fork 11
/
CMakeLists.txt
311 lines (263 loc) · 11.3 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
cmake_minimum_required(VERSION 3.20)
## Uncomment to output a dump of every CMake variable
# set(CMAKE_MESSAGE_LOG_LEVEL DEBUG)
if(NOT CMAKE_TOOLCHAIN_FILE)
# define toolchain file early for vcpkg. only set the variable if the file exists.
# if this is the first configuration after a clean clone of this repo, this file
# won't exist until the submodule is initialized below. configuration will fail if this
# is set to a path that doesn't exist, so only set it after the first pass of configuration
set(toolchain_file_path "${CMAKE_CURRENT_SOURCE_DIR}/extern/vcpkg/scripts/buildsystems/vcpkg.cmake")
if (EXISTS "${toolchain_file_path}")
set(CMAKE_TOOLCHAIN_FILE "${toolchain_file_path}")
endif()
endif()
project(roguelite LANGUAGES C CXX)
set(gdextension_lib_name ${PROJECT_NAME})
string(TOLOWER "${CMAKE_SYSTEM_NAME}" host_os)
set(VCPKG_TARGET_TRIPLET "x64-${host_os}-static")
# needs to be >= C++17
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_COLOR_DIAGNOSTICS ON)
# define output paths for gdextension shared lib and debug symbols
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/project/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/project/bin")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/project/bin")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/project/bin")
set(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/project/bin")
# postfix debug binaries with "d"
set(CMAKE_DEBUG_POSTFIX "d")
# =======================================================================
# Godot Engine and C++ bindings submodule management
# =======================================================================
# confirm we found the godot engine source files.
# if the sources list is empty, the submodule probably
# hasn't been initialized or updated yet.
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-cpp/src")
message(NOTICE "godot-cpp bingings source not found")
message(NOTICE "initializing/updating the godot-cpp submodule...")
# update the c++ bingings submodule to populate it with
# the necessary source for the gdextension library
execute_process(
COMMAND git submodule update --init extern/godot-cpp
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
endif()
# confirm we found the godot engine source files.
# if the sources list is empty, the submodule probably
# hasn't been initialized or updated yet.
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/core")
message(NOTICE "Godot engine sources not found")
message(NOTICE "initializing/updating the engine submodule...")
# update the engine submodule to populate it with the
# code necessary to build a debug version of the editor that
# can be easily debugged along with the gdextension library
execute_process(
COMMAND git submodule update --init extern/godot-engine
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
endif()
# confirm we found the vcpkg submodule ports dir.
# if the sources list is empty, the submodule probably
# hasn't been initialized or updated yet.
if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/extern/vcpkg/ports")
message(NOTICE "VCPKG package manager sources not found")
message(NOTICE "initializing/updating the vcpkg submodule...")
# update the vcpkg submodule to populate it with the code necessary
# to grab all dependencies needed for the gdextension library build
execute_process(
COMMAND git submodule update --init extern/vcpkg
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND_ERROR_IS_FATAL ANY
)
endif()
# =======================================================================
# VCPKG bootstrap / initialization.
# Only happens once, when vcpkg.exe is missing.
# =======================================================================
set(vcpkg_executable "${CMAKE_CURRENT_SOURCE_DIR}/extern/vcpkg/vcpkg${CMAKE_EXECUTABLE_SUFFIX}")
if(EXISTS "${vcpkg_executable}")
message(NOTICE "Found VCPKG Executable: ${vcpkg_executable}")
else()
message(NOTICE "Could not find VCPKG Executable: ${vcpkg_executable}")
message(NOTICE "Calling VCPKG bootstrap scripts.")
# bootstrap vcpkg to configured and install
if(WIN32)
execute_process(
COMMAND ps -c "./extern/vcpkg/bootstrap-vcpkg.bat"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND_ERROR_IS_FATAL ANY
)
elseif(UNIX)
execute_process(
COMMAND bash "./extern/vcpkg/bootstrap-vcpkg.sh"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND_ERROR_IS_FATAL ANY
)
endif()
# fail out if vcpkg isn't found after setup
if(NOT EXISTS "${vcpkg_executable}")
message(FATAL_ERROR "ERROR: '${vcpkg_executable}' not found!")
endif()
endif()
# =======================================================================
# Godot editor/engine debug build
# =======================================================================
set(host_os_engine "${host_os}")
if(UNIX)
set(host_os_engine "${host_os}bsd")
endif()
set(godot_debug_editor_executable
"${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/bin/godot.${host_os_engine}.editor.dev.x86_64${CMAKE_EXECUTABLE_SUFFIX}"
)
message(NOTICE "godot_debug_editor_executable = ${godot_debug_editor_executable}")
if(NOT EXISTS "${godot_debug_editor_executable}")
message("Godot engine debug binaries not found, invoking debug build of engine...")
execute_process(
COMMAND scons platform=${host_os} arch=x64 target=editor use_static_cpp=yes dev_build=yes debug_symbols=yes optimize=none use_lto=no --clean
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine"
COMMAND_ERROR_IS_FATAL ANY
)
# this build should only ever need to be run once (unless the enging debug binaries
# are deleted or you want to change the build configuration/command invoked below).
execute_process(
COMMAND scons platform=${host_os} arch=x64 target=editor use_static_cpp=yes dev_build=yes debug_symbols=yes optimize=none use_lto=no use_lto=no
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine"
COMMAND_ERROR_IS_FATAL ANY
)
# not necessary, the temp file in here just confuses Visual Studio
file(REMOVE_RECURSE "${CMAKE_CURRENT_SOURCE_DIR}}/extern/godot-engine/.sconf_temp")
if(NOT EXISTS "${godot_debug_editor_executable}")
message(FATAL_ERROR "Couldn't find godot debug executable after scons build: ${godot_debug_editor_executable}")
endif()
endif()
# =======================================================================
# 3rd party library setup/configuration (leverages vcpkg)
# =======================================================================
find_package(fmt CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
# =======================================================================
# Godot C++ bindings library setup/configuration
# =======================================================================
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-cpp)
# =======================================================================
# Godot engine library setup/configuration.
# Not necessary, just provides better support in multiple IDEs
# for engine source code browsing, intellisense, and debugging
# =======================================================================
# populate source file list for the godot engine submodule
file(GLOB_RECURSE godot_engine_sources CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/*.[hc]"
"${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/*.[hc]pp"
)
# add the engine sources as a library so intellisense actually works
add_library(godot_engine EXCLUDE_FROM_ALL ${godot_engine_sources})
target_include_directories(godot_engine PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine"
"${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/platform/windows"
"${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/thirdparty/zlib"
"${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/thirdparty/vulkan/include"
SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/thirdparty/zstd"
SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-engine/thirdparty/mbedtls/include"
)
# define a bunch of the same symbol definitions
# used when the engine was build using scons
target_compile_definitions(godot_engine PUBLIC
$<$<CONFIG:Debug>:
DEBUG_ENABLED
DEBUG_METHODS_ENABLED
DEV_ENABLED
>
NOMINMAX
TOOLS_ENABLED
NO_EDITOR_SPLASH
WINDOWS_ENABLED
WASAPI_ENABLED
WINMIDI_ENABLED
TYPED_METHOD_BIND
VULKAN_ENABLED
GLES3_ENABLED
MINIZIP_ENABLED
BROTLI_ENABLED
ZSTD_STATIC_LINKING_ONLY
USE_VOLK
VK_USE_PLATFORM_WIN32_KHR
GLAD_ENABLED
GLES_OVER_GL
)
# =======================================================================
# GDExtension dynamic library setup/configuration
# =======================================================================
# create gdextension dynamic lib from the project src
file(GLOB_RECURSE roguelite_sources CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.[hc]"
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.[hc]pp"
)
# add the gdextension dynamic library
add_library(${gdextension_lib_name} SHARED ${roguelite_sources})
set(compiler_is_clang "$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>")
set(compiler_is_gnu "$<CXX_COMPILER_ID:GNU>")
set(compiler_is_msvc "$<CXX_COMPILER_ID:MSVC>")
include("${CMAKE_CURRENT_SOURCE_DIR}/extern/godot-cpp/cmake/GodotCompilerWarnings.cmake")
# set compiler options for the gdextension library
target_compile_options(${gdextension_lib_name} PUBLIC
$<${compiler_is_msvc}:
/EHsc
/utf-8
/Zc:preprocessor
$<$<CONFIG:Debug>:
/MDd
>
$<$<CONFIG:Release>:
/MD
/O2
>
>
$<$<NOT:${compiler_is_msvc}>:
-g
-Wno-unused-value
$<${compiler_is_gnu}:
-Wno-attributes=rl::
>
$<${compiler_is_clang}:
-Wno-unknown-attributes
>
$<$<CONFIG:Debug>:
-fno-omit-frame-pointer
-O0
>
$<$<CONFIG:Release>:
-O3
>
>
)
target_include_directories(${gdextension_lib_name} PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/src"
)
target_link_options(${gdextension_lib_name} PRIVATE
$<$<NOT:${compiler_is_msvc}>:
-static-libgcc
-static-libstdc++
-Wl,-R,'$$ORIGIN'
>
)
# =======================================================================
# Dependency linkage
# =======================================================================
# link gdextension to the cpp bindings library
target_link_libraries(${gdextension_lib_name}
PUBLIC godot::cpp
PRIVATE fmt::fmt
PRIVATE fmt::fmt-header-only
PRIVATE spdlog::spdlog_header_only
)
# =======================================================================
# Print configuration report
# =======================================================================
include(${CMAKE_SOURCE_DIR}/scripts/cmake/utils.cmake)
print_project_variables()