You've already forked godot
							
							
				mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-04 12:00:25 +00:00 
			
		
		
		
	SCons: Add emitter to declutter build objects
This commit is contained in:
		
							
								
								
									
										16
									
								
								SConstruct
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								SConstruct
									
									
									
									
									
								
							@@ -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
 | 
			
		||||
@@ -236,6 +237,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))
 | 
			
		||||
@@ -1052,6 +1060,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")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								methods.py
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								methods.py
									
									
									
									
									
								
							@@ -16,8 +16,7 @@ from typing import Generator, List, Optional, Union, cast
 | 
			
		||||
from misc.utility.color import print_error, print_info, print_warning
 | 
			
		||||
 | 
			
		||||
# Get the "Godot" folder name ahead of time
 | 
			
		||||
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
 | 
			
		||||
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
 | 
			
		||||
base_folder = Path(__file__).resolve().parent
 | 
			
		||||
 | 
			
		||||
compiler_version_cache = None
 | 
			
		||||
 | 
			
		||||
@@ -83,6 +82,29 @@ def add_source_files(self, sources, files, allow_gen=False):
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def redirect_emitter(target, source, env):
 | 
			
		||||
    """
 | 
			
		||||
    Emitter to automatically redirect object/library build files to the `bin/obj` directory,
 | 
			
		||||
    retaining subfolder structure. External build files will attempt to retain subfolder
 | 
			
		||||
    structure relative to their environment's parent directory, sorted under `bin/obj/external`.
 | 
			
		||||
    If `redirect_build_objects` is `False`, or an external build file isn't relative to the
 | 
			
		||||
    passed environment, this emitter does nothing.
 | 
			
		||||
    """
 | 
			
		||||
    if not env["redirect_build_objects"]:
 | 
			
		||||
        return target, source
 | 
			
		||||
 | 
			
		||||
    redirected_targets = []
 | 
			
		||||
    for item in target:
 | 
			
		||||
        if base_folder in (path := Path(item.get_abspath()).resolve()).parents:
 | 
			
		||||
            item = env.File(f"#bin/obj/{path.relative_to(base_folder)}")
 | 
			
		||||
        elif (alt_base := Path(env.Dir(".").get_abspath()).resolve().parent) in path.parents:
 | 
			
		||||
            item = env.File(f"#bin/obj/external/{path.relative_to(alt_base)}")
 | 
			
		||||
        else:
 | 
			
		||||
            print_warning(f'Failed to redirect "{path}"')
 | 
			
		||||
        redirected_targets.append(item)
 | 
			
		||||
    return redirected_targets, source
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def disable_warnings(self):
 | 
			
		||||
    # 'self' is the environment
 | 
			
		||||
    if self.msvc and not using_clang(self):
 | 
			
		||||
@@ -150,7 +172,7 @@ def get_version_info(module_version_string="", silent=False):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_git_info():
 | 
			
		||||
    os.chdir(base_folder_path)
 | 
			
		||||
    os.chdir(base_folder)
 | 
			
		||||
 | 
			
		||||
    # Parse Git hash if we're in a Git repo.
 | 
			
		||||
    git_hash = ""
 | 
			
		||||
@@ -775,7 +797,7 @@ def show_progress(env):
 | 
			
		||||
    if env["ninja"]:
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    NODE_COUNT_FILENAME = f"{base_folder_path}.scons_node_count"
 | 
			
		||||
    NODE_COUNT_FILENAME = base_folder / ".scons_node_count"
 | 
			
		||||
 | 
			
		||||
    class ShowProgress:
 | 
			
		||||
        def __init__(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -101,7 +101,7 @@ for name, path in env.module_list.items():
 | 
			
		||||
if env["tests"]:
 | 
			
		||||
 | 
			
		||||
    def modules_tests_builder(target, source, env):
 | 
			
		||||
        headers = sorted([os.path.relpath(src.path, methods.base_folder_path).replace("\\", "/") for src in source])
 | 
			
		||||
        headers = sorted([os.path.relpath(src.path, methods.base_folder).replace("\\", "/") for src in source])
 | 
			
		||||
        with methods.generated_wrapper(str(target[0])) as file:
 | 
			
		||||
            for header in headers:
 | 
			
		||||
                file.write(f'#include "{header}"\n')
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ env_thirdparty.disable_warnings()
 | 
			
		||||
thirdparty_obj = env_thirdparty.SharedObject("#thirdparty/misc/ifaddrs-android.cc")
 | 
			
		||||
android_objects.append(thirdparty_obj)
 | 
			
		||||
 | 
			
		||||
lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSUFFIX=env["SHLIBSUFFIX"])
 | 
			
		||||
