Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SCons] Split targets.py, apply flags from tools #1392

Merged
merged 1 commit into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tools/android.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import sys
import my_spawn
import common_compiler_flags
from SCons.Script import ARGUMENTS


Expand Down Expand Up @@ -118,3 +119,5 @@ def generate(env):
env.Append(LINKFLAGS=["--target=" + arch_info["target"] + env["android_api_level"], "-march=" + arch_info["march"]])

env.Append(CPPDEFINES=["ANDROID_ENABLED", "UNIX_ENABLED"])

common_compiler_flags.generate(env)
94 changes: 94 additions & 0 deletions tools/common_compiler_flags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import os
import subprocess
import sys


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")


def exists(env):
return True


def generate(env):
# Require C++17
if env.get("is_msvc", False):
env.Append(CXXFLAGS=["/std:c++17"])
else:
env.Append(CXXFLAGS=["-std=c++17"])

# Disable exception handling. Godot doesn't use exceptions anywhere, and this
# saves around 20% of binary size and very significant build time.
if env["disable_exceptions"]:
if env.get("is_msvc", False):
env.Append(CPPDEFINES=[("_HAS_EXCEPTIONS", 0)])
else:
env.Append(CXXFLAGS=["-fno-exceptions"])
elif env.get("is_msvc", False):
env.Append(CXXFLAGS=["/EHsc"])

if not env.get("is_msvc", False):
if env["symbols_visibility"] == "visible":
env.Append(CCFLAGS=["-fvisibility=default"])
env.Append(LINKFLAGS=["-fvisibility=default"])
elif env["symbols_visibility"] == "hidden":
env.Append(CCFLAGS=["-fvisibility=hidden"])
env.Append(LINKFLAGS=["-fvisibility=hidden"])

# 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"])
env.Append(LINKFLAGS=["/DEBUG:FULL"])

if env["optimize"] == "speed":
env.Append(CCFLAGS=["/O2"])
env.Append(LINKFLAGS=["/OPT:REF"])
elif env["optimize"] == "speed_trace":
env.Append(CCFLAGS=["/O2"])
env.Append(LINKFLAGS=["/OPT:REF", "/OPT:NOICF"])
elif env["optimize"] == "size":
env.Append(CCFLAGS=["/O1"])
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"])
# `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces.
elif env["optimize"] == "speed_trace":
env.Append(CCFLAGS=["-O2"])
elif env["optimize"] == "size":
env.Append(CCFLAGS=["-Os"])
elif env["optimize"] == "debug":
env.Append(CCFLAGS=["-Og"])
elif env["optimize"] == "none":
env.Append(CCFLAGS=["-O0"])
100 changes: 67 additions & 33 deletions tools/godotcpp.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import os, sys, platform

from SCons.Variables import EnumVariable, PathVariable, BoolVariable
from SCons.Variables.BoolVariable import _text2bool
from SCons.Tool import Tool
from SCons.Builder import Builder
from SCons.Errors import UserError
from SCons.Script import ARGUMENTS


from binding_generator import scons_generate_bindings, scons_emit_files

