SCons: Refactor running commands through builders

A new `env.Run` method is added which allows to control the verbosity
of builders output automatically depending on whether the "verbose"
option is set. It also allows to optionally run any SCons commands in a
subprocess using the existing `run_in_subprocess` method, unifying
the interface. `Action` objects wrap all builder functions to include a
short build message associated with any action.

Notably, this removes quite verbose output generated by `make_doc_header`
and `make_editor_icons_action` builders.
This commit is contained in:
Andrii Doroshenko (Xrayez) 2020-07-27 21:00:26 +03:00
parent f93c04d8ef
commit d86de6c98e
11 changed files with 97 additions and 51 deletions

View File

@ -84,6 +84,7 @@ env_base.__class__.add_shared_library = methods.add_shared_library
env_base.__class__.add_library = methods.add_library
env_base.__class__.add_program = methods.add_program
env_base.__class__.CommandNoCache = methods.CommandNoCache
env_base.__class__.Run = methods.Run
env_base.__class__.disable_warnings = methods.disable_warnings
env_base.__class__.module_check_dependencies = methods.module_check_dependencies
@ -627,27 +628,24 @@ if selected_platform in platform_list:
methods.no_verbose(sys, env)
if not env["platform"] == "server":
env.Append(
BUILDERS={
"GLES2_GLSL": env.Builder(
action=run_in_subprocess(gles_builders.build_gles2_headers), suffix="glsl.gen.h", src_suffix=".glsl"
)
}
)
env.Append(
BUILDERS={
"RD_GLSL": env.Builder(
action=run_in_subprocess(gles_builders.build_rd_headers), suffix="glsl.gen.h", src_suffix=".glsl"
)
}
)
env.Append(
BUILDERS={
"GLSL_HEADER": env.Builder(
action=run_in_subprocess(gles_builders.build_raw_headers), suffix="glsl.gen.h", src_suffix=".glsl"
)
}
)
GLSL_BUILDERS = {
"GLES2_GLSL": env.Builder(
action=env.Run(gles_builders.build_gles2_headers, 'Building GLES2_GLSL header: "$TARGET"'),
suffix="glsl.gen.h",
src_suffix=".glsl",
),
"RD_GLSL": env.Builder(
action=env.Run(gles_builders.build_rd_headers, 'Building RD_GLSL header: "$TARGET"'),
suffix="glsl.gen.h",
src_suffix=".glsl",
),
"GLSL_HEADER": env.Builder(
action=env.Run(gles_builders.build_raw_headers, 'Building GLSL header: "$TARGET"'),
suffix="glsl.gen.h",
src_suffix=".glsl",
),
}
env.Append(BUILDERS=GLSL_BUILDERS)
scons_cache_path = os.environ.get("SCONS_CACHE")
if scons_cache_path != None:

View File

@ -149,28 +149,34 @@ env.Depends(
env.CommandNoCache(
"#core/io/certs_compressed.gen.h",
"#thirdparty/certs/ca-certificates.crt",
run_in_subprocess(core_builders.make_certs_header),
env.Run(core_builders.make_certs_header, "Building ca-certificates header."),
)
# Make binders
env.CommandNoCache(
["method_bind.gen.inc", "method_bind_ext.gen.inc", "method_bind_free_func.gen.inc"],
"make_binders.py",
run_in_subprocess(make_binders.run),
env.Run(make_binders.run, "Generating method binders."),
)
# Authors
env.Depends("#core/authors.gen.h", "../AUTHORS.md")
env.CommandNoCache("#core/authors.gen.h", "../AUTHORS.md", run_in_subprocess(core_builders.make_authors_header))
env.CommandNoCache(
"#core/authors.gen.h", "../AUTHORS.md", env.Run(core_builders.make_authors_header, "Generating authors header."),
)
# Donors
env.Depends("#core/donors.gen.h", "../DONORS.md")
env.CommandNoCache("#core/donors.gen.h", "../DONORS.md", run_in_subprocess(core_builders.make_donors_header))
env.CommandNoCache(
"#core/donors.gen.h", "../DONORS.md", env.Run(core_builders.make_donors_header, "Generating donors header."),
)
# License
env.Depends("#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"])
env.CommandNoCache(
"#core/license.gen.h", ["../COPYRIGHT.txt", "../LICENSE.txt"], run_in_subprocess(core_builders.make_license_header)
"#core/license.gen.h",
["../COPYRIGHT.txt", "../LICENSE.txt"],
env.Run(core_builders.make_license_header, "Generating license header."),
)
# Chain load SCsubs

