@@ -194,6 +194,7 @@ def get_opts():
194
194
),
195
195
BoolVariable ("use_mingw" , "Use the Mingw compiler, even if MSVC is installed." , False ),
196
196
BoolVariable ("use_llvm" , "Use the LLVM compiler" , False ),
197
+ BoolVariable ("use_dwarf" , "Produce DWARF debug symbols instead of PDB when using the LLVM compiler" , False ),
197
198
BoolVariable ("use_static_cpp" , "Link MinGW/MSVC C++ runtime libraries statically" , True ),
198
199
BoolVariable ("use_asan" , "Use address sanitizer (ASAN)" , False ),
199
200
BoolVariable ("use_ubsan" , "Use LLVM compiler undefined behavior sanitizer (UBSAN)" , False ),
@@ -364,6 +365,34 @@ def setup_mingw(env: "SConsEnvironment"):
364
365
print ("Using MinGW, arch %s" % (env ["arch" ]))
365
366
366
367
368
+ def setup_llvm (env ):
369
+ """Set up env for use with clang"""
370
+
371
+ Version = False
372
+
373
+ try :
374
+ out = subprocess .Popen (
375
+ "clang --version" ,
376
+ shell = True ,
377
+ encoding = "utf-8" ,
378
+ stderr = subprocess .PIPE ,
379
+ stdout = subprocess .PIPE ,
380
+ )
381
+ outs , errs = out .communicate ()
382
+ if out .returncode == 0 :
383
+ import re
384
+
385
+ Version = re .search ("^clang version ([0-9\\ .]+)\n " , outs ).group (1 )
386
+ except Exception :
387
+ pass
388
+
389
+ if not Version :
390
+ print_error ("CLang could not be found, make sure it is installed and in PATH." )
391
+ sys .exit (255 )
392
+
393
+ print ("Found clang version %s, arch %s" % (Version , env ["arch" ]))
394
+
395
+
367
396
def configure_msvc (env : "SConsEnvironment" , vcvars_msvc_config ):
368
397
"""Configure env to work with MSVC"""
369
398
@@ -947,6 +976,201 @@ def configure_mingw(env: "SConsEnvironment"):
947
976
env .Append (BUILDERS = {"RES" : env .Builder (action = build_res_file , suffix = ".o" , src_suffix = ".rc" )})
948
977
949
978
979
+ def configure_llvm (env : "SConsEnvironment" ):
980
+ env .use_windows_spawn_fix ()
981
+
982
+ if env ["target" ] != "template_release" and env .dev_build :
983
+ # Allow big objects. It's supposed not to have drawbacks but seems to break
984
+ # GCC LTO, so enabling for debug builds only (which are not built with LTO
985
+ # and are the only ones with too big objects).
986
+ env .Append (CCFLAGS = ["-Wa,-mbig-obj" ])
987
+
988
+ if env ["windows_subsystem" ] == "gui" :
989
+ env .Append (LINKFLAGS = ["-Wl,-subsystem:windows" ])
990
+ else :
991
+ env .Append (LINKFLAGS = ["-Wl,-subsystem:console" ])
992
+ env .AppendUnique (CPPDEFINES = ["WINDOWS_SUBSYSTEM_CONSOLE" ])
993
+
994
+ ## Compiler configuration
995
+
996
+ if os .name != "nt" :
997
+ env ["PROGSUFFIX" ] = env ["PROGSUFFIX" ] + ".exe" # for linux cross-compilation
998
+
999
+ if env ["arch" ] == "x86_32" :
1000
+ if env ["use_static_cpp" ]:
1001
+ env .Append (LINKFLAGS = ["-static" ])
1002
+ env .Append (LINKFLAGS = ["-static-libgcc" ])
1003
+ env .Append (LINKFLAGS = ["-static-libstdc++" ])
1004
+ else :
1005
+ if env ["use_static_cpp" ]:
1006
+ env .Append (LINKFLAGS = ["-static" ])
1007
+
1008
+ # FIXME: Temporarily disabled, because llvm doesn't like the assembly
1009
+ # if env["arch"] in ["x86_32", "x86_64"]:
1010
+ # env["x86_libtheora_opt_gcc"] = True
1011
+
1012
+ env .Append (CCFLAGS = ["-ffp-contract=off" ])
1013
+
1014
+ env ["CC" ] = "clang"
1015
+ env ["CXX" ] = "clang++"
1016
+ env ["AS" ] = "clang" # CLang can act as an assembler, so it is not usually bundled with llvm-as
1017
+ env ["AR" ] = "llvm-ar"
1018
+ env ["RANLIB" ] = "llvm-ranlib"
1019
+ env .extra_suffix = ".llvm" + env .extra_suffix
1020
+
1021
+ ## LTO
1022
+
1023
+ if env ["lto" ] == "auto" : # Full LTO for production with LLVM.
1024
+ env ["lto" ] = "full"
1025
+
1026
+ if env ["lto" ] != "none" :
1027
+ if env ["lto" ] == "thin" :
1028
+ env .Append (LINKFLAGS = ["-flto=thin" ])
1029
+ else :
1030
+ env .Append (LINKFLAGS = ["-flto" ])
1031
+
1032
+ if env ["use_asan" ]:
1033
+ env .Append (LINKFLAGS = ["-Wl,-stack:" + str (STACK_SIZE_SANITIZERS )])
1034
+ else :
1035
+ env .Append (LINKFLAGS = ["-Wl,-stack:" + str (STACK_SIZE )])
1036
+
1037
+ # Sanitizers
1038
+
1039
+ if int (env ["target_win_version" ], 16 ) < 0x0601 :
1040
+ print_error ("`target_win_version` should be 0x0601 or higher (Windows 7)." )
1041
+ sys .exit (255 )
1042
+
1043
+ if env ["use_asan" ] or env ["use_ubsan" ]:
1044
+ if env ["arch" ] not in ["x86_32" , "x86_64" ]:
1045
+ print ("Sanitizers are only supported for x86_32 and x86_64." )
1046
+ sys .exit (255 )
1047
+
1048
+ env .extra_suffix += ".san"
1049
+ env .AppendUnique (CPPDEFINES = ["SANITIZERS_ENABLED" ])
1050
+ san_flags = []
1051
+ if env ["use_asan" ]:
1052
+ san_flags .append ("-fsanitize=address" )
1053
+ if env ["use_ubsan" ]:
1054
+ san_flags .append ("-fsanitize=undefined" )
1055
+ # Disable the vptr check since it gets triggered on any COM interface calls.
1056
+ san_flags .append ("-fno-sanitize=vptr" )
1057
+ env .Append (CFLAGS = san_flags )
1058
+ env .Append (CCFLAGS = san_flags )
1059
+ env .Append (LINKFLAGS = san_flags )
1060
+
1061
+ if os .name == "nt" and methods ._colorize :
1062
+ env .Append (CCFLAGS = ["$(-fansi-escape-codes$)" , "$(-fcolor-diagnostics$)" ])
1063
+
1064
+ # FIXME: Using thin AR causes link to fail. Possible incompatibility with MSVC linker. Force use of lld instead?
1065
+ # if get_is_ar_thin_supported(env):
1066
+ # env.Append(ARFLAGS=["--thin"])
1067
+
1068
+ ## Compile flags
1069
+
1070
+ env .Append (CPPDEFINES = [])
1071
+ env .Append (
1072
+ CPPDEFINES = [
1073
+ "WINDOWS_ENABLED" ,
1074
+ "WASAPI_ENABLED" ,
1075
+ "WINMIDI_ENABLED" ,
1076
+ "TYPED_METHOD_BIND" ,
1077
+ "WIN32" ,
1078
+ # Prevent Windows SDK headers from defining min and max macros,
1079
+ # which conflict with min and max templates
1080
+ "NOMINMAX" ,
1081
+ # The inline assembly trick used for older MSVC versions does not work for LLVM.
1082
+ # Fall back to portable implementation.
1083
+ # An alternative is to define __MINGW32__ but this would influence other libraries
1084
+ "R128_STDC_ONLY" ,
1085
+ ("WINVER" , env ["target_win_version" ]),
1086
+ ("_WIN32_WINNT" , env ["target_win_version" ]),
1087
+ ]
1088
+ )
1089
+ env .Append (
1090
+ LIBS = [
1091
+ "avrt" ,
1092
+ "bcrypt" ,
1093
+ "crypt32" ,
1094
+ "dinput8" ,
1095
+ "dsound" ,
1096
+ "dwmapi" ,
1097
+ "dwrite" ,
1098
+ "dxguid" ,
1099
+ "gdi32" ,
1100
+ "imm32" ,
1101
+ "iphlpapi" ,
1102
+ "kernel32" ,
1103
+ "ntdll" ,
1104
+ "ole32" ,
1105
+ "oleaut32" ,
1106
+ "sapi" ,
1107
+ "shell32" ,
1108
+ "advapi32" ,
1109
+ "shlwapi" ,
1110
+ "user32" ,
1111
+ "uuid" ,
1112
+ "wbemuuid" ,
1113
+ "winmm" ,
1114
+ "ws2_32" ,
1115
+ "wsock32" ,
1116
+ ]
1117
+ )
1118
+
1119
+ if env .debug_features :
1120
+ env .Append (LIBS = ["psapi" , "dbghelp" ])
1121
+
1122
+ if env ["vulkan" ]:
1123
+ env .Append (CPPDEFINES = ["VULKAN_ENABLED" , "RD_ENABLED" ])
1124
+ if not env ["use_volk" ]:
1125
+ env .Append (LIBS = ["vulkan" ])
1126
+
1127
+ if env ["d3d12" ]:
1128
+ # Check whether we have d3d12 dependencies installed.
1129
+ if not os .path .exists (env ["mesa_libs" ]):
1130
+ print_error (
1131
+ "The Direct3D 12 rendering driver requires dependencies to be installed.\n "
1132
+ "You can install them by running `python misc\\ scripts\\ install_d3d12_sdk_windows.py`.\n "
1133
+ "See the documentation for more information:\n \t "
1134
+ "https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_windows.html"
1135
+ )
1136
+ sys .exit (255 )
1137
+
1138
+ env .AppendUnique (CPPDEFINES = ["D3D12_ENABLED" , "RD_ENABLED" ])
1139
+ env .Append (LIBS = ["dxgi" , "dxguid" ])
1140
+
1141
+ # PIX
1142
+ if env ["arch" ] not in ["x86_64" , "arm64" ] or env ["pix_path" ] == "" or not os .path .exists (env ["pix_path" ]):
1143
+ env ["use_pix" ] = False
1144
+
1145
+ if env ["use_pix" ]:
1146
+ arch_subdir = "arm64" if env ["arch" ] == "arm64" else "x64"
1147
+
1148
+ env .Append (LIBPATH = [env ["pix_path" ] + "/bin/" + arch_subdir ])
1149
+ env .Append (LIBS = ["WinPixEventRuntime" ])
1150
+
1151
+ env .Append (LIBPATH = [env ["mesa_libs" ] + "/bin" ])
1152
+ env .Append (LIBS = ["libNIR.windows." + env ["arch" ]])
1153
+ env .Append (LIBS = ["version" ]) # Mesa dependency.
1154
+
1155
+ if env ["opengl3" ]:
1156
+ env .Append (CPPDEFINES = ["GLES3_ENABLED" ])
1157
+ if env ["angle_libs" ] != "" :
1158
+ env .AppendUnique (CPPDEFINES = ["EGL_STATIC" ])
1159
+ env .Append (LIBPATH = [env ["angle_libs" ]])
1160
+ env .Append (
1161
+ LIBS = [
1162
+ "EGL.windows." + env ["arch" ],
1163
+ "GLES.windows." + env ["arch" ],
1164
+ "ANGLE.windows." + env ["arch" ],
1165
+ ]
1166
+ )
1167
+ env .Append (LIBS = ["dxgi" , "d3d9" , "d3d11" ])
1168
+ env .Prepend (CPPPATH = ["#thirdparty/angle/include" ])
1169
+
1170
+ # resrc
1171
+ env .Append (BUILDERS = {"RES" : env .Builder (action = build_res_file , suffix = ".o" , src_suffix = ".rc" )})
1172
+
1173
+
950
1174
def configure (env : "SConsEnvironment" ):
951
1175
# Validate arch.
952
1176
supported_arches = ["x86_32" , "x86_64" , "arm32" , "arm64" ]
@@ -965,7 +1189,10 @@ def configure(env: "SConsEnvironment"):
965
1189
env ["ENV" ]["TMP" ] = os .environ ["TMP" ]
966
1190
967
1191
# First figure out which compiler, version, and target arch we're using
968
- if os .getenv ("VCINSTALLDIR" ) and detect_build_env_arch () and not env ["use_mingw" ]:
1192
+ if env ["use_llvm" ] and not env ["use_mingw" ]:
1193
+ setup_llvm (env )
1194
+ env .msvc = False
1195
+ elif os .getenv ("VCINSTALLDIR" ) and detect_build_env_arch () and not env ["use_mingw" ]:
969
1196
setup_msvc_manual (env )
970
1197
env .msvc = True
971
1198
vcvars_msvc_config = True
@@ -981,5 +1208,8 @@ def configure(env: "SConsEnvironment"):
981
1208
if env .msvc :
982
1209
configure_msvc (env , vcvars_msvc_config )
983
1210
1211
+ elif env ["use_llvm" ]:
1212
+ configure_llvm (env )
1213
+
984
1214
else : # MinGW
985
1215
configure_mingw (env )
0 commit comments