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