Skip to content

Commit

Permalink
Merge pull request #65745 from akien-mga/scons-production-lto-earlier
Browse files Browse the repository at this point in the history
Refactor handling of `production` flag and per-platform LTO defaults
  • Loading branch information
akien-mga committed Sep 20, 2022
2 parents 7da5322 + 35a15e6 commit aa553f4
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 47 deletions.
71 changes: 34 additions & 37 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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")
Expand All @@ -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,
Expand Down
7 changes: 4 additions & 3 deletions platform/android/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
]


Expand Down Expand Up @@ -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"])
Expand Down
9 changes: 5 additions & 4 deletions platform/ios/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
]


Expand Down Expand Up @@ -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"])
Expand Down
4 changes: 4 additions & 0 deletions platform/linuxbsd/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]:
Expand Down
9 changes: 6 additions & 3 deletions platform/macos/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
]


Expand Down Expand Up @@ -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"])
Expand All @@ -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"])
Expand Down
4 changes: 4 additions & 0 deletions platform/web/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"])
Expand Down
8 changes: 8 additions & 0 deletions platform/windows/detect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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`.")
Expand Down Expand Up @@ -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"]:
Expand Down

0 comments on commit aa553f4

Please sign in to comment.