Skip to content

Commit 5c79c79

Browse files
committed
SCons: Add emitter to declutter build objects
1 parent 7893202 commit 5c79c79

File tree

6 files changed

+53
-9
lines changed

6 files changed

+53
-9
lines changed

SConstruct

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ from importlib.util import module_from_spec, spec_from_file_location
1414
from types import ModuleType
1515

1616
from SCons import __version__ as scons_raw_version
17+
from SCons.Builder import ListEmitter
1718

1819
# Explicitly resolve the helper modules, this is done to avoid clash with
1920
# 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
236237
opts.Add(BoolVariable("steamapi", "Enable minimal SteamAPI integration for usage time tracking (editor only)", False))
237238
opts.Add("cache_path", "Path to a directory where SCons cache files will be stored. No value disables the cache.", "")
238239
opts.Add("cache_limit", "Max size (in GiB) for the SCons cache. 0 means no limit.", "0")
240+
opts.Add(
241+
BoolVariable(
242+
"redirect_build_objects",
243+
"Enable redirecting built objects/libraries to `bin/obj/` to declutter the repository.",
244+
True,
245+
)
246+
)
239247

240248
# Thirdparty libraries
241249
opts.Add(BoolVariable("builtin_brotli", "Use the built-in Brotli library", True))
@@ -1054,6 +1062,14 @@ if env["ninja"]:
10541062
if env["threads"]:
10551063
env.Append(CPPDEFINES=["THREADS_ENABLED"])
10561064

1065+
# Ensure build objects are put in their own folder.
1066+
env.Prepend(LIBEMITTER=[methods.redirect_emitter])
1067+
env.Prepend(SHLIBEMITTER=[methods.redirect_emitter])
1068+
for key in (emitters := env.StaticObject.builder.emitter):
1069+
emitters[key] = ListEmitter([methods.redirect_emitter] + env.Flatten(emitters[key]))
1070+
for key in (emitters := env.SharedObject.builder.emitter):
1071+
emitters[key] = ListEmitter([methods.redirect_emitter] + env.Flatten(emitters[key]))
1072+
10571073
# Build subdirs, the build order is dependent on link order.
10581074
Export("env")
10591075

methods.py

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
from misc.utility.color import print_error, print_info, print_warning
1515

1616
# Get the "Godot" folder name ahead of time
17-
base_folder_path = str(os.path.abspath(Path(__file__).parent)) + "/"
18-
base_folder_only = os.path.basename(os.path.normpath(base_folder_path))
17+
base_folder = Path(__file__).parent.resolve()
1918

2019
compiler_version_cache = None
2120

@@ -81,6 +80,34 @@ def add_source_files(self, sources, files, allow_gen=False):
8180
return True
8281

8382

83+
def redirect_emitter(target, source, env):
84+
"""
85+
Emitter to automatically redirect object/library build files to the `bin/obj` directory,
86+
retaining subfolder structure. External build files will attempt to retain subfolder
87+
structure relative to their environment's parent directory, sorted under `bin/obj/external`.
88+
If `redirect_build_objects` is `False`, or an external build file isn't relative to the
89+
passed environment, this emitter does nothing.
90+
"""
91+
if not env["redirect_build_objects"]:
92+
return target, source
93+
redirected_targets = []
94+
for item in env.Flatten(target):
95+
if isinstance(item, str):
96+
item = env.File(item)
97+
path = Path(item.get_abspath()).resolve()
98+
try:
99+
item = env.File(f"#bin/obj/{path.relative_to(base_folder)}")
100+
except ValueError:
101+
# External file; most likely a custom module. Assume relevant environment was passed.
102+
alt_base = Path(env.Dir(".").get_abspath()).parent.resolve()
103+
try:
104+
item = env.File(f"#bin/obj/external/{path.relative_to(alt_base)}")
105+
except ValueError:
106+
pass
107+
redirected_targets.append(item)
108+
return redirected_targets, source
109+
110+
84111
def disable_warnings(self):
85112
# 'self' is the environment
86113
if self.msvc and not using_clang(self):
@@ -767,7 +794,7 @@ def show_progress(env):
767794
if env["ninja"]:
768795
return
769796

770-
NODE_COUNT_FILENAME = f"{base_folder_path}.scons_node_count"
797+
NODE_COUNT_FILENAME = base_folder / ".scons_node_count"
771798

772799
class ShowProgress:
773800
def __init__(self):

platform/android/SCsub

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ env_thirdparty.disable_warnings()
4444
thirdparty_obj = env_thirdparty.SharedObject("#thirdparty/misc/ifaddrs-android.cc")
4545
android_objects.append(thirdparty_obj)
4646

47-
lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSUFFIX=env["SHLIBSUFFIX"])
47+
lib = env_android.add_shared_library("#bin/libgodot", android_objects, redirect_build_objects=False)
4848

4949
# Needed to force rebuilding the platform files when the thirdparty code is updated.
5050
env.Depends(lib, thirdparty_obj)
@@ -78,9 +78,7 @@ if lib_arch_dir != "":
7878
lib_tools_dir = ""
7979

8080
out_dir = "#platform/android/java/lib/libs/" + lib_tools_dir + lib_type_dir + "/" + lib_arch_dir
81-
env_android.Command(
82-
out_dir + "/libgodot_android.so", "#bin/libgodot" + env["SHLIBSUFFIX"], Move("$TARGET", "$SOURCE")
83-
)
81+
env_android.Command(out_dir + "/libgodot_android.so", lib, Move("$TARGET", "$SOURCE"))
8482

8583
stl_lib_path = (
8684
str(env["ANDROID_NDK_ROOT"]) + "/sources/cxx-stl/llvm-libc++/libs/" + lib_arch_dir + "/libc++_shared.so"

platform/web/detect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def library_emitter(target, source, env):
9898

9999

100100
def configure(env: "SConsEnvironment"):
101-
env.Append(LIBEMITTER=library_emitter)
101+
env.Append(LIBEMITTER=[library_emitter])
102102

103103
# Validate arch.
104104
supported_arches = ["wasm32"]

platform/windows/SCsub

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ from pathlib import Path
88

99
import platform_windows_builders
1010

11+
from methods import redirect_emitter
12+
1113
sources = []
1214

1315
common_win = [
@@ -49,6 +51,7 @@ def arrange_program_clean(prog):
4951
Clean(prog, extra_files_to_clean)
5052

5153

54+
env["BUILDERS"]["RES"].emitter = redirect_emitter
5255
res_file = "godot_res.rc"
5356
res_target = "godot_res" + env["OBJSUFFIX"]
5457
res_obj = env.RES(res_target, res_file)

platform/windows/detect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ def configure_msvc(env: "SConsEnvironment"):
278278
from tempfile import mkstemp
279279

280280
# Ensure we have a location to write captured output to, in case of false positives.
281-
capture_path = methods.base_folder_path + "platform/windows/msvc_capture.log"
281+
capture_path = methods.base_folder / "platform" / "windows" / "msvc_capture.log"
282282
with open(capture_path, "wt", encoding="utf-8"):
283283
pass
284284

0 commit comments

Comments
 (0)