diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2022-09-13 17:01:47 +0200 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2022-09-19 18:11:29 +0200 |
commit | 35a15e619161798820b2bd6ff46178c5b7ccebcf (patch) | |
tree | c22c80afb7f82aeaabca3c43cb6e8ff7a7c1cd05 | |
parent | 6f5704d86f95171ba8b6b2ac9f56e284c4d35d7a (diff) |
SCons: Refactor handling of `production` flag and per-platform LTO defaults
Fixup to #63288.
See #65583 for the bug report.
Co-authored-by: Cyberrebell <chainsaw75@web.de>
-rw-r--r-- | SConstruct | 71 | ||||
-rw-r--r-- | platform/android/detect.py | 7 | ||||
-rw-r--r-- | platform/ios/detect.py | 9 | ||||
-rw-r--r-- | platform/linuxbsd/detect.py | 4 | ||||
-rw-r--r-- | platform/macos/detect.py | 9 | ||||
-rw-r--r-- | platform/web/detect.py | 4 | ||||
-rw-r--r-- | platform/windows/detect.py | 8 |
7 files changed, 65 insertions, 47 deletions
diff --git a/SConstruct b/SConstruct index 891f1116e1..200e8e5984 100644 --- a/SConstruct +++ b/SConstruct @@ -170,7 +170,7 @@ opts.Add(EnumVariable("arch", "CPU architecture", "auto", ["auto"] + architectur opts.Add(EnumVariable("float", "Floating-point precision", "32", ("32", "64"))) opts.Add(EnumVariable("optimize", "Optimization type", "speed", ("speed", "size", "none"))) opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False)) -opts.Add(EnumVariable("lto", "Link-time optimization (for production buids)", "none", ("none", "thin", "full"))) +opts.Add(EnumVariable("lto", "Link-time optimization (for production buids)", "none", ("none", "auto", "thin", "full"))) # Components opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated and removed features", True)) @@ -460,36 +460,17 @@ if selected_platform in platform_list: env["LINKFLAGS"] = "" env.Append(LINKFLAGS=str(LINKFLAGS).split()) - # Platform specific flags + # Platform specific flags. + # These can sometimes override default options. flag_list = platform_flags[selected_platform] for f in flag_list: if not (f[0] in ARGUMENTS) or ARGUMENTS[f[0]] == "auto": # Allow command line to override platform flags env[f[0]] = f[1] - # Must happen after the flags' definition, so that they can be used by platform detect - detect.configure(env) - - print( - 'Building for platform "%s", architecture "%s", %s, target "%s".' - % (selected_platform, env["arch"], "editor" if env["tools"] else "template", env["target"]) - ) - - # Set our C and C++ standard requirements. - # C++17 is required as we need guaranteed copy elision as per GH-36436. - # Prepending to make it possible to override. - # This needs to come after `configure`, otherwise we don't have env.msvc. - if not env.msvc: - # Specifying GNU extensions support explicitly, which are supported by - # both GCC and Clang. Both currently default to gnu11 and gnu++14. - env.Prepend(CFLAGS=["-std=gnu11"]) - env.Prepend(CXXFLAGS=["-std=gnu++17"]) - else: - # MSVC doesn't have clear C standard support, /std only covers C++. - # We apply it to CCFLAGS (both C and C++ code) in case it impacts C features. - env.Prepend(CCFLAGS=["/std:c++17"]) - - # 'dev' and 'production' are aliases to set default options if they haven't been set - # manually by the user. + # 'dev' and 'production' are aliases to set default options if they haven't been + # set manually by the user. + # These need to be checked *after* platform specific flags so that different + # default values can be set (e.g. to keep LTO off for `production` on some platforms). if env["dev"]: env["verbose"] = methods.get_cmdline_bool("verbose", True) env["warnings"] = ARGUMENTS.get("warnings", "extra") @@ -498,27 +479,43 @@ if selected_platform in platform_list: env["tests"] = methods.get_cmdline_bool("tests", True) if env["production"]: env["use_static_cpp"] = methods.get_cmdline_bool("use_static_cpp", True) - env["lto"] = ARGUMENTS.get("lto", "full") env["debug_symbols"] = methods.get_cmdline_bool("debug_symbols", False) + # LTO "auto" means we handle the preferred option in each platform detect.py. + env["lto"] = ARGUMENTS.get("lto", "auto") if not env["tools"] and env["target"] == "debug": print( "WARNING: Requested `production` build with `tools=no target=debug`, " "this will give you a full debug template (use `target=release_debug` " "for an optimized template with debug features)." ) - if env.msvc: - print( - "WARNING: For `production` Windows builds, you should use MinGW with GCC " - "or Clang instead of Visual Studio, as they can better optimize the " - "GDScript VM in a very significant way. MSVC LTO also doesn't work " - "reliably for our use case." - "If you want to use MSVC nevertheless for production builds, set " - "`debug_symbols=no lto=none` instead of the `production=yes` option." - ) - Exit(255) + + # Must happen after the flags' definition, as configure is when most flags + # are actually handled to change compile options, etc. + detect.configure(env) + + # Needs to happen after configure to handle "auto". if env["lto"] != "none": print("Using LTO: " + env["lto"]) + # Set our C and C++ standard requirements. + # C++17 is required as we need guaranteed copy elision as per GH-36436. + # Prepending to make it possible to override. + # This needs to come after `configure`, otherwise we don't have env.msvc. + if not env.msvc: + # Specifying GNU extensions support explicitly, which are supported by + # both GCC and Clang. Both currently default to gnu11 and gnu++14. + env.Prepend(CFLAGS=["-std=gnu11"]) + env.Prepend(CXXFLAGS=["-std=gnu++17"]) + else: + # MSVC doesn't have clear C standard support, /std only covers C++. + # We apply it to CCFLAGS (both C and C++ code) in case it impacts C features. + env.Prepend(CCFLAGS=["/std:c++17"]) + + print( + 'Building for platform "%s", architecture "%s", %s, target "%s".' + % (selected_platform, env["arch"], "editor" if env["tools"] else "template", env["target"]) + ) + # Enforce our minimal compiler version requirements cc_version = methods.get_compiler_version(env) or { "major": None, diff --git a/platform/android/detect.py b/platform/android/detect.py index 1d9bcdd932..a31bba745f 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -47,9 +47,6 @@ def get_flags(): return [ ("arch", "arm64"), # Default for convenience. ("tools", False), - # Benefits of LTO for Android (size, performance) haven't been clearly established yet. - # So for now we override the default value which may be set when using `production=yes`. - ("lto", "none"), ] @@ -136,6 +133,10 @@ def configure(env): env.Append(CPPFLAGS=["-UNDEBUG"]) # LTO + + if env["lto"] == "auto": # LTO benefits for Android (size, performance) haven't been clearly established yet. + env["lto"] = "none" + if env["lto"] != "none": if env["lto"] == "thin": env.Append(CCFLAGS=["-flto=thin"]) diff --git a/platform/ios/detect.py b/platform/ios/detect.py index ed7e714c4e..d5e6ee4b46 100644 --- a/platform/ios/detect.py +++ b/platform/ios/detect.py @@ -39,9 +39,6 @@ def get_flags(): ("arch", "arm64"), # Default for convenience. ("tools", False), ("use_volk", False), - # Disable by default even if production is set, as it makes linking in Xcode - # on exports very slow and that's not what most users expect. - ("lto", "none"), ] @@ -73,7 +70,11 @@ def configure(env): env.Append(CCFLAGS=["-gdwarf-2", "-O0"]) env.Append(CPPDEFINES=["_DEBUG", ("DEBUG", 1)]) - # LTO + ## LTO + + if env["lto"] == "auto": # Disable by default as it makes linking in Xcode very slow. + env["lto"] = "none" + if env["lto"] != "none": if env["lto"] == "thin": env.Append(CCFLAGS=["-flto=thin"]) diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 36644d5f29..12d2432eea 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -171,6 +171,10 @@ def configure(env): env.Append(LINKFLAGS=["-fsanitize=memory"]) # LTO + + if env["lto"] == "auto": # Full LTO for production. + env["lto"] = "full" + if env["lto"] != "none": if env["lto"] == "thin": if not env["use_llvm"]: diff --git a/platform/macos/detect.py b/platform/macos/detect.py index bcf4776609..834ac935d8 100644 --- a/platform/macos/detect.py +++ b/platform/macos/detect.py @@ -40,9 +40,6 @@ def get_flags(): return [ ("arch", detect_arch()), ("use_volk", False), - # Benefits of LTO for macOS (size, performance) haven't been clearly established yet. - # So for now we override the default value which may be set when using `production=yes`. - ("lto", "none"), ] @@ -170,6 +167,10 @@ def configure(env): env["AS"] = basecmd + "as" # LTO + + if env["lto"] == "auto": # LTO benefits for macOS (size, performance) haven't been clearly established yet. + env["lto"] = "none" + if env["lto"] != "none": if env["lto"] == "thin": env.Append(CCFLAGS=["-flto=thin"]) @@ -178,6 +179,8 @@ def configure(env): env.Append(CCFLAGS=["-flto"]) env.Append(LINKFLAGS=["-flto"]) + # Sanitizers + if env["use_ubsan"] or env["use_asan"] or env["use_tsan"]: env.extra_suffix += ".san" env.Append(CCFLAGS=["-DSANITIZERS_ENABLED"]) diff --git a/platform/web/detect.py b/platform/web/detect.py index 08f964db92..9cce73efc4 100644 --- a/platform/web/detect.py +++ b/platform/web/detect.py @@ -109,6 +109,10 @@ def configure(env): env["ENV"] = os.environ # LTO + + if env["lto"] == "auto": # Full LTO for production. + env["lto"] = "full" + if env["lto"] != "none": if env["lto"] == "thin": env.Append(CCFLAGS=["-flto=thin"]) diff --git a/platform/windows/detect.py b/platform/windows/detect.py index e6e1874fc0..52a959b34a 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -448,6 +448,9 @@ def configure_msvc(env, vcvars_msvc_config): ## LTO + if env["lto"] == "auto": # No LTO by default for MSVC, doesn't help. + env["lto"] = "none" + if env["lto"] != "none": if env["lto"] == "thin": print("ThinLTO is only compatible with LLVM, use `use_llvm=yes` or `lto=full`.") @@ -564,6 +567,11 @@ def configure_mingw(env): if try_cmd("gcc-ranlib --version", env["mingw_prefix"], env["arch"]): env["RANLIB"] = mingw_bin_prefix + "gcc-ranlib" + ## LTO + + if env["lto"] == "auto": # Full LTO for production with MinGW. + env["lto"] = "full" + if env["lto"] != "none": if env["lto"] == "thin": if not env["use_llvm"]: |