lib = env_android.add_shared_library("libgodot", android_objects)
 | 
			
		||||
 | 
			
		||||
# Needed to force rebuilding the platform files when the thirdparty code is updated.
 | 
			
		||||
env.Depends(lib, thirdparty_obj)
 | 
			
		||||
@@ -78,9 +78,7 @@ if lib_arch_dir != "":
 | 
			
		||||
        lib_tools_dir = ""
 | 
			
		||||
 | 
			
		||||
    out_dir = "#platform/android/java/lib/libs/" + lib_tools_dir + lib_type_dir + "/" + lib_arch_dir
 | 
			
		||||
    env_android.Command(
 | 
			
		||||
        out_dir + "/libgodot_android.so", "#bin/libgodot" + env["SHLIBSUFFIX"], Move("$TARGET", "$SOURCE")
 | 
			
		||||
    )
 | 
			
		||||
    env_android.Command(out_dir + "/libgodot_android.so", lib, Move("$TARGET", "$SOURCE"))
 | 
			
		||||
 | 
			
		||||
    stl_lib_path = (
 | 
			
		||||
        str(env["ANDROID_NDK_ROOT"]) + "/sources/cxx-stl/llvm-libc++/libs/" + lib_arch_dir + "/libc++_shared.so"
 | 
			
		||||
 
 | 
			
		||||
@@ -98,7 +98,7 @@ def library_emitter(target, source, env):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def configure(env: "SConsEnvironment"):
 | 
			
		||||
    env.Append(LIBEMITTER=library_emitter)
 | 
			
		||||
    env.Append(LIBEMITTER=[library_emitter])
 | 
			
		||||
 | 
			
		||||
    # Validate arch.
 | 
			
		||||
    supported_arches = ["wasm32"]
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,8 @@ from pathlib import Path
 | 
			
		||||
 | 
			
		||||
import platform_windows_builders
 | 
			
		||||
 | 
			
		||||
from methods import redirect_emitter
 | 
			
		||||
 | 
			
		||||
sources = []
 | 
			
		||||
 | 
			
		||||
common_win = [
 | 
			
		||||
@@ -49,6 +51,7 @@ def arrange_program_clean(prog):
 | 
			
		||||
        Clean(prog, extra_files_to_clean)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
env["BUILDERS"]["RES"].emitter = redirect_emitter
 | 
			
		||||
res_file = "godot_res.rc"
 | 
			
		||||
res_target = "godot_res" + env["OBJSUFFIX"]
 | 
			
		||||
res_obj = env.RES(res_target, res_file)
 | 
			
		||||
 
 | 
			
		||||
@@ -278,7 +278,7 @@ def configure_msvc(env: "SConsEnvironment"):
 | 
			
		||||
        from tempfile import mkstemp
 | 
			
		||||
 | 
			
		||||
        # Ensure we have a location to write captured output to, in case of false positives.
 | 
			
		||||
        capture_path = methods.base_folder_path + "platform/windows/msvc_capture.log"
 | 
			
		||||
        capture_path = methods.base_folder / "platform" / "windows" / "msvc_capture.log"
 | 
			
		||||
        with open(capture_path, "wt", encoding="utf-8"):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user