Add lto scons option, defaulting to "auto" ("full" in production, "none" in dev builds).

pull/1601/head
Lukas Tenbrink 2024-09-21 12:52:50 +02:00
parent 57bd88ad99
commit b4973810ef
8 changed files with 69 additions and 0 deletions

View File

@ -120,4 +120,9 @@ def generate(env):
env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"]) env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"])
# Refer to https://github.com/godotengine/godot/blob/master/platform/android/detect.py
# LTO benefits for Android (size, performance) haven't been clearly established yet.
if env["lto"] == "auto":
env["lto"] = "none"
common_compiler_flags.generate(env) common_compiler_flags.generate(env)

View File

@ -22,6 +22,10 @@ def exists(env):
def generate(env): def generate(env):
assert env["lto"] in ["thin", "full", "none"], "Unrecognized lto: {}".format(env["lto"])
if env["lto"] != "none":
print("Using LTO: " + env["lto"])
# Require C++17 # Require C++17
if env.get("is_msvc", False): if env.get("is_msvc", False):
env.Append(CXXFLAGS=["/std:c++17"]) env.Append(CXXFLAGS=["/std:c++17"])
@ -64,6 +68,22 @@ def generate(env):
env.Append(LINKFLAGS=["/OPT:REF"]) env.Append(LINKFLAGS=["/OPT:REF"])
elif env["optimize"] == "debug" or env["optimize"] == "none": elif env["optimize"] == "debug" or env["optimize"] == "none":
env.Append(CCFLAGS=["/Od"]) env.Append(CCFLAGS=["/Od"])
if env["lto"] == "thin":
if not env["use_llvm"]:
print("ThinLTO is only compatible with LLVM, use `use_llvm=yes` or `lto=full`.")
env.Exit(255)
env.Append(CCFLAGS=["-flto=thin"])
env.Append(LINKFLAGS=["-flto=thin"])
elif env["lto"] == "full":
if env["use_llvm"]:
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto"])
else:
env.AppendUnique(CCFLAGS=["/GL"])
env.AppendUnique(ARFLAGS=["/LTCG"])
env.AppendUnique(LINKFLAGS=["/LTCG"])
else: else:
if env["debug_symbols"]: if env["debug_symbols"]:
# Adding dwarf-4 explicitly makes stacktraces work with clang builds, # Adding dwarf-4 explicitly makes stacktraces work with clang builds,
@ -91,3 +111,13 @@ def generate(env):
env.Append(CCFLAGS=["-Og"]) env.Append(CCFLAGS=["-Og"])
elif env["optimize"] == "none": elif env["optimize"] == "none":
env.Append(CCFLAGS=["-O0"]) env.Append(CCFLAGS=["-O0"])
if env["lto"] == "thin":
if (env["platform"] == "windows" or env["platform"] == "linux") and not env["use_llvm"]:
print("ThinLTO is only compatible with LLVM, use `use_llvm=yes` or `lto=full`.")
env.Exit(255)
env.Append(CCFLAGS=["-flto=thin"])
env.Append(LINKFLAGS=["-flto=thin"])
elif env["lto"] == "full":
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto"])

View File

@ -326,6 +326,14 @@ def options(opts, env):
("none", "custom", "debug", "speed", "speed_trace", "size"), ("none", "custom", "debug", "speed", "speed_trace", "size"),
) )
) )
opts.Add(
EnumVariable(
"lto",
"Link-time optimization",
"none",
("none", "auto", "thin", "full"),
)
)
opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", True)) opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", True))
opts.Add(BoolVariable("dev_build", "Developer build with dev-only debugging code (DEV_ENABLED)", False)) opts.Add(BoolVariable("dev_build", "Developer build with dev-only debugging code (DEV_ENABLED)", False))
opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False)) opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False))

View File

@ -97,4 +97,9 @@ def generate(env):
env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED"]) env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED"])
# Refer to https://github.com/godotengine/godot/blob/master/platform/ios/detect.py:
# Disable by default as it makes linking in Xcode very slow.
if env["lto"] == "auto":
env["lto"] = "none"
common_compiler_flags.generate(env) common_compiler_flags.generate(env)

View File

@ -39,4 +39,8 @@ def generate(env):
env.Append(CPPDEFINES=["LINUX_ENABLED", "UNIX_ENABLED"]) env.Append(CPPDEFINES=["LINUX_ENABLED", "UNIX_ENABLED"])
# Refer to https://github.com/godotengine/godot/blob/master/platform/linuxbsd/detect.py
if env["lto"] == "auto":
env["lto"] = "full"
common_compiler_flags.generate(env) common_compiler_flags.generate(env)

View File

@ -73,4 +73,9 @@ def generate(env):
env.Append(CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED"]) env.Append(CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED"])
# Refer to https://github.com/godotengine/godot/blob/master/platform/macos/detect.py
# LTO benefits for macOS (size, performance) haven't been clearly established yet.
if env["lto"] == "auto":
env["lto"] = "none"
common_compiler_flags.generate(env) common_compiler_flags.generate(env)

View File

@ -48,4 +48,8 @@ def generate(env):
env.Append(CPPDEFINES=["WEB_ENABLED", "UNIX_ENABLED"]) env.Append(CPPDEFINES=["WEB_ENABLED", "UNIX_ENABLED"])
# Refer to https://github.com/godotengine/godot/blob/master/platform/web/detect.py
if env["lto"] == "auto":
env["lto"] = "full"
common_compiler_flags.generate(env) common_compiler_flags.generate(env)

View File

@ -199,4 +199,12 @@ def generate(env):
env.Append(CPPDEFINES=["WINDOWS_ENABLED"]) env.Append(CPPDEFINES=["WINDOWS_ENABLED"])
# Refer to https://github.com/godotengine/godot/blob/master/platform/windows/detect.py
if env["lto"] == "auto":
if env.get("is_msvc", False):
# No LTO by default for MSVC, doesn't help.
env["lto"] = "none"
else: # Release
env["lto"] = "full"
common_compiler_flags.generate(env) common_compiler_flags.generate(env)