This commit is contained in:
Spartan322
2025-04-19 07:12:16 -04:00
5209 changed files with 229124 additions and 66199 deletions

View File

@@ -14,6 +14,7 @@ from importlib.util import module_from_spec, spec_from_file_location
from types import ModuleType
from SCons import __version__ as scons_raw_version
from SCons.Builder import ListEmitter
# Explicitly resolve the helper modules, this is done to avoid clash with
# modules of the same name that might be randomly added (e.g. someone adding
@@ -57,7 +58,7 @@ import gles3_builders
import glsl_builders
import methods
import scu_builders
from misc.utility.color import STDERR_COLOR, print_error, print_info, print_warning
from misc.utility.color import is_stderr_color, print_error, print_info, print_warning
from platform_methods import architecture_aliases, architectures, compatibility_platform_aliases
if ARGUMENTS.get("target", "editor") == "editor":
@@ -166,7 +167,7 @@ opts.Add(
"optimize",
"Optimization level (by default inferred from 'target' and 'dev_build')",
"auto",
("auto", "none", "custom", "debug", "speed", "speed_trace", "size"),
("auto", "none", "custom", "debug", "speed", "speed_trace", "size", "size_extra"),
)
)
opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", False))
@@ -186,11 +187,12 @@ opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True))
opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True))
opts.Add(BoolVariable("d3d12", "Enable the Direct3D 12 rendering driver on supported platforms", False))
opts.Add(BoolVariable("metal", "Enable the Metal rendering driver on supported platforms (Apple arm64 only)", False))
opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True))
opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True))
opts.Add(BoolVariable("disable_exceptions", "Force disabling exception handling code", True))
opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True))
opts.Add(BoolVariable("accesskit", "Use AccessKit C SDK", True))
opts.Add(("accesskit_sdk_path", "Path to the AccessKit C SDK", ""))
# Advanced options
opts.Add(
@@ -220,6 +222,11 @@ opts.Add("vsproj_name", "Name of the Visual Studio solution", "redot")
opts.Add("import_env_vars", "A comma-separated list of environment variables to copy from the outer environment.", "")
opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False))
opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False))
opts.Add(BoolVariable("disable_physics_2d", "Disable 2D physics nodes and server", False))
opts.Add(BoolVariable("disable_physics_3d", "Disable 3D physics nodes and server", False))
opts.Add(BoolVariable("disable_navigation_2d", "Disable 2D navigation features", False))
opts.Add(BoolVariable("disable_navigation_3d", "Disable 3D navigation features", False))
opts.Add(BoolVariable("disable_xr", "Disable XR nodes and server", False))
opts.Add("build_profile", "Path to a file containing a feature build profile", "")
opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True))
opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True))
@@ -236,6 +243,13 @@ opts.Add(BoolVariable("engine_update_check", "Enable engine update checks in the
opts.Add(BoolVariable("steamapi", "Enable minimal SteamAPI integration for usage time tracking (editor only)", False))
opts.Add("cache_path", "Path to a directory where SCons cache files will be stored. No value disables the cache.", "")
opts.Add("cache_limit", "Max size (in GiB) for the SCons cache. 0 means no limit.", "0")
opts.Add(
BoolVariable(
"redirect_build_objects",
"Enable redirecting built objects/libraries to `bin/obj/` to declutter the repository.",
True,
)
)
# Thirdparty libraries
opts.Add(BoolVariable("builtin_brotli", "Use the built-in Brotli library", True))
@@ -433,10 +447,19 @@ for tool in custom_tools:
env.Tool(tool)
# add default include paths
# Add default include paths.
env.Prepend(CPPPATH=["#"])
# Allow marking includes as external/system to avoid raising warnings.
env["_CCCOMCOM"] += " $_CPPEXTINCFLAGS"
env["CPPEXTPATH"] = []
if env.scons_version < (4, 2):
env["_CPPEXTINCFLAGS"] = "${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE)}"
else:
env["_CPPEXTINCFLAGS"] = (
"${_concat(EXTINCPREFIX, CPPEXTPATH, EXTINCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}"
)
# configure ENV for platform
env.platform_exporters = platform_exporters
env.platform_apis = platform_apis
@@ -696,83 +719,84 @@ if env["arch"] == "x86_32":
# Explicitly specify colored output.
if methods.using_gcc(env):
env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if STDERR_COLOR else "-fno-diagnostics-color"])
env.AppendUnique(CCFLAGS=["-fdiagnostics-color" if is_stderr_color() else "-fno-diagnostics-color"])
elif methods.using_clang(env) or methods.using_emcc(env):
env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if STDERR_COLOR else "-fno-color-diagnostics"])
env.AppendUnique(CCFLAGS=["-fcolor-diagnostics" if is_stderr_color() else "-fno-color-diagnostics"])
if sys.platform == "win32":
env.AppendUnique(CCFLAGS=["-fansi-escape-codes"])
# Set optimize and debug_symbols flags.
# "custom" means do nothing and let users set their own optimization flags.
# Needs to happen after configure to have `env.msvc` defined.
env.AppendUnique(CCFLAGS=["$OPTIMIZELEVEL"])
if env.msvc:
if env["debug_symbols"]:
env.Append(CCFLAGS=["/Zi", "/FS"])
env.Append(LINKFLAGS=["/DEBUG:FULL"])
env.AppendUnique(CCFLAGS=["/Zi", "/FS"])
env.AppendUnique(LINKFLAGS=["/DEBUG:FULL"])
else:
env.Append(LINKFLAGS=["/DEBUG:NONE"])
env.AppendUnique(LINKFLAGS=["/DEBUG:NONE"])
if env["optimize"].startswith("speed"):
env.Append(CCFLAGS=["/O2"])
env.Append(LINKFLAGS=["/OPT:REF"])
env["OPTIMIZELEVEL"] = "/O2"
env.AppendUnique(LINKFLAGS=["/OPT:REF"])
if env["optimize"] == "speed_trace":
env.Append(LINKFLAGS=["/OPT:NOICF"])
elif env["optimize"] == "size":
env.Append(CCFLAGS=["/O1"])
env.Append(LINKFLAGS=["/OPT:REF"])
env.AppendUnique(LINKFLAGS=["/OPT:NOICF"])
elif env["optimize"].startswith("size"):
env["OPTIMIZELEVEL"] = "/O1"
env.AppendUnique(LINKFLAGS=["/OPT:REF"])
if env["optimize"] == "size_extra":
env.AppendUnique(CPPDEFINES=["SIZE_EXTRA"])
elif env["optimize"] == "debug" or env["optimize"] == "none":
env.Append(CCFLAGS=["/Od"])
env["OPTIMIZELEVEL"] = "/Od"
else:
if env["debug_symbols"]:
if env["platform"] == "windows":
if methods.using_clang(env):
env.Append(CCFLAGS=["-gdwarf-4"]) # clang dwarf-5 symbols are broken on Windows.
env.AppendUnique(CCFLAGS=["-gdwarf-4"]) # clang dwarf-5 symbols are broken on Windows.
else:
env.Append(CCFLAGS=["-gdwarf-5"]) # For gcc, only dwarf-5 symbols seem usable by libbacktrace.
env.AppendUnique(CCFLAGS=["-gdwarf-5"]) # For gcc, only dwarf-5 symbols seem usable by libbacktrace.
else:
# Adding dwarf-4 explicitly makes stacktraces work with clang builds,
# otherwise addr2line doesn't understand them
env.Append(CCFLAGS=["-gdwarf-4"])
env.AppendUnique(CCFLAGS=["-gdwarf-4"])
if methods.using_emcc(env):
# Emscripten only produces dwarf symbols when using "-g3".
env.Append(CCFLAGS=["-g3"])
env.AppendUnique(CCFLAGS=["-g3"])
# Emscripten linker needs debug symbols options too.
env.Append(LINKFLAGS=["-gdwarf-4"])
env.Append(LINKFLAGS=["-g3"])
env.AppendUnique(LINKFLAGS=["-gdwarf-4"])
env.AppendUnique(LINKFLAGS=["-g3"])
elif env.dev_build:
env.Append(CCFLAGS=["-g3"])
env.AppendUnique(CCFLAGS=["-g3"])
else:
env.Append(CCFLAGS=["-g2"])
env.AppendUnique(CCFLAGS=["-g2"])
if env["debug_paths_relative"]:
# Remap absolute paths to relative paths for debug symbols.
project_path = Dir("#").abspath
env.Append(CCFLAGS=[f"-ffile-prefix-map={project_path}=."])
env.AppendUnique(CCFLAGS=[f"-ffile-prefix-map={project_path}=."])
else:
if methods.is_apple_clang(env):
# Apple Clang, its linker doesn't like -s.
env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
env.AppendUnique(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"])
else:
env.Append(LINKFLAGS=["-s"])
env.AppendUnique(LINKFLAGS=["-s"])
# Linker needs optimization flags too, at least for Emscripten.
# For other toolchains, this _may_ be useful for LTO too to disambiguate.
env.AppendUnique(LINKFLAGS=["$OPTIMIZELEVEL"])
if env["optimize"] == "speed":
env.Append(CCFLAGS=["-O3"])
env.Append(LINKFLAGS=["-O3"])
env["OPTIMIZELEVEL"] = "-O3"
# `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces.
elif env["optimize"] == "speed_trace":
env.Append(CCFLAGS=["-O2"])
env.Append(LINKFLAGS=["-O2"])
elif env["optimize"] == "size":
env.Append(CCFLAGS=["-Os"])
env.Append(LINKFLAGS=["-Os"])
env["OPTIMIZELEVEL"] = "-O2"
elif env["optimize"].startswith("size"):
env["OPTIMIZELEVEL"] = "-Os"
if env["optimize"] == "size_extra":
env.AppendUnique(CPPDEFINES=["SIZE_EXTRA"])
elif env["optimize"] == "debug":
env.Append(CCFLAGS=["-Og"])
env.Append(LINKFLAGS=["-Og"])
env["OPTIMIZELEVEL"] = "-Og"
elif env["optimize"] == "none":
env.Append(CCFLAGS=["-O0"])
env.Append(LINKFLAGS=["-O0"])
env["OPTIMIZELEVEL"] = "-O0"
# Needs to happen after configure to handle "auto".
if env["lto"] != "none":
@@ -813,6 +837,7 @@ elif env.msvc:
env.Append(CXXFLAGS=["/EHsc"])
# Configure compiler warnings
env.AppendUnique(CCFLAGS=["$WARNLEVEL"])
if env.msvc and not methods.using_clang(env): # MSVC
# Disable warnings which we don't plan to fix.
disabled_warnings = [
@@ -830,19 +855,23 @@ if env.msvc and not methods.using_clang(env): # MSVC
]
if env["warnings"] == "extra":
env.Append(CCFLAGS=["/W4"] + disabled_warnings)
env["WARNLEVEL"] = "/W4"
env.AppendUnique(CCFLAGS=disabled_warnings)
elif env["warnings"] == "all":
env["WARNLEVEL"] = "/W3"
# C4458 is like -Wshadow. Part of /W4 but let's apply it for the default /W3 too.
env.Append(CCFLAGS=["/W3", "/w34458"] + disabled_warnings)
env.AppendUnique(CCFLAGS=["/w34458"] + disabled_warnings)
elif env["warnings"] == "moderate":
env.Append(CCFLAGS=["/W2"] + disabled_warnings)
env["WARNLEVEL"] = "/W2"
env.AppendUnique(CCFLAGS=disabled_warnings)
else: # 'no'
env["WARNLEVEL"] = "/w"
# C4267 is particularly finicky & needs to be explicitly disabled.
env.Append(CCFLAGS=["/w", "/wd4267"])
env.AppendUnique(CCFLAGS=["/wd4267"])
if env["werror"]:
env.Append(CCFLAGS=["/WX"])
env.Append(LINKFLAGS=["/WX"])
env.AppendUnique(CCFLAGS=["/WX"])
env.AppendUnique(LINKFLAGS=["/WX"])
else: # GCC, Clang
common_warnings = []
@@ -861,14 +890,14 @@ else: # GCC, Clang
# for putting them in `Set` or `Map`. We don't mind about unreliable ordering.
common_warnings += ["-Wno-ordered-compare-function-pointers"]
# clang-cl will interpret `-Wall` as `-Weverything`, workaround with compatibility cast
W_ALL = "-Wall" if not env.msvc else "-W3"
# clang-cl will interpret `-Wall` as `-Weverything`, workaround with compatibility cast.
env["WARNLEVEL"] = "-Wall" if not env.msvc else "-W3"
if env["warnings"] == "extra":
env.Append(CCFLAGS=[W_ALL, "-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings)
env.Append(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"])
env.AppendUnique(CCFLAGS=["-Wextra", "-Wwrite-strings", "-Wno-unused-parameter"] + common_warnings)
env.AppendUnique(CXXFLAGS=["-Wctor-dtor-privacy", "-Wnon-virtual-dtor"])
if methods.using_gcc(env):
env.Append(
env.AppendUnique(
CCFLAGS=[
"-Walloc-zero",
"-Wduplicated-branches",
@@ -876,25 +905,38 @@ else: # GCC, Clang
"-Wstringop-overflow=4",
]
)
env.Append(CXXFLAGS=["-Wplacement-new=1"])
env.AppendUnique(CXXFLAGS=["-Wplacement-new=1", "-Wvirtual-inheritance"])
# Need to fix a warning with AudioServer lambdas before enabling.
# if cc_version_major != 9: # GCC 9 had a regression (GH-36325).
# env.Append(CXXFLAGS=["-Wnoexcept"])
if cc_version_major >= 9:
env.Append(CCFLAGS=["-Wattribute-alias=2"])
env.AppendUnique(CCFLAGS=["-Wattribute-alias=2"])
if cc_version_major >= 11: # Broke on MethodBind templates before GCC 11.
env.Append(CCFLAGS=["-Wlogical-op"])
env.AppendUnique(CCFLAGS=["-Wlogical-op"])
elif methods.using_clang(env) or methods.using_emcc(env):
env.Append(CCFLAGS=["-Wimplicit-fallthrough"])
env.AppendUnique(CCFLAGS=["-Wimplicit-fallthrough"])
elif env["warnings"] == "all":
env.Append(CCFLAGS=[W_ALL] + common_warnings)
env.AppendUnique(CCFLAGS=common_warnings)
elif env["warnings"] == "moderate":
env.Append(CCFLAGS=[W_ALL, "-Wno-unused"] + common_warnings)
env.AppendUnique(CCFLAGS=["-Wno-unused"] + common_warnings)
else: # 'no'
env.Append(CCFLAGS=["-w"])
env["WARNLEVEL"] = "-w"
if env["werror"]:
env.Append(CCFLAGS=["-Werror"])
env.AppendUnique(CCFLAGS=["-Werror"])
# Configure external includes.
if env.msvc:
if not methods.using_clang(env):
if cc_version_major < 16 or (cc_version_major == 16 and cc_version_minor < 10):
env.AppendUnique(CCFLAGS=["/experimental:external"])
env.AppendUnique(CCFLAGS=["/external:anglebrackets"])
env.AppendUnique(CCFLAGS=["/external:W0"])
env["EXTINCPREFIX"] = "/external:I"
env["EXTINCSUFFIX"] = ""
else:
env["EXTINCPREFIX"] = "-isystem "
env["EXTINCSUFFIX"] = ""
if hasattr(detect, "get_program_suffix"):
suffix = "." + detect.get_program_suffix()
@@ -918,6 +960,51 @@ suffix += env.extra_suffix
sys.path.remove(tmppath)
sys.modules.pop("detect")
if env.editor_build:
unsupported_opts = []
for disable_opt in [
"disable_3d",
"disable_advanced_gui",
"disable_physics_2d",
"disable_physics_3d",
"disable_navigation_2d",
"disable_navigation_3d",
]:
if env[disable_opt]:
unsupported_opts.append(disable_opt)
if unsupported_opts != []:
print_error(
"The following build option(s) cannot be used for editor builds, but only for export template builds: {}.".format(
", ".join(unsupported_opts)
)
)
Exit(255)
if env["disable_3d"]:
env.Append(CPPDEFINES=["_3D_DISABLED"])
env["disable_navigation_3d"] = True
env["disable_physics_3d"] = True
env["disable_xr"] = True
if env["disable_advanced_gui"]:
env.Append(CPPDEFINES=["ADVANCED_GUI_DISABLED"])
if env["disable_physics_2d"]:
env.Append(CPPDEFINES=["PHYSICS_2D_DISABLED"])
if env["disable_physics_3d"]:
env.Append(CPPDEFINES=["PHYSICS_3D_DISABLED"])
if env["disable_navigation_2d"]:
env.Append(CPPDEFINES=["NAVIGATION_2D_DISABLED"])
if env["disable_navigation_3d"]:
env.Append(CPPDEFINES=["NAVIGATION_3D_DISABLED"])
if env["disable_xr"]:
env.Append(CPPDEFINES=["XR_DISABLED"])
if env["minizip"]:
env.Append(CPPDEFINES=["MINIZIP_ENABLED"])
if env["brotli"]:
env.Append(CPPDEFINES=["BROTLI_ENABLED"])
if not env["verbose"]:
methods.no_verbose(env)
modules_enabled = OrderedDict()
env.module_dependencies = {}
env.module_icons_paths = []
@@ -968,8 +1055,6 @@ if env.editor_build:
print_error("Not all modules required by editor builds are enabled.")
Exit(255)
env.version_info = methods.get_version_info(env.module_version_string)
env["PROGSUFFIX_WRAP"] = suffix + env.module_version_string + ".console" + env["PROGSUFFIX"]
env["PROGSUFFIX"] = suffix + env.module_version_string + env["PROGSUFFIX"]
env["OBJSUFFIX"] = suffix + env["OBJSUFFIX"]
@@ -989,28 +1074,6 @@ env["SHLIBSUFFIX"] = suffix + env["SHLIBSUFFIX"]
env["OBJPREFIX"] = env["object_prefix"]
env["SHOBJPREFIX"] = env["object_prefix"]
if env["disable_3d"]:
if env.editor_build:
print_error("Build option `disable_3d=yes` cannot be used for editor builds, only for export template builds.")
Exit(255)
else:
env.Append(CPPDEFINES=["_3D_DISABLED"])
if env["disable_advanced_gui"]:
if env.editor_build:
print_error(
"Build option `disable_advanced_gui=yes` cannot be used for editor builds, only for export template builds."
)
Exit(255)
else:
env.Append(CPPDEFINES=["ADVANCED_GUI_DISABLED"])
if env["minizip"]:
env.Append(CPPDEFINES=["MINIZIP_ENABLED"])
if env["brotli"]:
env.Append(CPPDEFINES=["BROTLI_ENABLED"])
if not env["verbose"]:
methods.no_verbose(env)
GLSL_BUILDERS = {
"RD_GLSL": env.Builder(
action=env.Run(glsl_builders.build_rd_headers),
@@ -1051,6 +1114,14 @@ if env["ninja"]:
if env["threads"]:
env.Append(CPPDEFINES=["THREADS_ENABLED"])
# Ensure build objects are put in their own folder if `redirect_build_objects` is enabled.
env.Prepend(LIBEMITTER=[methods.redirect_emitter])
env.Prepend(SHLIBEMITTER=[methods.redirect_emitter])
for key in (emitters := env.StaticObject.builder.emitter):
emitters[key] = ListEmitter([methods.redirect_emitter] + env.Flatten(emitters[key]))
for key in (emitters := env.SharedObject.builder.emitter):
emitters[key] = ListEmitter([methods.redirect_emitter] + env.Flatten(emitters[key]))
# Build subdirs, the build order is dependent on link order.
Export("env")
@@ -1082,11 +1153,11 @@ if "check_c_headers" in env:
for header in headers:
if conf.CheckCHeader(header):
env.AppendUnique(CPPDEFINES=[headers[header]])
conf.Finish()
methods.show_progress(env)
# TODO: replace this with `env.Dump(format="json")`
# once we start requiring SCons 4.0 as min version.
methods.dump(env)
methods.prepare_purge(env)
methods.prepare_timer()
# Miscellaneous & post-build methods.
if not env.GetOption("clean") and not env.GetOption("help"):
methods.dump(env)
methods.show_progress(env)
methods.prepare_purge(env)
methods.prepare_timer()