common_compiler_flags.py 4.6 KB

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