1
1
import os , sys , platform
2
2
3
3
from SCons .Variables import EnumVariable , PathVariable , BoolVariable
4
+ from SCons .Variables .BoolVariable import _text2bool
4
5
from SCons .Tool import Tool
5
6
from SCons .Builder import Builder
6
7
from SCons .Errors import UserError
8
+ from SCons .Script import ARGUMENTS
9
+
7
10
8
11
from binding_generator import scons_generate_bindings , scons_emit_files
9
12
@@ -14,6 +17,17 @@ def add_sources(sources, dir, extension):
14
17
sources .append (dir + "/" + f )
15
18
16
19
20
+ def get_cmdline_bool (option , default ):
21
+ """We use `ARGUMENTS.get()` to check if options were manually overridden on the command line,
22
+ and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings.
23
+ """
24
+ cmdline_val = ARGUMENTS .get (option )
25
+ if cmdline_val is not None :
26
+ return _text2bool (cmdline_val )
27
+ else :
28
+ return default
29
+
30
+
17
31
def normalize_path (val , env ):
18
32
return val if os .path .isabs (val ) else os .path .join (env .Dir ("#" ).abspath , val )
19
33
@@ -230,16 +244,23 @@ def options(opts, env):
230
244
)
231
245
)
232
246
247
+ opts .Add (
248
+ EnumVariable (
249
+ "optimize" ,
250
+ "The desired optimization flags" ,
251
+ "speed_trace" ,
252
+ ("none" , "custom" , "debug" , "speed" , "speed_trace" , "size" ),
253
+ )
254
+ )
255
+ opts .Add (BoolVariable ("debug_symbols" , "Build with debugging symbols" , True ))
256
+ opts .Add (BoolVariable ("dev_build" , "Developer build with dev-only debugging code (DEV_ENABLED)" , False ))
257
+
233
258
# Add platform options (custom tools can override platforms)
234
259
for pl in sorted (set (platforms + custom_platforms )):
235
260
tool = Tool (pl , toolpath = get_platform_tools_paths (env ))
236
261
if hasattr (tool , "options" ):
237
262
tool .options (opts )
238
263
239
- # Targets flags tool (optimizations, debug symbols)
240
- target_tool = Tool ("targets" , toolpath = ["tools" ])
241
- target_tool .options (opts )
242
-
243
264
244
265
def generate (env ):
245
266
# Default num_jobs to local cpu count if not user specified.
@@ -286,43 +307,56 @@ def generate(env):
286
307
287
308
print ("Building for architecture " + env ["arch" ] + " on platform " + env ["platform" ])
288
309
289
- if env .get ("use_hot_reload" ) is None :
290
- env ["use_hot_reload" ] = env ["target" ] != "template_release"
291
- if env ["use_hot_reload" ]:
292
- env .Append (CPPDEFINES = ["HOT_RELOAD_ENABLED" ])
310
+ # These defaults may be needed by platform tools
311
+ env .use_hot_reload = env .get ("use_hot_reload" , env ["target" ] != "template_release" )
312
+ env .editor_build = env ["target" ] == "editor"
313
+ env .dev_build = env ["dev_build" ]
314
+ env .debug_features = env ["target" ] in ["editor" , "template_debug" ]
315
+
316
+ if env .dev_build :
317
+ opt_level = "none"
318
+ elif env .debug_features :
319
+ opt_level = "speed_trace"
320
+ else : # Release
321
+ opt_level = "speed"
322
+
323
+ env ["optimize" ] = ARGUMENTS .get ("optimize" , opt_level )
324
+ env ["debug_symbols" ] = get_cmdline_bool ("debug_symbols" , env .dev_build )
293
325
294
326
tool = Tool (env ["platform" ], toolpath = get_platform_tools_paths (env ))
295
327
296
328
if tool is None or not tool .exists (env ):
297
329
raise ValueError ("Required toolchain not found for platform " + env ["platform" ])
298
330
299
331
tool .generate (env )
300
- target_tool = Tool ("targets" , toolpath = ["tools" ])
301
- target_tool .generate (env )
302
-
303
- # Disable exception handling. Godot doesn't use exceptions anywhere, and this
304
- # saves around 20% of binary size and very significant build time.
305
- if env ["disable_exceptions" ]:
306
- if env .get ("is_msvc" , False ):
307
- env .Append (CPPDEFINES = [("_HAS_EXCEPTIONS" , 0 )])
308
- else :
309
- env .Append (CXXFLAGS = ["-fno-exceptions" ])
310
- elif env .get ("is_msvc" , False ):
311
- env .Append (CXXFLAGS = ["/EHsc" ])
312
-
313
- if not env .get ("is_msvc" , False ):
314
- if env ["symbols_visibility" ] == "visible" :
315
- env .Append (CCFLAGS = ["-fvisibility=default" ])
316
- env .Append (LINKFLAGS = ["-fvisibility=default" ])
317
- elif env ["symbols_visibility" ] == "hidden" :
318
- env .Append (CCFLAGS = ["-fvisibility=hidden" ])
319
- env .Append (LINKFLAGS = ["-fvisibility=hidden" ])
320
-
321
- # Require C++17
322
- if env .get ("is_msvc" , False ):
323
- env .Append (CXXFLAGS = ["/std:c++17" ])
332
+
333
+ if env .use_hot_reload :
334
+ env .Append (CPPDEFINES = ["HOT_RELOAD_ENABLED" ])
335
+
336
+ if env .editor_build :
337
+ env .Append (CPPDEFINES = ["TOOLS_ENABLED" ])
338
+
339
+ # Configuration of build targets:
340
+ # - Editor or template
341
+ # - Debug features (DEBUG_ENABLED code)
342
+ # - Dev only code (DEV_ENABLED code)
343
+ # - Optimization level
344
+ # - Debug symbols for crash traces / debuggers
345
+ # Keep this configuration in sync with SConstruct in upstream Godot.
346
+ if env .debug_features :
347
+ # DEBUG_ENABLED enables debugging *features* and debug-only code, which is intended
348
+ # to give *users* extra debugging information for their game development.
349
+ env .Append (CPPDEFINES = ["DEBUG_ENABLED" ])
350
+ # In upstream Godot this is added in typedefs.h when DEBUG_ENABLED is set.
351
+ env .Append (CPPDEFINES = ["DEBUG_METHODS_ENABLED" ])
352
+
353
+ if env .dev_build :
354
+ # DEV_ENABLED enables *engine developer* code which should only be compiled for those
355
+ # working on the engine itself.
356
+ env .Append (CPPDEFINES = ["DEV_ENABLED" ])
324
357
else :
325
- env .Append (CXXFLAGS = ["-std=c++17" ])
358
+ # Disable assert() for production targets (only used in thirdparty code).
359
+ env .Append (CPPDEFINES = ["NDEBUG" ])
326
360
327
361
if env ["precision" ] == "double" :
328
362
env .Append (CPPDEFINES = ["REAL_T_IS_DOUBLE" ])
0 commit comments