View File

@ -16,7 +16,7 @@ env.Depends("#core/input/default_controller_mappings.gen.cpp", controller_databa
env.CommandNoCache(
"#core/input/default_controller_mappings.gen.cpp",
controller_databases,
run_in_subprocess(input_builders.make_default_controller_mappings),
env.Run(input_builders.make_default_controller_mappings, "Generating default controller mappings."),
)
env.add_source_files(env.core_sources, "*.cpp")

View File

@ -7,7 +7,6 @@ env.editor_sources = []
import os
import os.path
import glob
from platform_methods import run_in_subprocess
import editor_builders
@ -61,7 +60,11 @@ if env["tools"]:
docs = sorted(docs)
env.Depends("#editor/doc_data_compressed.gen.h", docs)
env.CommandNoCache("#editor/doc_data_compressed.gen.h", docs, run_in_subprocess(editor_builders.make_doc_header))
env.CommandNoCache(
"#editor/doc_data_compressed.gen.h",
docs,
env.Run(editor_builders.make_doc_header, "Generating documentation header."),
)
path = env.Dir(".").abspath
@ -69,14 +72,18 @@ if env["tools"]:
tlist = glob.glob(path + "/translations/*.po")
env.Depends("#editor/editor_translations.gen.h", tlist)
env.CommandNoCache(
"#editor/editor_translations.gen.h", tlist, run_in_subprocess(editor_builders.make_editor_translations_header)
"#editor/editor_translations.gen.h",
tlist,
env.Run(editor_builders.make_editor_translations_header, "Generating editor translations header."),
)
# Documentation translations
tlist = glob.glob(env.Dir("#doc").abspath + "/translations/*.po")
env.Depends("#editor/doc_translations.gen.h", tlist)
env.CommandNoCache(
"#editor/doc_translations.gen.h", tlist, run_in_subprocess(editor_builders.make_doc_translations_header)
"#editor/doc_translations.gen.h",
tlist,
env.Run(editor_builders.make_doc_translations_header, "Generating translations header."),
)
# Fonts
@ -84,7 +91,11 @@ if env["tools"]:
flist.extend(glob.glob(path + "/../thirdparty/fonts/*.otf"))
flist.sort()
env.Depends("#editor/builtin_fonts.gen.h", flist)
env.CommandNoCache("#editor/builtin_fonts.gen.h", flist, run_in_subprocess(editor_builders.make_fonts_header))
env.CommandNoCache(
"#editor/builtin_fonts.gen.h",
flist,
env.Run(editor_builders.make_fonts_header, "Generating builtin fonts header."),
)
env.add_source_files(env.editor_sources, "*.cpp")

View File

@ -4,14 +4,14 @@ Import("env")
import os
from platform_methods import run_in_subprocess
import editor_icons_builders
make_editor_icons_builder = Builder(
action=run_in_subprocess(editor_icons_builders.make_editor_icons_action), suffix=".h", src_suffix=".svg"
)
env["BUILDERS"]["MakeEditorIconsBuilder"] = make_editor_icons_builder
env["BUILDERS"]["MakeEditorIconsBuilder"] = Builder(
action=env.Run(editor_icons_builders.make_editor_icons_action, "Generating editor icons header."),
suffix=".h",
src_suffix=".svg",
)
# Editor's own icons
icon_sources = Glob("*.svg")

View File

@ -2,7 +2,6 @@
Import("env")
from platform_methods import run_in_subprocess
import main_builders
env.main_sources = []
@ -15,15 +14,21 @@ if env["tests"]:
env_main.Append(CPPDEFINES=["TESTS_ENABLED"])
env_main.Depends("#main/splash.gen.h", "#main/splash.png")
env_main.CommandNoCache("#main/splash.gen.h", "#main/splash.png", run_in_subprocess(main_builders.make_splash))
env_main.CommandNoCache(
"#main/splash.gen.h", "#main/splash.png", env.Run(main_builders.make_splash, "Building splash screen header."),
)
env_main.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png")
env_main.CommandNoCache(
"#main/splash_editor.gen.h", "#main/splash_editor.png", run_in_subprocess(main_builders.make_splash_editor)
"#main/splash_editor.gen.h",
"#main/splash_editor.png",
env.Run(main_builders.make_splash_editor, "Building editor splash screen header."),
)
env_main.Depends("#main/app_icon.gen.h", "#main/app_icon.png")
env_main.CommandNoCache("#main/app_icon.gen.h", "#main/app_icon.png", run_in_subprocess(main_builders.make_app_icon))
env_main.CommandNoCache(
"#main/app_icon.gen.h", "#main/app_icon.png", env.Run(main_builders.make_app_icon, "Building application icon."),
)
lib = env_main.add_library("main", env.main_sources)
env.Prepend(LIBS=[lib])

View File

@ -4,6 +4,11 @@ import glob
import subprocess
from collections import OrderedDict
# We need to define our own `Action` method to control the verbosity of output
# and whenever we need to run those commands in a subprocess on some platforms.
from SCons.Script import Action
from platform_methods import run_in_subprocess
def add_source_files(self, sources, files, warn_duplicates=True):
# Convert string to list of absolute paths (including expanding wildcard)
@ -621,6 +626,14 @@ def CommandNoCache(env, target, sources, command, **args):
return result
def Run(env, function, short_message, subprocess=True):
output_print = short_message if not env["verbose"] else ""
if not subprocess:
return Action(function, output_print)
else:
return Action(run_in_subprocess(function), output_print)
def detect_darwin_sdk_path(platform, env):
sdk_name = ""
if platform == "osx":

View File

@ -10,14 +10,28 @@ env_modules = env.Clone()
Export("env_modules")
# Header with MODULE_*_ENABLED defines.
env.CommandNoCache("modules_enabled.gen.h", Value(env.module_list), modules_builders.generate_modules_enabled)
env.CommandNoCache(
"modules_enabled.gen.h",
Value(env.module_list),
env.Run(
modules_builders.generate_modules_enabled,
"Generating enabled modules header.",
# NOTE: No need to run in subprocess since this is still executed serially.
subprocess=False,
),
)
# Header to be included in `tests/test_main.cpp` to run module-specific tests.
if env["tests"]:
env.CommandNoCache(
"modules_tests.gen.h",
Value(env.module_list),
Action(modules_builders.generate_modules_tests, "Generating modules tests header."),
env.Run(
modules_builders.generate_modules_tests,
"Generating modules tests header.",
# NOTE: No need to run in subprocess since this is still executed serially.
subprocess=False,
),
)
env.AlwaysBuild("modules_tests.gen.h")

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python
import resource_to_cpp
from platform_methods import run_in_subprocess
Import("env")
Import("env_modules")

View File

@ -22,13 +22,12 @@ SConscript("pluginscript/SCsub")
SConscript("videodecoder/SCsub")
from platform_methods import run_in_subprocess
import gdnative_builders
_, gensource = env_gdnative.CommandNoCache(
["include/gdnative_api_struct.gen.h", "gdnative_api_struct.gen.cpp"],
"gdnative_api.json",
run_in_subprocess(gdnative_builders.build_gdnative_api_struct),
env.Run(gdnative_builders.build_gdnative_api_struct, "Generating GDNative API."),
)
env_gdnative.add_source_files(env.modules_sources, [gensource])

View File

@ -44,11 +44,12 @@ def run_in_subprocess(builder_function):
json.dump(data, json_file, indent=2)
json_file_size = os.stat(json_path).st_size
print(
"Executing builder function in subprocess: "
"module_path=%r, parameter_file=%r, parameter_file_size=%r, target=%r, source=%r"
% (module_path, json_path, json_file_size, target, source)
)
if env["verbose"]:
print(
"Executing builder function in subprocess: "
"module_path=%r, parameter_file=%r, parameter_file_size=%r, target=%r, source=%r"
% (module_path, json_path, json_file_size, target, source)
)
try:
exit_code = subprocess.call([sys.executable, module_path, json_path], env=subprocess_env)
finally: