common_compiler_flags.py 3.4 KB

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