Expand All @@ -14,6 +17,17 @@ def add_sources(sources, dir, extension):
sources.append(dir + "/" + f)


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.
"""
cmdline_val = ARGUMENTS.get(option)
if cmdline_val is not None:
return _text2bool(cmdline_val)
else:
return default


def normalize_path(val, env):
return val if os.path.isabs(val) else os.path.join(env.Dir("#").abspath, val)

Expand Down Expand Up @@ -230,16 +244,23 @@ def options(opts, env):
)
)

opts.Add(
EnumVariable(
"optimize",
"The desired optimization flags",
"speed_trace",
("none", "custom", "debug", "speed", "speed_trace", "size"),
)
)
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))

# Add platform options (custom tools can override platforms)
for pl in sorted(set(platforms + custom_platforms)):
tool = Tool(pl, toolpath=get_platform_tools_paths(env))
if hasattr(tool, "options"):
tool.options(opts)

# Targets flags tool (optimizations, debug symbols)
target_tool = Tool("targets", toolpath=["tools"])
target_tool.options(opts)


def generate(env):
# Default num_jobs to local cpu count if not user specified.
Expand Down Expand Up @@ -286,43 +307,56 @@ def generate(env):

print("Building for architecture " + env["arch"] + " on platform " + env["platform"])

if env.get("use_hot_reload") is None:
env["use_hot_reload"] = env["target"] != "template_release"
if env["use_hot_reload"]:
env.Append(CPPDEFINES=["HOT_RELOAD_ENABLED"])
# These defaults may be needed by platform tools
env.use_hot_reload = env.get("use_hot_reload", env["target"] != "template_release")
env.editor_build = env["target"] == "editor"
env.dev_build = env["dev_build"]
env.debug_features = env["target"] in ["editor", "template_debug"]

if env.dev_build:
opt_level = "none"
elif env.debug_features:
opt_level = "speed_trace"
else: # Release
opt_level = "speed"

env["optimize"] = ARGUMENTS.get("optimize", opt_level)
env["debug_symbols"] = get_cmdline_bool("debug_symbols", env.dev_build)

tool = Tool(env["platform"], toolpath=get_platform_tools_paths(env))

if tool is None or not tool.exists(env):
raise ValueError("Required toolchain not found for platform " + env["platform"])

tool.generate(env)
target_tool = Tool("targets", toolpath=["tools"])
target_tool.generate(env)

# Disable exception handling. Godot doesn't use exceptions anywhere, and this
# saves around 20% of binary size and very significant build time.
if env["disable_exceptions"]:
if env.get("is_msvc", False):
env.Append(CPPDEFINES=[("_HAS_EXCEPTIONS", 0)])
else:
env.Append(CXXFLAGS=["-fno-exceptions"])
elif env.get("is_msvc", False):
env.Append(CXXFLAGS=["/EHsc"])

if not env.get("is_msvc", False):
if env["symbols_visibility"] == "visible":
env.Append(CCFLAGS=["-fvisibility=default"])
env.Append(LINKFLAGS=["-fvisibility=default"])
elif env["symbols_visibility"] == "hidden":
env.Append(CCFLAGS=["-fvisibility=hidden"])
env.Append(LINKFLAGS=["-fvisibility=hidden"])

# Require C++17
if env.get("is_msvc", False):
env.Append(CXXFLAGS=["/std:c++17"])

if env.use_hot_reload:
env.Append(CPPDEFINES=["HOT_RELOAD_ENABLED"])

if env.editor_build:
env.Append(CPPDEFINES=["TOOLS_ENABLED"])

# 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.
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:
env.Append(CXXFLAGS=["-std=c++17"])
# Disable assert() for production targets (only used in thirdparty code).
env.Append(CPPDEFINES=["NDEBUG"])

if env["precision"] == "double":
env.Append(CPPDEFINES=["REAL_T_IS_DOUBLE"])
Expand Down
3 changes: 3 additions & 0 deletions tools/ios.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import sys
import subprocess
import common_compiler_flags
from SCons.Variables import *

if sys.version_info < (3,):
Expand Down Expand Up @@ -104,3 +105,5 @@ def generate(env):
env.Append(LINKFLAGS=["-isysroot", env["IOS_SDK_PATH"], "-F" + env["IOS_SDK_PATH"]])

env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED"])

common_compiler_flags.generate(env)
5 changes: 4 additions & 1 deletion tools/linux.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import common_compiler_flags
from SCons.Variables import *
from SCons.Tool import clang, clangxx

Expand All @@ -14,7 +15,7 @@ def generate(env):
if env["use_llvm"]:
clang.generate(env)
clangxx.generate(env)
elif env["use_hot_reload"]:
elif env.use_hot_reload:
# Required for extensions to truly unload.
env.Append(CXXFLAGS=["-fno-gnu-unique"])

Expand All @@ -37,3 +38,5 @@ def generate(env):
env.Append(LINKFLAGS=["-march=rv64gc"])

env.Append(CPPDEFINES=["LINUX_ENABLED", "UNIX_ENABLED"])

common_compiler_flags.generate(env)
3 changes: 3 additions & 0 deletions tools/macos.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import os
import sys
import common_compiler_flags


def has_osxcross():
Expand Down Expand Up @@ -70,3 +71,5 @@ def generate(env):
)

env.Append(CPPDEFINES=["MACOS_ENABLED", "UNIX_ENABLED"])

common_compiler_flags.generate(env)
Loading
Loading