@@ -194,6 +194,14 @@ def _find_exe(exe, paths=None):
194
194
'win-arm64' : 'x86_arm64'
195
195
}
196
196
197
+ # A map keyed by get_platform() return values to value accepted by
198
+ # clang as the triple.
199
+ PLAT_TO_LLVM_TARGETS = {
200
+ 'win32' : 'i686' ,
201
+ 'win-amd64' : 'x86_64' ,
202
+ 'win-arm64' : 'aarch64' ,
203
+ }
204
+
197
205
# A set containing the DLLs that are guaranteed to be available for
198
206
# all micro versions of this Python version. Known extension
199
207
# dependencies that are not in this set will be copied to the output
@@ -231,11 +239,12 @@ class MSVCCompiler(CCompiler) :
231
239
exe_extension = '.exe'
232
240
233
241
234
- def __init__ (self , verbose = 0 , dry_run = 0 , force = 0 ):
242
+ def __init__ (self , verbose = 0 , dry_run = 0 , force = 0 , use_clang_cl = False ):
235
243
CCompiler .__init__ (self , verbose , dry_run , force )
236
244
# target platform (.plat_name is consistent with 'bdist')
237
245
self .plat_name = None
238
246
self .initialized = False
247
+ self .use_clang_cl = use_clang_cl
239
248
240
249
def initialize (self , plat_name = None ):
241
250
# multi-init means we would need to check platform same each time...
@@ -257,6 +266,8 @@ def initialize(self, plat_name=None):
257
266
258
267
self ._paths = vc_env .get ('path' , '' )
259
268
paths = self ._paths .split (os .pathsep )
269
+ if self .use_clang_cl :
270
+ self .cc = _find_exe ("clang-cl.exe" )
260
271
self .cc = _find_exe ("cl.exe" , paths )
261
272
self .linker = _find_exe ("link.exe" , paths )
262
273
self .lib = _find_exe ("lib.exe" , paths )
@@ -295,6 +306,16 @@ def initialize(self, plat_name=None):
295
306
ldflags_debug = [
296
307
'/nologo' , '/INCREMENTAL:NO' , '/LTCG' , '/DEBUG:FULL'
297
308
]
309
+ if self .use_clang_cl :
310
+ # Add target for clang
311
+ target_flag = "{}-pc-windows-msvc" .format (PLAT_TO_LLVM_TARGETS [plat_name ])
312
+ self .compile_options .append (target_flag )
313
+ self .compile_options_debug .append (target_flag )
314
+ # Remove whole program optimization flags to avoid warnings about
315
+ # unrecognized options
316
+ self .compile_options .remove ('/GL' )
317
+ ldflags .remove ('/LTCG' )
318
+ ldflags_debug .remove ('/LTCG' )
298
319
299
320
self .ldflags_exe = [* ldflags , '/MANIFEST:EMBED,ID=1' ]
300
321
self .ldflags_exe_debug = [* ldflags_debug , '/MANIFEST:EMBED,ID=1' ]
@@ -587,3 +608,10 @@ def find_library_file(self, dirs, lib, debug=0):
587
608
else :
588
609
# Oops, didn't find it in *any* of 'dirs'
589
610
return None
611
+
612
+
613
+ class ClangMSVCCompiler (MSVCCompiler ):
614
+ compiler_type = 'clang-cl'
615
+
616
+ def __init__ (self , verbose = 0 , dry_run = 0 , force = 0 ):
617
+ MSVCCompiler .__init__ (self , verbose , dry_run , force , True )
0 commit comments