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