|
| 1 | +import os |
| 2 | +import subprocess |
| 3 | + |
| 4 | + |
| 5 | +def using_clang(env): |
| 6 | + return "clang" in os.path.basename(env["CC"]) |
| 7 | + |
| 8 | + |
| 9 | +def is_vanilla_clang(env): |
| 10 | + if not using_clang(env): |
| 11 | + return False |
| 12 | + try: |
| 13 | + version = subprocess.check_output([env.subst(env["CXX"]), "--version"]).strip().decode("utf-8") |
| 14 | + except (subprocess.CalledProcessError, OSError): |
| 15 | + print("Couldn't parse CXX environment variable to infer compiler version.") |
| 16 | + return False |
| 17 | + return not version.startswith("Apple") |
| 18 | + |
| 19 | + |
| 20 | +def exists(env): |
| 21 | + return True |
| 22 | + |
| 23 | + |
| 24 | +def generate(env): |
| 25 | + # Require C++17 |
| 26 | + if env.get("is_msvc", False): |
| 27 | + env.Append(CXXFLAGS=["/std:c++17"]) |
| 28 | + else: |
| 29 | + env.Append(CXXFLAGS=["-std=c++17"]) |
| 30 | + |
| 31 | + # Disable exception handling. Godot doesn't use exceptions anywhere, and this |
| 32 | + # saves around 20% of binary size and very significant build time. |
| 33 | + if env["disable_exceptions"]: |
| 34 | + if env.get("is_msvc", False): |
| 35 | + env.Append(CPPDEFINES=[("_HAS_EXCEPTIONS", 0)]) |
| 36 | + else: |
| 37 | + env.Append(CXXFLAGS=["-fno-exceptions"]) |
| 38 | + elif env.get("is_msvc", False): |
| 39 | + env.Append(CXXFLAGS=["/EHsc"]) |
| 40 | + |
| 41 | + if not env.get("is_msvc", False): |
| 42 | + if env["symbols_visibility"] == "visible": |
| 43 | + env.Append(CCFLAGS=["-fvisibility=default"]) |
| 44 | + env.Append(LINKFLAGS=["-fvisibility=default"]) |
| 45 | + elif env["symbols_visibility"] == "hidden": |
| 46 | + env.Append(CCFLAGS=["-fvisibility=hidden"]) |
| 47 | + env.Append(LINKFLAGS=["-fvisibility=hidden"]) |
| 48 | + |
| 49 | + # Set optimize and debug_symbols flags. |
| 50 | + # "custom" means do nothing and let users set their own optimization flags. |
| 51 | + if env.get("is_msvc", False): |
| 52 | + if env["debug_symbols"]: |
| 53 | + env.Append(CCFLAGS=["/Zi", "/FS"]) |
| 54 | + env.Append(LINKFLAGS=["/DEBUG:FULL"]) |
| 55 | + |
| 56 | + if env["optimize"] == "speed": |
| 57 | + env.Append(CCFLAGS=["/O2"]) |
| 58 | + env.Append(LINKFLAGS=["/OPT:REF"]) |
| 59 | + elif env["optimize"] == "speed_trace": |
| 60 | + env.Append(CCFLAGS=["/O2"]) |
| 61 | + env.Append(LINKFLAGS=["/OPT:REF", "/OPT:NOICF"]) |
| 62 | + elif env["optimize"] == "size": |
| 63 | + env.Append(CCFLAGS=["/O1"]) |
| 64 | + env.Append(LINKFLAGS=["/OPT:REF"]) |
| 65 | + elif env["optimize"] == "debug" or env["optimize"] == "none": |
| 66 | + env.Append(CCFLAGS=["/Od"]) |
| 67 | + else: |
| 68 | + if env["debug_symbols"]: |
| 69 | + # Adding dwarf-4 explicitly makes stacktraces work with clang builds, |
| 70 | + # otherwise addr2line doesn't understand them. |
| 71 | + env.Append(CCFLAGS=["-gdwarf-4"]) |
| 72 | + if env.dev_build: |
| 73 | + env.Append(CCFLAGS=["-g3"]) |
| 74 | + else: |
| 75 | + env.Append(CCFLAGS=["-g2"]) |
| 76 | + else: |
| 77 | + if using_clang(env) and not is_vanilla_clang(env): |
| 78 | + # Apple Clang, its linker doesn't like -s. |
| 79 | + env.Append(LINKFLAGS=["-Wl,-S", "-Wl,-x", "-Wl,-dead_strip"]) |
| 80 | + else: |
| 81 | + env.Append(LINKFLAGS=["-s"]) |
| 82 | + |
| 83 | + if env["optimize"] == "speed": |
| 84 | + env.Append(CCFLAGS=["-O3"]) |
| 85 | + # `-O2` is friendlier to debuggers than `-O3`, leading to better crash backtraces. |
| 86 | + elif env["optimize"] == "speed_trace": |
| 87 | + env.Append(CCFLAGS=["-O2"]) |
| 88 | + elif env["optimize"] == "size": |
| 89 | + env.Append(CCFLAGS=["-Os"]) |
| 90 | + elif env["optimize"] == "debug": |
| 91 | + env.Append(CCFLAGS=["-Og"]) |
| 92 | + elif env["optimize"] == "none": |
| 93 | + env.Append(CCFLAGS=["-O0"]) |
0 commit comments