Browse Source

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.
Andrii Doroshenko (Xrayez) 5 years ago
parent
commit
d86de6c98e
11 changed files with 97 additions and 51 deletions
  1. 19 21
      SConstruct
  2. 11 5
      core/SCsub
  3. 1 1
      core/input/SCsub
  4. 16 5
      editor/SCsub
  5. 5 5
      editor/icons/SCsub
  6. 9 4
      main/SCsub
  7. 13 0
      methods.py
  8. 16 2
      modules/SCsub
  9. 0 1
      modules/denoise/SCsub
  10. 1 2
      modules/gdnative/SCsub
  11. 6 5
      platform_methods.py

+ 19 - 21
SConstruct

@@ -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_library = methods.add_library
 env_base.__class__.add_program = methods.add_program
 env_base.__class__.add_program = methods.add_program
 env_base.__class__.CommandNoCache = methods.CommandNoCache
 env_base.__class__.CommandNoCache = methods.CommandNoCache
+env_base.__class__.Run = methods.Run
 env_base.__class__.disable_warnings = methods.disable_warnings
 env_base.__class__.disable_warnings = methods.disable_warnings
 env_base.__class__.module_check_dependencies = methods.module_check_dependencies
 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)
         methods.no_verbose(sys, env)
 
 
     if not env["platform"] == "server":
     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")
     scons_cache_path = os.environ.get("SCONS_CACHE")
     if scons_cache_path != None:
     if scons_cache_path != None:

+ 11 - 5
core/SCsub

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

+ 1 - 1
core/input/SCsub

@@ -16,7 +16,7 @@ env.Depends("#core/input/default_controller_mappings.gen.cpp", controller_databa
 env.CommandNoCache(
 env.CommandNoCache(
     "#core/input/default_controller_mappings.gen.cpp",
     "#core/input/default_controller_mappings.gen.cpp",
     controller_databases,
     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")
 env.add_source_files(env.core_sources, "*.cpp")

+ 16 - 5
editor/SCsub

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

+ 5 - 5
editor/icons/SCsub

@@ -4,14 +4,14 @@ Import("env")
 
 
 import os
 import os
 
 
-from platform_methods import run_in_subprocess
 import editor_icons_builders
 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
 # Editor's own icons
 icon_sources = Glob("*.svg")
 icon_sources = Glob("*.svg")

+ 9 - 4
main/SCsub

@@ -2,7 +2,6 @@
 
 
 Import("env")
 Import("env")
 
 
-from platform_methods import run_in_subprocess
 import main_builders
 import main_builders
 
 
 env.main_sources = []
 env.main_sources = []
@@ -15,15 +14,21 @@ if env["tests"]:
     env_main.Append(CPPDEFINES=["TESTS_ENABLED"])
     env_main.Append(CPPDEFINES=["TESTS_ENABLED"])
 
 
 env_main.Depends("#main/splash.gen.h", "#main/splash.png")
 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.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png")
 env_main.CommandNoCache(
 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.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)
 lib = env_main.add_library("main", env.main_sources)
 env.Prepend(LIBS=[lib])
 env.Prepend(LIBS=[lib])

+ 13 - 0
methods.py

@@ -4,6 +4,11 @@ import glob
 import subprocess
 import subprocess
 from collections import OrderedDict
 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):
 def add_source_files(self, sources, files, warn_duplicates=True):
     # Convert string to list of absolute paths (including expanding wildcard)
     # Convert string to list of absolute paths (including expanding wildcard)
@@ -621,6 +626,14 @@ def CommandNoCache(env, target, sources, command, **args):
     return result
     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):
 def detect_darwin_sdk_path(platform, env):
     sdk_name = ""
     sdk_name = ""
     if platform == "osx":
     if platform == "osx":

+ 16 - 2
modules/SCsub

@@ -10,14 +10,28 @@ env_modules = env.Clone()
 Export("env_modules")
 Export("env_modules")
 
 
 # Header with MODULE_*_ENABLED defines.
 # 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.
 # Header to be included in `tests/test_main.cpp` to run module-specific tests.
 if env["tests"]:
 if env["tests"]:
     env.CommandNoCache(
     env.CommandNoCache(
         "modules_tests.gen.h",
         "modules_tests.gen.h",
         Value(env.module_list),
         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")
     env.AlwaysBuild("modules_tests.gen.h")
 
 

+ 0 - 1
modules/denoise/SCsub

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

+ 1 - 2
modules/gdnative/SCsub

@@ -22,13 +22,12 @@ SConscript("pluginscript/SCsub")
 SConscript("videodecoder/SCsub")
 SConscript("videodecoder/SCsub")
 
 
 
 
-from platform_methods import run_in_subprocess
 import gdnative_builders
 import gdnative_builders
 
 
 _, gensource = env_gdnative.CommandNoCache(
 _, gensource = env_gdnative.CommandNoCache(
     ["include/gdnative_api_struct.gen.h", "gdnative_api_struct.gen.cpp"],
     ["include/gdnative_api_struct.gen.h", "gdnative_api_struct.gen.cpp"],
     "gdnative_api.json",
     "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])
 env_gdnative.add_source_files(env.modules_sources, [gensource])
 
 

+ 6 - 5
platform_methods.py

@@ -44,11 +44,12 @@ def run_in_subprocess(builder_function):
             json.dump(data, json_file, indent=2)
             json.dump(data, json_file, indent=2)
         json_file_size = os.stat(json_path).st_size
         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:
         try:
             exit_code = subprocess.call([sys.executable, module_path, json_path], env=subprocess_env)
             exit_code = subprocess.call([sys.executable, module_path, json_path], env=subprocess_env)
         finally:
         finally: