Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keewenaw
GitHub Repository: keewenaw/ethereum-wallet-cracker
Path: blob/main/test/lib/python3.9/site-packages/setuptools/_distutils/msvccompiler.py
4799 views
1
"""distutils.msvccompiler
2
3
Contains MSVCCompiler, an implementation of the abstract CCompiler class
4
for the Microsoft Visual Studio.
5
"""
6
7
# Written by Perry Stoll
8
# hacked by Robin Becker and Thomas Heller to do a better job of
9
# finding DevStudio (through the registry)
10
11
import sys, os
12
from distutils.errors import \
13
DistutilsExecError, DistutilsPlatformError, \
14
CompileError, LibError, LinkError
15
from distutils.ccompiler import \
16
CCompiler, gen_lib_options
17
from distutils import log
18
19
_can_read_reg = False
20
try:
21
import winreg
22
23
_can_read_reg = True
24
hkey_mod = winreg
25
26
RegOpenKeyEx = winreg.OpenKeyEx
27
RegEnumKey = winreg.EnumKey
28
RegEnumValue = winreg.EnumValue
29
RegError = winreg.error
30
31
except ImportError:
32
try:
33
import win32api
34
import win32con
35
_can_read_reg = True
36
hkey_mod = win32con
37
38
RegOpenKeyEx = win32api.RegOpenKeyEx
39
RegEnumKey = win32api.RegEnumKey
40
RegEnumValue = win32api.RegEnumValue
41
RegError = win32api.error
42
except ImportError:
43
log.info("Warning: Can't read registry to find the "
44
"necessary compiler setting\n"
45
"Make sure that Python modules winreg, "
46
"win32api or win32con are installed.")
47
pass
48
49
if _can_read_reg:
50
HKEYS = (hkey_mod.HKEY_USERS,
51
hkey_mod.HKEY_CURRENT_USER,
52
hkey_mod.HKEY_LOCAL_MACHINE,
53
hkey_mod.HKEY_CLASSES_ROOT)
54
55
def read_keys(base, key):
56
"""Return list of registry keys."""
57
try:
58
handle = RegOpenKeyEx(base, key)
59
except RegError:
60
return None
61
L = []
62
i = 0
63
while True:
64
try:
65
k = RegEnumKey(handle, i)
66
except RegError:
67
break
68
L.append(k)
69
i += 1
70
return L
71
72
def read_values(base, key):
73
"""Return dict of registry keys and values.
74
75
All names are converted to lowercase.
76
"""
77
try:
78
handle = RegOpenKeyEx(base, key)
79
except RegError:
80
return None
81
d = {}
82
i = 0
83
while True:
84
try:
85
name, value, type = RegEnumValue(handle, i)
86
except RegError:
87
break
88
name = name.lower()
89
d[convert_mbcs(name)] = convert_mbcs(value)
90
i += 1
91
return d
92
93
def convert_mbcs(s):
94
dec = getattr(s, "decode", None)
95
if dec is not None:
96
try:
97
s = dec("mbcs")
98
except UnicodeError:
99
pass
100
return s
101
102
class MacroExpander:
103
def __init__(self, version):
104
self.macros = {}
105
self.load_macros(version)
106
107
def set_macro(self, macro, path, key):
108
for base in HKEYS:
109
d = read_values(base, path)
110
if d:
111
self.macros["$(%s)" % macro] = d[key]
112
break
113
114
def load_macros(self, version):
115
vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version
116
self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir")
117
self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir")
118
net = r"Software\Microsoft\.NETFramework"
119
self.set_macro("FrameworkDir", net, "installroot")
120
try:
121
if version > 7.0:
122
self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1")
123
else:
124
self.set_macro("FrameworkSDKDir", net, "sdkinstallroot")
125
except KeyError as exc: #
126
raise DistutilsPlatformError(
127
"""Python was built with Visual Studio 2003;
128
extensions must be built with a compiler than can generate compatible binaries.
129
Visual Studio 2003 was not found on this system. If you have Cygwin installed,
130
you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""")
131
132
p = r"Software\Microsoft\NET Framework Setup\Product"
133
for base in HKEYS:
134
try:
135
h = RegOpenKeyEx(base, p)
136
except RegError:
137
continue
138
key = RegEnumKey(h, 0)
139
d = read_values(base, r"%s\%s" % (p, key))
140
self.macros["$(FrameworkVersion)"] = d["version"]
141
142
def sub(self, s):
143
for k, v in self.macros.items():
144
s = s.replace(k, v)
145
return s
146
147
def get_build_version():
148
"""Return the version of MSVC that was used to build Python.
149
150
For Python 2.3 and up, the version number is included in
151
sys.version. For earlier versions, assume the compiler is MSVC 6.
152
"""
153
prefix = "MSC v."
154
i = sys.version.find(prefix)
155
if i == -1:
156
return 6
157
i = i + len(prefix)
158
s, rest = sys.version[i:].split(" ", 1)
159
majorVersion = int(s[:-2]) - 6
160
if majorVersion >= 13:
161
# v13 was skipped and should be v14
162
majorVersion += 1
163
minorVersion = int(s[2:3]) / 10.0
164
# I don't think paths are affected by minor version in version 6
165
if majorVersion == 6:
166
minorVersion = 0
167
if majorVersion >= 6:
168
return majorVersion + minorVersion
169
# else we don't know what version of the compiler this is
170
return None
171
172
def get_build_architecture():
173
"""Return the processor architecture.
174
175
Possible results are "Intel" or "AMD64".
176
"""
177
178
prefix = " bit ("
179
i = sys.version.find(prefix)
180
if i == -1:
181
return "Intel"
182
j = sys.version.find(")", i)
183
return sys.version[i+len(prefix):j]
184
185
def normalize_and_reduce_paths(paths):
186
"""Return a list of normalized paths with duplicates removed.
187
188
The current order of paths is maintained.
189
"""
190
# Paths are normalized so things like: /a and /a/ aren't both preserved.
191
reduced_paths = []
192
for p in paths:
193
np = os.path.normpath(p)
194
# XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set.
195
if np not in reduced_paths:
196
reduced_paths.append(np)
197
return reduced_paths
198
199
200
class MSVCCompiler(CCompiler) :
201
"""Concrete class that implements an interface to Microsoft Visual C++,
202
as defined by the CCompiler abstract class."""
203
204
compiler_type = 'msvc'
205
206
# Just set this so CCompiler's constructor doesn't barf. We currently
207
# don't use the 'set_executables()' bureaucracy provided by CCompiler,
208
# as it really isn't necessary for this sort of single-compiler class.
209
# Would be nice to have a consistent interface with UnixCCompiler,
210
# though, so it's worth thinking about.
211
executables = {}
212
213
# Private class data (need to distinguish C from C++ source for compiler)
214
_c_extensions = ['.c']
215
_cpp_extensions = ['.cc', '.cpp', '.cxx']
216
_rc_extensions = ['.rc']
217
_mc_extensions = ['.mc']
218
219
# Needed for the filename generation methods provided by the
220
# base class, CCompiler.
221
src_extensions = (_c_extensions + _cpp_extensions +
222
_rc_extensions + _mc_extensions)
223
res_extension = '.res'
224
obj_extension = '.obj'
225
static_lib_extension = '.lib'
226
shared_lib_extension = '.dll'
227
static_lib_format = shared_lib_format = '%s%s'
228
exe_extension = '.exe'
229
230
def __init__(self, verbose=0, dry_run=0, force=0):
231
super().__init__(verbose, dry_run, force)
232
self.__version = get_build_version()
233
self.__arch = get_build_architecture()
234
if self.__arch == "Intel":
235
# x86
236
if self.__version >= 7:
237
self.__root = r"Software\Microsoft\VisualStudio"
238
self.__macros = MacroExpander(self.__version)
239
else:
240
self.__root = r"Software\Microsoft\Devstudio"
241
self.__product = "Visual Studio version %s" % self.__version
242
else:
243
# Win64. Assume this was built with the platform SDK
244
self.__product = "Microsoft SDK compiler %s" % (self.__version + 6)
245
246
self.initialized = False
247
248
def initialize(self):
249
self.__paths = []
250
if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
251
# Assume that the SDK set up everything alright; don't try to be
252
# smarter
253
self.cc = "cl.exe"
254
self.linker = "link.exe"
255
self.lib = "lib.exe"
256
self.rc = "rc.exe"
257
self.mc = "mc.exe"
258
else:
259
self.__paths = self.get_msvc_paths("path")
260
261
if len(self.__paths) == 0:
262
raise DistutilsPlatformError("Python was built with %s, "
263
"and extensions need to be built with the same "
264
"version of the compiler, but it isn't installed."
265
% self.__product)
266
267
self.cc = self.find_exe("cl.exe")
268
self.linker = self.find_exe("link.exe")
269
self.lib = self.find_exe("lib.exe")
270
self.rc = self.find_exe("rc.exe") # resource compiler
271
self.mc = self.find_exe("mc.exe") # message compiler
272
self.set_path_env_var('lib')
273
self.set_path_env_var('include')
274
275
# extend the MSVC path with the current path
276
try:
277
for p in os.environ['path'].split(';'):
278
self.__paths.append(p)
279
except KeyError:
280
pass
281
self.__paths = normalize_and_reduce_paths(self.__paths)
282
os.environ['path'] = ";".join(self.__paths)
283
284
self.preprocess_options = None
285
if self.__arch == "Intel":
286
self.compile_options = [ '/nologo', '/O2', '/MD', '/W3', '/GX' ,
287
'/DNDEBUG']
288
self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX',
289
'/Z7', '/D_DEBUG']
290
else:
291
# Win64
292
self.compile_options = [ '/nologo', '/O2', '/MD', '/W3', '/GS-' ,
293
'/DNDEBUG']
294
self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-',
295
'/Z7', '/D_DEBUG']
296
297
self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO']
298
if self.__version >= 7:
299
self.ldflags_shared_debug = [
300
'/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
301
]
302
else:
303
self.ldflags_shared_debug = [
304
'/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG'
305
]
306
self.ldflags_static = [ '/nologo']
307
308
self.initialized = True
309
310
# -- Worker methods ------------------------------------------------
311
312
def object_filenames(self,
313
source_filenames,
314
strip_dir=0,
315
output_dir=''):
316
# Copied from ccompiler.py, extended to return .res as 'object'-file
317
# for .rc input file
318
if output_dir is None: output_dir = ''
319
obj_names = []
320
for src_name in source_filenames:
321
(base, ext) = os.path.splitext (src_name)
322
base = os.path.splitdrive(base)[1] # Chop off the drive
323
base = base[os.path.isabs(base):] # If abs, chop off leading /
324
if ext not in self.src_extensions:
325
# Better to raise an exception instead of silently continuing
326
# and later complain about sources and targets having
327
# different lengths
328
raise CompileError ("Don't know how to compile %s" % src_name)
329
if strip_dir:
330
base = os.path.basename (base)
331
if ext in self._rc_extensions:
332
obj_names.append (os.path.join (output_dir,
333
base + self.res_extension))
334
elif ext in self._mc_extensions:
335
obj_names.append (os.path.join (output_dir,
336
base + self.res_extension))
337
else:
338
obj_names.append (os.path.join (output_dir,
339
base + self.obj_extension))
340
return obj_names
341
342
343
def compile(self, sources,
344
output_dir=None, macros=None, include_dirs=None, debug=0,
345
extra_preargs=None, extra_postargs=None, depends=None):
346
347
if not self.initialized:
348
self.initialize()
349
compile_info = self._setup_compile(output_dir, macros, include_dirs,
350
sources, depends, extra_postargs)
351
macros, objects, extra_postargs, pp_opts, build = compile_info
352
353
compile_opts = extra_preargs or []
354
compile_opts.append ('/c')
355
if debug:
356
compile_opts.extend(self.compile_options_debug)
357
else:
358
compile_opts.extend(self.compile_options)
359
360
for obj in objects:
361
try:
362
src, ext = build[obj]
363
except KeyError:
364
continue
365
if debug:
366
# pass the full pathname to MSVC in debug mode,
367
# this allows the debugger to find the source file
368
# without asking the user to browse for it
369
src = os.path.abspath(src)
370
371
if ext in self._c_extensions:
372
input_opt = "/Tc" + src
373
elif ext in self._cpp_extensions:
374
input_opt = "/Tp" + src
375
elif ext in self._rc_extensions:
376
# compile .RC to .RES file
377
input_opt = src
378
output_opt = "/fo" + obj
379
try:
380
self.spawn([self.rc] + pp_opts +
381
[output_opt] + [input_opt])
382
except DistutilsExecError as msg:
383
raise CompileError(msg)
384
continue
385
elif ext in self._mc_extensions:
386
# Compile .MC to .RC file to .RES file.
387
# * '-h dir' specifies the directory for the
388
# generated include file
389
# * '-r dir' specifies the target directory of the
390
# generated RC file and the binary message resource
391
# it includes
392
#
393
# For now (since there are no options to change this),
394
# we use the source-directory for the include file and
395
# the build directory for the RC file and message
396
# resources. This works at least for win32all.
397
h_dir = os.path.dirname(src)
398
rc_dir = os.path.dirname(obj)
399
try:
400
# first compile .MC to .RC and .H file
401
self.spawn([self.mc] +
402
['-h', h_dir, '-r', rc_dir] + [src])
403
base, _ = os.path.splitext (os.path.basename (src))
404
rc_file = os.path.join (rc_dir, base + '.rc')
405
# then compile .RC to .RES file
406
self.spawn([self.rc] +
407
["/fo" + obj] + [rc_file])
408
409
except DistutilsExecError as msg:
410
raise CompileError(msg)
411
continue
412
else:
413
# how to handle this file?
414
raise CompileError("Don't know how to compile %s to %s"
415
% (src, obj))
416
417
output_opt = "/Fo" + obj
418
try:
419
self.spawn([self.cc] + compile_opts + pp_opts +
420
[input_opt, output_opt] +
421
extra_postargs)
422
except DistutilsExecError as msg:
423
raise CompileError(msg)
424
425
return objects
426
427
428
def create_static_lib(self,
429
objects,
430
output_libname,
431
output_dir=None,
432
debug=0,
433
target_lang=None):
434
435
if not self.initialized:
436
self.initialize()
437
(objects, output_dir) = self._fix_object_args(objects, output_dir)
438
output_filename = self.library_filename(output_libname,
439
output_dir=output_dir)
440
441
if self._need_link(objects, output_filename):
442
lib_args = objects + ['/OUT:' + output_filename]
443
if debug:
444
pass # XXX what goes here?
445
try:
446
self.spawn([self.lib] + lib_args)
447
except DistutilsExecError as msg:
448
raise LibError(msg)
449
else:
450
log.debug("skipping %s (up-to-date)", output_filename)
451
452
453
def link(self,
454
target_desc,
455
objects,
456
output_filename,
457
output_dir=None,
458
libraries=None,
459
library_dirs=None,
460
runtime_library_dirs=None,
461
export_symbols=None,
462
debug=0,
463
extra_preargs=None,
464
extra_postargs=None,
465
build_temp=None,
466
target_lang=None):
467
468
if not self.initialized:
469
self.initialize()
470
(objects, output_dir) = self._fix_object_args(objects, output_dir)
471
fixed_args = self._fix_lib_args(libraries, library_dirs,
472
runtime_library_dirs)
473
(libraries, library_dirs, runtime_library_dirs) = fixed_args
474
475
if runtime_library_dirs:
476
self.warn ("I don't know what to do with 'runtime_library_dirs': "
477
+ str (runtime_library_dirs))
478
479
lib_opts = gen_lib_options(self,
480
library_dirs, runtime_library_dirs,
481
libraries)
482
if output_dir is not None:
483
output_filename = os.path.join(output_dir, output_filename)
484
485
if self._need_link(objects, output_filename):
486
if target_desc == CCompiler.EXECUTABLE:
487
if debug:
488
ldflags = self.ldflags_shared_debug[1:]
489
else:
490
ldflags = self.ldflags_shared[1:]
491
else:
492
if debug:
493
ldflags = self.ldflags_shared_debug
494
else:
495
ldflags = self.ldflags_shared
496
497
export_opts = []
498
for sym in (export_symbols or []):
499
export_opts.append("/EXPORT:" + sym)
500
501
ld_args = (ldflags + lib_opts + export_opts +
502
objects + ['/OUT:' + output_filename])
503
504
# The MSVC linker generates .lib and .exp files, which cannot be
505
# suppressed by any linker switches. The .lib files may even be
506
# needed! Make sure they are generated in the temporary build
507
# directory. Since they have different names for debug and release
508
# builds, they can go into the same directory.
509
if export_symbols is not None:
510
(dll_name, dll_ext) = os.path.splitext(
511
os.path.basename(output_filename))
512
implib_file = os.path.join(
513
os.path.dirname(objects[0]),
514
self.library_filename(dll_name))
515
ld_args.append ('/IMPLIB:' + implib_file)
516
517
if extra_preargs:
518
ld_args[:0] = extra_preargs
519
if extra_postargs:
520
ld_args.extend(extra_postargs)
521
522
self.mkpath(os.path.dirname(output_filename))
523
try:
524
self.spawn([self.linker] + ld_args)
525
except DistutilsExecError as msg:
526
raise LinkError(msg)
527
528
else:
529
log.debug("skipping %s (up-to-date)", output_filename)
530
531
532
# -- Miscellaneous methods -----------------------------------------
533
# These are all used by the 'gen_lib_options() function, in
534
# ccompiler.py.
535
536
def library_dir_option(self, dir):
537
return "/LIBPATH:" + dir
538
539
def runtime_library_dir_option(self, dir):
540
raise DistutilsPlatformError(
541
"don't know how to set runtime library search path for MSVC++")
542
543
def library_option(self, lib):
544
return self.library_filename(lib)
545
546
547
def find_library_file(self, dirs, lib, debug=0):
548
# Prefer a debugging library if found (and requested), but deal
549
# with it if we don't have one.
550
if debug:
551
try_names = [lib + "_d", lib]
552
else:
553
try_names = [lib]
554
for dir in dirs:
555
for name in try_names:
556
libfile = os.path.join(dir, self.library_filename (name))
557
if os.path.exists(libfile):
558
return libfile
559
else:
560
# Oops, didn't find it in *any* of 'dirs'
561
return None
562
563
# Helper methods for using the MSVC registry settings
564
565
def find_exe(self, exe):
566
"""Return path to an MSVC executable program.
567
568
Tries to find the program in several places: first, one of the
569
MSVC program search paths from the registry; next, the directories
570
in the PATH environment variable. If any of those work, return an
571
absolute path that is known to exist. If none of them work, just
572
return the original program name, 'exe'.
573
"""
574
for p in self.__paths:
575
fn = os.path.join(os.path.abspath(p), exe)
576
if os.path.isfile(fn):
577
return fn
578
579
# didn't find it; try existing path
580
for p in os.environ['Path'].split(';'):
581
fn = os.path.join(os.path.abspath(p),exe)
582
if os.path.isfile(fn):
583
return fn
584
585
return exe
586
587
def get_msvc_paths(self, path, platform='x86'):
588
"""Get a list of devstudio directories (include, lib or path).
589
590
Return a list of strings. The list will be empty if unable to
591
access the registry or appropriate registry keys not found.
592
"""
593
if not _can_read_reg:
594
return []
595
596
path = path + " dirs"
597
if self.__version >= 7:
598
key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories"
599
% (self.__root, self.__version))
600
else:
601
key = (r"%s\6.0\Build System\Components\Platforms"
602
r"\Win32 (%s)\Directories" % (self.__root, platform))
603
604
for base in HKEYS:
605
d = read_values(base, key)
606
if d:
607
if self.__version >= 7:
608
return self.__macros.sub(d[path]).split(";")
609
else:
610
return d[path].split(";")
611
# MSVC 6 seems to create the registry entries we need only when
612
# the GUI is run.
613
if self.__version == 6:
614
for base in HKEYS:
615
if read_values(base, r"%s\6.0" % self.__root) is not None:
616
self.warn("It seems you have Visual Studio 6 installed, "
617
"but the expected registry settings are not present.\n"
618
"You must at least run the Visual Studio GUI once "
619
"so that these entries are created.")
620
break
621
return []
622
623
def set_path_env_var(self, name):
624
"""Set environment variable 'name' to an MSVC path type value.
625
626
This is equivalent to a SET command prior to execution of spawned
627
commands.
628
"""
629
630
if name == "lib":
631
p = self.get_msvc_paths("library")
632
else:
633
p = self.get_msvc_paths(name)
634
if p:
635
os.environ[name] = ';'.join(p)
636
637
638
if get_build_version() >= 8.0:
639
log.debug("Importing new compiler from distutils.msvc9compiler")
640
OldMSVCCompiler = MSVCCompiler
641
from distutils.msvc9compiler import MSVCCompiler
642
# get_build_architecture not really relevant now we support cross-compile
643
from distutils.msvc9compiler import MacroExpander
644
645