2
0

common_compiler_flags.py 5.0 KB

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