-
-
Notifications
You must be signed in to change notification settings - Fork 751
Expand file tree
/
Copy pathgodotcpp.cmake
More file actions
433 lines (366 loc) · 15.8 KB
/
godotcpp.cmake
File metadata and controls
433 lines (366 loc) · 15.8 KB
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
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
#[=======================================================================[.rst:
godotcpp.cmake
--------------
As godot-cpp is a C++ project, there are no C files, and detection of a C
compiler is unnecessary. When CMake performs the configure process, if a
C compiler is specified, like in a toolchain, or from an IDE, then it will
print a warning stating that the CMAKE_C_COMPILER compiler is unused.
This if statement simply silences that warning.
]=======================================================================]
if(CMAKE_C_COMPILER)
endif()
#[[ Include Platform Files
Because these files are included into the top level CMakeLists.txt before the
project directive, it means that
CMAKE_CURRENT_SOURCE_DIR is the location of godot-cpp's CMakeLists.txt
CMAKE_SOURCE_DIR is the location where any prior project() directive was ]]
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GodotCPPModule.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/common_compiler_flags.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/android.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/ios.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/web.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows.cmake)
# Detect number of processors
include(ProcessorCount)
ProcessorCount(PROC_MAX)
message(STATUS "Auto-detected ${PROC_MAX} CPU cores available for build parallelism.")
# List of known platforms
set(PLATFORM_LIST
linux
macos
windows
android
ios
web
)
# List of known architectures
set(ARCH_LIST
x86_32
x86_64
arm32
arm64
rv64
ppc32
ppc64
wasm32
)
#[=============================[ godot_arch_name ]=============================]
#[[ Function to map CMAKE_SYSTEM_PROCESSOR names to godot arch equivalents ]]
function(godot_arch_name OUTVAR)
# Special case for macos universal builds that target both x86_64 and arm64
if(DEFINED CMAKE_OSX_ARCHITECTURES)
if("x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES AND "arm64" IN_LIST CMAKE_OSX_ARCHITECTURES)
set(${OUTVAR} "universal" PARENT_SCOPE)
return()
endif()
endif()
# Special case for MSVC cross-compilation
if(DEFINED CMAKE_VS_PLATFORM_NAME)
if(CMAKE_VS_PLATFORM_NAME STREQUAL "Win32")
set(${OUTVAR} "x86_32" PARENT_SCOPE)
return()
elseif(CMAKE_VS_PLATFORM_NAME STREQUAL "x64")
set(${OUTVAR} "x86_64" PARENT_SCOPE)
return()
elseif(CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
set(${OUTVAR} "arm64" PARENT_SCOPE)
return()
endif()
endif()
# Direct match early out.
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCH)
if(ARCH IN_LIST ARCH_LIST)
set(${OUTVAR} "${ARCH}" PARENT_SCOPE)
return()
endif()
# Known aliases
set(x86_64 "w64;amd64;x86-64")
set(arm32 "armv7;armv7-a")
set(arm64 "armv8;arm64v8;aarch64;armv8-a")
set(rv64 "rv;riscv;riscv64")
set(ppc32 "ppcle;ppc")
set(ppc64 "ppc64le")
if(ARCH IN_LIST x86_64)
set(${OUTVAR} "x86_64" PARENT_SCOPE)
elseif(ARCH IN_LIST arm32)
set(${OUTVAR} "arm32" PARENT_SCOPE)
elseif(ARCH IN_LIST arm64)
set(${OUTVAR} "arm64" PARENT_SCOPE)
elseif(ARCH IN_LIST rv64)
set(${OUTVAR} "rv64" PARENT_SCOPE)
elseif(ARCH IN_LIST ppc32)
set(${OUTVAR} "ppc32" PARENT_SCOPE)
elseif(ARCH IN_LIST ppc64)
set(${OUTVAR} "ppc64" PARENT_SCOPE)
elseif(ARCH MATCHES "86")
# Catches x86, i386, i486, i586, i686, etc.
set(${OUTVAR} "x86_32" PARENT_SCOPE)
else()
# Default value is whatever the processor is.
set(${OUTVAR} ${CMAKE_SYSTEM_PROCESSOR} PARENT_SCOPE)
endif()
endfunction()
# Function to define all the options.
function(godotcpp_options)
#NOTE: platform is managed using toolchain files.
#NOTE: arch is managed by using toolchain files.
# To create a universal build for macos, set CMAKE_OSX_ARCHITECTURES
set(GODOTCPP_TARGET
"template_debug"
CACHE STRING
"Which target to generate. valid values are: template_debug, template_release, and editor"
)
set_property(CACHE GODOTCPP_TARGET PROPERTY STRINGS "template_debug;template_release;editor")
# Input from user for GDExtension interface header and the API JSON file
set(GODOTCPP_API_VERSION
""
CACHE STRING
"The Godot API version to target (ex \"4.5\") using one of the included API JSON files"
)
set_property(CACHE GODOTCPP_API_VERSION PROPERTY STRINGS ";4.3;4.4;4.5;4.6")
set(GODOTCPP_GDEXTENSION_DIR
"gdextension"
CACHE PATH
"Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )"
)
set(GODOTCPP_CUSTOM_API_FILE
""
CACHE FILEPATH
"Path to a custom GDExtension API JSON file (takes precedence over `GODOTCPP_GDEXTENSION_DIR` and `GODOTCPP_API_VERSION`) ( /path/to/custom_api_file )"
)
#TODO generate_bindings
option(GODOTCPP_GENERATE_TEMPLATE_GET_NODE "Generate a template version of the Node class's get_node. (ON|OFF)" ON)
#TODO build_library
set(GODOTCPP_PRECISION "single" CACHE STRING "Set the floating-point precision level (single|double)")
set(GODOTCPP_THREADS ON CACHE BOOL "Enable threading support")
#TODO compiledb
#TODO compiledb_file
set(GODOTCPP_BUILD_PROFILE "" CACHE PATH "Path to a file containing a feature build profile")
set(GODOTCPP_USE_HOT_RELOAD "" CACHE BOOL "Enable the extra accounting required to support hot reload. (ON|OFF)")
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
# saves around 20% of binary size and very significant build time (GH-80513).
option(GODOTCPP_DISABLE_EXCEPTIONS "Force disabling exception handling code (ON|OFF)" ON)
set(GODOTCPP_SYMBOL_VISIBILITY
"hidden"
CACHE STRING
"Symbols visibility on GNU platforms. Use 'auto' to apply the default value. (auto|visible|hidden)"
)
set_property(CACHE GODOTCPP_SYMBOL_VISIBILITY PROPERTY STRINGS "auto;visible;hidden")
#TODO optimize
option(GODOTCPP_DEPRECATED "Enable compatibility code for deprecated and removed features" ON)
option(GODOTCPP_DEV_BUILD "Developer build with dev-only debugging code (DEV_ENABLED)" OFF)
#[[ debug_symbols
Debug symbols are enabled by using the Debug or RelWithDebInfo build configurations.
Single Config Generator is set at configure time
cmake ../ -DCMAKE_BUILD_TYPE=Debug
Multi-Config Generator is set at build time
cmake --build . --config Debug
]]
# FIXME These options are not present in SCons, and perhaps should be added there.
option(GODOTCPP_SYSTEM_HEADERS "Expose headers as SYSTEM." OFF)
option(GODOTCPP_WARNING_AS_ERROR "Treat warnings as errors" OFF)
# Enable Testing
option(GODOTCPP_ENABLE_TESTING "Enable the godot-cpp.test.<target> integration testing targets" OFF)
#[[ Target Platform Options ]]
android_options()
ios_options()
linux_options()
macos_options()
web_options()
windows_options()
endfunction()
#[===========================[ Target Generation ]===========================]
function(godotcpp_generate)
#[[ Multi-Threaded MSVC Compilation
When using the MSVC compiler the build command -j <n> only specifies
parallel jobs or targets, and not multi-threaded compilation To speed up
compile times on msvc, the /MP <n> flag can be set. But we need to set it
at configure time.
MSVC is true when the compiler is some version of Microsoft Visual C++ or
another compiler simulating the Visual C++ cl command-line syntax. ]]
if(MSVC)
math(EXPR PROC_N "(${PROC_MAX}-1) | (${X}-2)>>31 & 1")
message(STATUS "Using ${PROC_N} cores for multi-threaded compilation.")
# TODO You can override it at configure time with ...." )
else()
if(CMAKE_BUILD_PARALLEL_LEVEL)
set(_cores "${CMAKE_BUILD_PARALLEL_LEVEL}")
else()
set(_cores "all")
endif()
message(
STATUS
"Using ${_cores} cores. You can override"
" this at configure time by using -j <n> or --parallel <n> in the build"
" command."
)
message(STATUS " eg. cmake --build . -j 7 ...")
endif()
#[[ GODOTCPP_SYMBOL_VISIBLITY
To match the SCons options, the allowed values are "auto", "visible", and "hidden"
This effects the compiler flag_ -fvisibility=[default|internal|hidden|protected]
The corresponding target option CXX_VISIBILITY_PRESET accepts the compiler values.
TODO: It is probably worth a pull request which changes both to use the compiler values
.. _flag:https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fvisibility
]]
if(${GODOTCPP_SYMBOL_VISIBILITY} STREQUAL "auto" OR ${GODOTCPP_SYMBOL_VISIBILITY} STREQUAL "visible")
set(GODOTCPP_SYMBOL_VISIBILITY "default")
endif()
# Setup variable to optionally mark headers as SYSTEM
set(GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE "")
if(GODOTCPP_SYSTEM_HEADERS)
set(GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
endif()
#[[ Configure Binding Variables ]]
# Generate Binding Parameters (True|False)
set(USE_TEMPLATE_GET_NODE "False")
if(GODOTCPP_GENERATE_TEMPLATE_GET_NODE)
set(USE_TEMPLATE_GET_NODE "True")
endif()
# Bits (32|64)
math(EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8") # CMAKE_SIZEOF_VOID_P refers to target architecture.
# API json File
set(GODOTCPP_LATEST_API_VERSION "4.6")
if(GODOTCPP_API_VERSION STREQUAL "" OR GODOTCPP_API_VERSION STREQUAL GODOTCPP_LATEST_API_VERSION)
set(GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_GDEXTENSION_DIR}/extension_api.json")
else()
string(REPLACE "." "-" GODOTCPP_API_VERSION_DASHED "${GODOTCPP_API_VERSION}")
set(GODOTCPP_GDEXTENSION_API_FILE
"${GODOTCPP_GDEXTENSION_DIR}/extension_api-${GODOTCPP_API_VERSION_DASHED}.json"
)
endif()
if(GODOTCPP_CUSTOM_API_FILE) # User-defined override.
set(GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_CUSTOM_API_FILE}")
endif()
# Interface json file.
set(GODOTCPP_GDEXTENSION_INTERFACE_FILE "${GODOTCPP_GDEXTENSION_DIR}/gdextension_interface.json")
# Build Profile
if(GODOTCPP_BUILD_PROFILE)
message(STATUS "Using build profile to trim api file")
message(STATUS "\tBUILD_PROFILE = '${GODOTCPP_BUILD_PROFILE}'")
message(STATUS "\tAPI_SOURCE = '${GODOTCPP_GDEXTENSION_API_FILE}'")
build_profile_generate_trimmed_api(
"${GODOTCPP_BUILD_PROFILE}"
"${GODOTCPP_GDEXTENSION_API_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}/extension_api.json"
)
set(GODOTCPP_GDEXTENSION_API_FILE "${CMAKE_CURRENT_BINARY_DIR}/extension_api.json")
endif()
message(STATUS "GODOTCPP_GDEXTENSION_API_FILE = '${GODOTCPP_GDEXTENSION_API_FILE}'")
message(STATUS "GODOTCPP_GDEXTENSION_INTERFACE_FILE = '${GODOTCPP_GDEXTENSION_INTERFACE_FILE}'")
# generate the file list to use
binding_generator_get_file_list( GENERATED_FILES_LIST
"${GODOTCPP_GDEXTENSION_API_FILE}"
"${CMAKE_CURRENT_BINARY_DIR}"
)
binding_generator_generate_bindings(
"${GODOTCPP_GDEXTENSION_API_FILE}"
"${GODOTCPP_GDEXTENSION_INTERFACE_FILE}"
"${USE_TEMPLATE_GET_NODE}"
"${BITS}"
"${GODOTCPP_PRECISION}"
"${CMAKE_CURRENT_BINARY_DIR}"
)
### Platform is derived from the toolchain target
# See GeneratorExpressions PLATFORM_ID and CMAKE_SYSTEM_NAME
string(
CONCAT
SYSTEM_NAME
"$<$<PLATFORM_ID:Android>:android>"
"$<$<PLATFORM_ID:iOS>:ios>"
"$<$<PLATFORM_ID:Linux>:linux>"
"$<$<PLATFORM_ID:Darwin>:macos>"
"$<$<PLATFORM_ID:Emscripten>:web>"
"$<$<PLATFORM_ID:Windows>:windows>"
"$<$<PLATFORM_ID:Msys>:windows>"
)
# Process CPU architecture argument.
godot_arch_name( ARCH_NAME )
# Transform options into generator expressions
set(HOT_RELOAD-UNSET "$<STREQUAL:${GODOTCPP_USE_HOT_RELOAD},>")
set(DISABLE_EXCEPTIONS "$<BOOL:${GODOTCPP_DISABLE_EXCEPTIONS}>")
set(THREADS_ENABLED "$<BOOL:${GODOTCPP_THREADS}>")
# GODOTCPP_DEV_BUILD
set(RELEASE_TYPES "Release;MinSizeRel")
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(IS_MULTI_CONFIG)
message(NOTICE "=> Default build type is Debug. For other build types add --config <type> to build command")
elseif(GODOTCPP_DEV_BUILD AND CMAKE_BUILD_TYPE IN_LIST RELEASE_TYPES)
message(
WARNING
"=> GODOTCPP_DEV_BUILD implies a Debug-like build but CMAKE_BUILD_TYPE is '${CMAKE_BUILD_TYPE}'"
)
endif()
set(IS_DEV_BUILD "$<BOOL:${GODOTCPP_DEV_BUILD}>")
### Define our godot-cpp library targets
# Generator Expressions that rely on the target
set(DEBUG_FEATURES "$<NOT:$<STREQUAL:${GODOTCPP_TARGET},template_release>>")
set(HOT_RELOAD "$<IF:${HOT_RELOAD-UNSET},${DEBUG_FEATURES},$<BOOL:${GODOTCPP_USE_HOT_RELOAD}>>")
# Suffix Generator Expression
string(
CONCAT
GODOTCPP_SUFFIX_GENEX
"$<1:${SYSTEM_NAME}>"
"$<1:.${GODOTCPP_TARGET}>"
"$<${IS_DEV_BUILD}:.dev>"
"$<$<STREQUAL:${GODOTCPP_PRECISION},double>:.double>"
"$<1:.${ARCH_NAME}>"
# TODO IOS_SIMULATOR
"$<$<NOT:${THREADS_ENABLED}>:.nothreads>"
)
# The same as above, but with a leading '.' to maintain backwards compatibility.
set(GODOTCPP_SUFFIX ".${GODOTCPP_SUFFIX_GENEX}")
# the godot-cpp.* library targets
add_library(godot-cpp STATIC)
# Without adding this dependency to the binding generator, XCode will complain.
add_dependencies(godot-cpp generate_bindings)
# Added for backwards compatibility with prior cmake solution so that builds dont immediately break
# from a missing target.
add_library(godot::cpp ALIAS godot-cpp)
file(GLOB_RECURSE GODOTCPP_SOURCES LIST_DIRECTORIES NO CONFIGURE_DEPENDS src/*.cpp)
target_sources(godot-cpp PRIVATE ${GODOTCPP_SOURCES} ${GENERATED_FILES_LIST})
target_include_directories(
godot-cpp
${GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE}
PUBLIC include ${CMAKE_CURRENT_BINARY_DIR}/gen/include
)
# gersemi: off
set_target_properties(
godot-cpp
PROPERTIES
CXX_STANDARD 17
CXX_EXTENSIONS OFF
CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY}
COMPILE_WARNING_AS_ERROR ${GODOTCPP_WARNING_AS_ERROR}
POSITION_INDEPENDENT_CODE ON
BUILD_RPATH_USE_ORIGIN ON
PREFIX "lib"
OUTPUT_NAME "${PROJECT_NAME}${GODOTCPP_SUFFIX}"
ARCHIVE_OUTPUT_DIRECTORY "$<1:${CMAKE_BINARY_DIR}/bin>"
# Things that are handy to know for dependent targets
GODOTCPP_PLATFORM "${SYSTEM_NAME}"
GODOTCPP_TARGET "${GODOTCPP_TARGET}"
GODOTCPP_ARCH "${ARCH_NAME}"
GODOTCPP_PRECISION "${GODOTCPP_PRECISION}"
GODOTCPP_SUFFIX "${GODOTCPP_SUFFIX}"
GODOTCPP_SUFFIX_GENEX "${GODOTCPP_SUFFIX_GENEX}"
# Some IDE's respect this property to logically group targets
FOLDER "godot-cpp"
)
# gersemi: on
if(CMAKE_SYSTEM_NAME STREQUAL Android)
android_generate()
elseif(CMAKE_SYSTEM_NAME STREQUAL iOS)
ios_generate()
elseif(CMAKE_SYSTEM_NAME STREQUAL Linux)
linux_generate()
elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
macos_generate()
elseif(CMAKE_SYSTEM_NAME STREQUAL Emscripten)
web_generate()
elseif(CMAKE_SYSTEM_NAME STREQUAL Windows)
windows_generate()
endif()
endfunction()