SCons: Add an option to enable the experimental ninja build backend

With this option turned on, if properly set up, SCons generates a
`build.ninja` file and quits. To actually build the engine, the user can
then call `ninja` with whatever options they might prefer (not
everything is yet transferred properly to this new generated file).

Ideally, the scons file should never be called again, as ninja
automatically detects any SCons build script change and invokes
the required commands to regenerate itself.

This approach speeds up incremental builds considerably, as it limits
SCons to code generation and uses ninja's extremely fast timestamp-based
file change detector.
This commit is contained in:
Riteo 2024-03-12 22:51:19 +01:00
parent a5cf92664d
commit 55558fb175
3 changed files with 24 additions and 4 deletions

4
.gitignore vendored
View File

@ -35,6 +35,10 @@ bin
compile_commands.json
platform/windows/godot_res.res
# Ninja build files
build.ninja
.ninja
# Generated by Godot binary
.import/
/gdextension_interface.h

View File

@ -203,6 +203,7 @@ opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursi
opts.Add(BoolVariable("dev_mode", "Alias for dev options: verbose=yes warnings=extra werror=yes tests=yes", False))
opts.Add(BoolVariable("tests", "Build the unit tests", False))
opts.Add(BoolVariable("fast_unsafe", "Enable unsafe options for faster rebuilds", False))
opts.Add(BoolVariable("ninja", "Use the ninja backend for faster rebuilds", False))
opts.Add(BoolVariable("compiledb", "Generate compilation DB (`compile_commands.json`) for external tools", False))
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))
opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True))
@ -956,7 +957,8 @@ if selected_platform in platform_list:
env.vs_incs = []
env.vs_srcs = []
# CompileDB
# CompileDB and Ninja are only available with certain SCons versions which
# not everybody might have yet, so we have to check.
from SCons import __version__ as scons_raw_version
scons_ver = env._get_major_minor_revision(scons_raw_version)
@ -968,6 +970,20 @@ if selected_platform in platform_list:
env.Tool("compilation_db")
env.Alias("compiledb", env.CompilationDatabase())
if env["ninja"]:
if scons_ver < (4, 2, 0):
print("The `ninja=yes` option requires SCons 4.2 or later, but your version is %s." % scons_raw_version)
Exit(255)
SetOption("experimental", "ninja")
# By setting this we allow the user to run ninja by themselves with all
# the flags they need, as apparently automatically running from scons
# is way slower.
SetOption("disable_execute_ninja", True)
env.Tool("ninja")
# Threads
if env["threads"]:
env.Append(CPPDEFINES=["THREADS_ENABLED"])
@ -1041,9 +1057,10 @@ atexit.register(print_elapsed_time)
def purge_flaky_files():
paths_to_keep = ["ninja.build"]
for build_failure in GetBuildFailures():
path = build_failure.node.abspath
if os.path.isfile(path):
path = build_failure.node.path
if os.path.isfile(path) and path not in paths_to_keep:
os.remove(path)

View File

@ -66,7 +66,6 @@ def generate_export_icons(platform_path, platform_name):
svg_str += '";\n'
# NOTE: It is safe to generate this file here, since this is still executed serially.
wf = export_path + "/" + name + "_svg.gen.h"
methods.write_file_if_needed(wf, svg_str)