From 600e749d9bbeb5bad58d2d6d097b2f6b52cbe241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Thu, 10 Aug 2023 09:20:23 +0200 Subject: [PATCH] SCons: Sync `targets.py` fully with upstream Godot - Reorders existing code to match Godot. - Adds `NDEBUG` for non-dev builds. - Adds `-gdwarf-4` for Clang debug symbols. - Adds strip link flag for GCC/Clang builds without debug symbols. --- tools/targets.py | 70 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/tools/targets.py b/tools/targets.py index 5f8e768..2161134 100644 --- a/tools/targets.py +++ b/tools/targets.py @@ -1,10 +1,14 @@ import os +import subprocess import sys from SCons.Script import ARGUMENTS from SCons.Variables import * from SCons.Variables.BoolVariable import _text2bool +# Helper methods + + def get_cmdline_bool(option, default): """We use `ARGUMENTS.get()` to check if options were manually overridden on the command line, and SCons' _text2bool helper to convert them to booleans, otherwise they're handled as strings. @@ -16,6 +20,24 @@ def get_cmdline_bool(option, default): return default +def using_clang(env): + return "clang" in os.path.basename(env["CC"]) + + +def is_vanilla_clang(env): + if not using_clang(env): + return False + try: + version = subprocess.check_output([env.subst(env["CXX"]), "--version"]).strip().decode("utf-8") + except (subprocess.CalledProcessError, OSError): + print("Couldn't parse CXX environment variable to infer compiler version.") + return False + return not version.startswith("Apple") + + +# Main tool definition + + def options(opts): opts.Add( EnumVariable( @@ -34,19 +56,21 @@ def exists(env): def generate(env): + # Configuration of build targets: + # - Editor or template + # - Debug features (DEBUG_ENABLED code) + # - Dev only code (DEV_ENABLED code) + # - Optimization level + # - Debug symbols for crash traces / debuggers + + # Keep this configuration in sync with SConstruct in upstream Godot. + + env.editor_build = env["target"] == "editor" env.dev_build = env["dev_build"] env.debug_features = env["target"] in ["editor", "template_debug"] - env.editor_build = env["target"] == "editor" - - if env.editor_build: - env.AppendUnique(CPPDEFINES=["TOOLS_ENABLED"]) - - if env.debug_features: - env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED", "DEBUG_METHODS_ENABLED"]) if env.dev_build: opt_level = "none" - env.AppendUnique(CPPDEFINES=["DEV_ENABLED"]) elif env.debug_features: opt_level = "speed_trace" else: # Release @@ -55,6 +79,26 @@ def generate(env): env["optimize"] = ARGUMENTS.get("optimize", opt_level) env["debug_symbols"] = get_cmdline_bool("debug_symbols", env.dev_build) + if env.editor_build: + env.Append(CPPDEFINES=["TOOLS_ENABLED"]) + + if env.debug_features: + # DEBUG_ENABLED enables debugging *features* and debug-only code, which is intended + # to give *users* extra debugging information for their game development. + env.Append(CPPDEFINES=["DEBUG_ENABLED"]) + # In upstream Godot this is added in typedefs.h when DEBUG_ENABLED is set. + env.Append(CPPDEFINES=["DEBUG_METHODS_ENABLED"]) + + if env.dev_build: + # DEV_ENABLED enables *engine developer* code which should only be compiled for those + # working on the engine itself. + env.Append(CPPDEFINES=["DEV_ENABLED"]) + else: + # Disable assert() for production targets (only used in thirdparty code). + env.Append(CPPDEFINES=["NDEBUG"]) + + # Set optimize and debug_symbols flags. + # "custom" means do nothing and let users set their own optimization flags. if env.get("is_msvc", False): if env["debug_symbols"]: env.Append(CCFLAGS=["/Zi", "/FS"]) @@ -71,13 +115,21 @@ def generate(env): env.Append(LINKFLAGS=["/OPT:REF"]) elif env["optimize"] == "debug" or env["optimize"] == "none": env.Append(CCFLAGS=["/Od"]) - else: if env["debug_symbols"]: + # Adding dwarf-4 explicitly makes stacktraces work with clang builds, + # otherwise addr2line doesn't understand them. + env.Append(CCFLAGS=["-gdwarf-4"]) if env.dev_build: env.Append(CCFLAGS=["-g3"]) else: env.Append(CCFLAGS=["-g2"]) + else: + if using_clang(env) and not is_vanilla_clang(env): + # Apple Clang, its linker doesn't like -s. + env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"]) + else: + env.Append(LINKFLAGS=["-s"]) if env["optimize"] == "speed": env.Append(CCFLAGS=["-O3"])