]> jfr.im git - dlqueue.git/blame - venv/lib/python3.11/site-packages/setuptools/_distutils/cygwinccompiler.py
init: venv aand flask
[dlqueue.git] / venv / lib / python3.11 / site-packages / setuptools / _distutils / cygwinccompiler.py
CommitLineData
e0df8241
JR
1"""distutils.cygwinccompiler
2
3Provides the CygwinCCompiler class, a subclass of UnixCCompiler that
4handles the Cygwin port of the GNU C compiler to Windows. It also contains
5the Mingw32CCompiler class which handles the mingw32 port of GCC (same as
6cygwin in no-cygwin mode).
7"""
8
9import os
10import re
11import sys
12import copy
13import shlex
14import warnings
15from subprocess import check_output
16
17from .unixccompiler import UnixCCompiler
18from .file_util import write_file
19from .errors import (
20 DistutilsExecError,
21 DistutilsPlatformError,
22 CCompilerError,
23 CompileError,
24)
25from .version import LooseVersion, suppress_known_deprecation
26from ._collections import RangeMap
27
28
29_msvcr_lookup = RangeMap.left(
30 {
31 # MSVC 7.0
32 1300: ['msvcr70'],
33 # MSVC 7.1
34 1310: ['msvcr71'],
35 # VS2005 / MSVC 8.0
36 1400: ['msvcr80'],
37 # VS2008 / MSVC 9.0
38 1500: ['msvcr90'],
39 # VS2010 / MSVC 10.0
40 1600: ['msvcr100'],
41 # VS2012 / MSVC 11.0
42 1700: ['msvcr110'],
43 # VS2013 / MSVC 12.0
44 1800: ['msvcr120'],
45 # VS2015 / MSVC 14.0
46 1900: ['vcruntime140'],
47 2000: RangeMap.undefined_value,
48 },
49)
50
51
52def get_msvcr():
53 """Include the appropriate MSVC runtime library if Python was built
54 with MSVC 7.0 or later.
55 """
56 match = re.search(r'MSC v\.(\d{4})', sys.version)
57 try:
58 msc_ver = int(match.group(1))
59 except AttributeError:
60 return
61 try:
62 return _msvcr_lookup[msc_ver]
63 except KeyError:
64 raise ValueError("Unknown MS Compiler version %s " % msc_ver)
65
66
67_runtime_library_dirs_msg = (
68 "Unable to set runtime library search path on Windows, "
69 "usually indicated by `runtime_library_dirs` parameter to Extension"
70)
71
72
73class CygwinCCompiler(UnixCCompiler):
74 """Handles the Cygwin port of the GNU C compiler to Windows."""
75
76 compiler_type = 'cygwin'
77 obj_extension = ".o"
78 static_lib_extension = ".a"
79 shared_lib_extension = ".dll.a"
80 dylib_lib_extension = ".dll"
81 static_lib_format = "lib%s%s"
82 shared_lib_format = "lib%s%s"
83 dylib_lib_format = "cyg%s%s"
84 exe_extension = ".exe"
85
86 def __init__(self, verbose=0, dry_run=0, force=0):
87 super().__init__(verbose, dry_run, force)
88
89 status, details = check_config_h()
90 self.debug_print(
91 "Python's GCC status: {} (details: {})".format(status, details)
92 )
93 if status is not CONFIG_H_OK:
94 self.warn(
95 "Python's pyconfig.h doesn't seem to support your compiler. "
96 "Reason: %s. "
97 "Compiling may fail because of undefined preprocessor macros." % details
98 )
99
100 self.cc = os.environ.get('CC', 'gcc')
101 self.cxx = os.environ.get('CXX', 'g++')
102
103 self.linker_dll = self.cc
104 shared_option = "-shared"
105
106 self.set_executables(
107 compiler='%s -mcygwin -O -Wall' % self.cc,
108 compiler_so='%s -mcygwin -mdll -O -Wall' % self.cc,
109 compiler_cxx='%s -mcygwin -O -Wall' % self.cxx,
110 linker_exe='%s -mcygwin' % self.cc,
111 linker_so=('{} -mcygwin {}'.format(self.linker_dll, shared_option)),
112 )
113
114 # Include the appropriate MSVC runtime library if Python was built
115 # with MSVC 7.0 or later.
116 self.dll_libraries = get_msvcr()
117
118 @property
119 def gcc_version(self):
120 # Older numpy depended on this existing to check for ancient
121 # gcc versions. This doesn't make much sense with clang etc so
122 # just hardcode to something recent.
123 # https://github.com/numpy/numpy/pull/20333
124 warnings.warn(
125 "gcc_version attribute of CygwinCCompiler is deprecated. "
126 "Instead of returning actual gcc version a fixed value 11.2.0 is returned.",
127 DeprecationWarning,
128 stacklevel=2,
129 )
130 with suppress_known_deprecation():
131 return LooseVersion("11.2.0")
132
133 def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
134 """Compiles the source by spawning GCC and windres if needed."""
135 if ext in ('.rc', '.res'):
136 # gcc needs '.res' and '.rc' compiled to object files !!!
137 try:
138 self.spawn(["windres", "-i", src, "-o", obj])
139 except DistutilsExecError as msg:
140 raise CompileError(msg)
141 else: # for other files use the C-compiler
142 try:
143 self.spawn(
144 self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs
145 )
146 except DistutilsExecError as msg:
147 raise CompileError(msg)
148
149 def link(
150 self,
151 target_desc,
152 objects,
153 output_filename,
154 output_dir=None,
155 libraries=None,
156 library_dirs=None,
157 runtime_library_dirs=None,
158 export_symbols=None,
159 debug=0,
160 extra_preargs=None,
161 extra_postargs=None,
162 build_temp=None,
163 target_lang=None,
164 ):
165 """Link the objects."""
166 # use separate copies, so we can modify the lists
167 extra_preargs = copy.copy(extra_preargs or [])
168 libraries = copy.copy(libraries or [])
169 objects = copy.copy(objects or [])
170
171 if runtime_library_dirs:
172 self.warn(_runtime_library_dirs_msg)
173
174 # Additional libraries
175 libraries.extend(self.dll_libraries)
176
177 # handle export symbols by creating a def-file
178 # with executables this only works with gcc/ld as linker
179 if (export_symbols is not None) and (
180 target_desc != self.EXECUTABLE or self.linker_dll == "gcc"
181 ):
182 # (The linker doesn't do anything if output is up-to-date.
183 # So it would probably better to check if we really need this,
184 # but for this we had to insert some unchanged parts of
185 # UnixCCompiler, and this is not what we want.)
186
187 # we want to put some files in the same directory as the
188 # object files are, build_temp doesn't help much
189 # where are the object files
190 temp_dir = os.path.dirname(objects[0])
191 # name of dll to give the helper files the same base name
192 (dll_name, dll_extension) = os.path.splitext(
193 os.path.basename(output_filename)
194 )
195
196 # generate the filenames for these files
197 def_file = os.path.join(temp_dir, dll_name + ".def")
198
199 # Generate .def file
200 contents = ["LIBRARY %s" % os.path.basename(output_filename), "EXPORTS"]
201 for sym in export_symbols:
202 contents.append(sym)
203 self.execute(write_file, (def_file, contents), "writing %s" % def_file)
204
205 # next add options for def-file
206
207 # for gcc/ld the def-file is specified as any object files
208 objects.append(def_file)
209
210 # end: if ((export_symbols is not None) and
211 # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")):
212
213 # who wants symbols and a many times larger output file
214 # should explicitly switch the debug mode on
215 # otherwise we let ld strip the output file
216 # (On my machine: 10KiB < stripped_file < ??100KiB
217 # unstripped_file = stripped_file + XXX KiB
218 # ( XXX=254 for a typical python extension))
219 if not debug:
220 extra_preargs.append("-s")
221
222 UnixCCompiler.link(
223 self,
224 target_desc,
225 objects,
226 output_filename,
227 output_dir,
228 libraries,
229 library_dirs,
230 runtime_library_dirs,
231 None, # export_symbols, we do this in our def-file
232 debug,
233 extra_preargs,
234 extra_postargs,
235 build_temp,
236 target_lang,
237 )
238
239 def runtime_library_dir_option(self, dir):
240 # cygwin doesn't support rpath. While in theory we could error
241 # out like MSVC does, code might expect it to work like on Unix, so
242 # just warn and hope for the best.
243 self.warn(_runtime_library_dirs_msg)
244 return []
245
246 # -- Miscellaneous methods -----------------------------------------
247
248 def _make_out_path(self, output_dir, strip_dir, src_name):
249 # use normcase to make sure '.rc' is really '.rc' and not '.RC'
250 norm_src_name = os.path.normcase(src_name)
251 return super()._make_out_path(output_dir, strip_dir, norm_src_name)
252
253 @property
254 def out_extensions(self):
255 """
256 Add support for rc and res files.
257 """
258 return {
259 **super().out_extensions,
260 **{ext: ext + self.obj_extension for ext in ('.res', '.rc')},
261 }
262
263
264# the same as cygwin plus some additional parameters
265class Mingw32CCompiler(CygwinCCompiler):
266 """Handles the Mingw32 port of the GNU C compiler to Windows."""
267
268 compiler_type = 'mingw32'
269
270 def __init__(self, verbose=0, dry_run=0, force=0):
271 super().__init__(verbose, dry_run, force)
272
273 shared_option = "-shared"
274
275 if is_cygwincc(self.cc):
276 raise CCompilerError('Cygwin gcc cannot be used with --compiler=mingw32')
277
278 self.set_executables(
279 compiler='%s -O -Wall' % self.cc,
280 compiler_so='%s -mdll -O -Wall' % self.cc,
281 compiler_cxx='%s -O -Wall' % self.cxx,
282 linker_exe='%s' % self.cc,
283 linker_so='{} {}'.format(self.linker_dll, shared_option),
284 )
285
286 def runtime_library_dir_option(self, dir):
287 raise DistutilsPlatformError(_runtime_library_dirs_msg)
288
289
290# Because these compilers aren't configured in Python's pyconfig.h file by
291# default, we should at least warn the user if he is using an unmodified
292# version.
293
294CONFIG_H_OK = "ok"
295CONFIG_H_NOTOK = "not ok"
296CONFIG_H_UNCERTAIN = "uncertain"
297
298
299def check_config_h():
300 """Check if the current Python installation appears amenable to building
301 extensions with GCC.
302
303 Returns a tuple (status, details), where 'status' is one of the following
304 constants:
305
306 - CONFIG_H_OK: all is well, go ahead and compile
307 - CONFIG_H_NOTOK: doesn't look good
308 - CONFIG_H_UNCERTAIN: not sure -- unable to read pyconfig.h
309
310 'details' is a human-readable string explaining the situation.
311
312 Note there are two ways to conclude "OK": either 'sys.version' contains
313 the string "GCC" (implying that this Python was built with GCC), or the
314 installed "pyconfig.h" contains the string "__GNUC__".
315 """
316
317 # XXX since this function also checks sys.version, it's not strictly a
318 # "pyconfig.h" check -- should probably be renamed...
319
320 from distutils import sysconfig
321
322 # if sys.version contains GCC then python was compiled with GCC, and the
323 # pyconfig.h file should be OK
324 if "GCC" in sys.version:
325 return CONFIG_H_OK, "sys.version mentions 'GCC'"
326
327 # Clang would also work
328 if "Clang" in sys.version:
329 return CONFIG_H_OK, "sys.version mentions 'Clang'"
330
331 # let's see if __GNUC__ is mentioned in python.h
332 fn = sysconfig.get_config_h_filename()
333 try:
334 config_h = open(fn)
335 try:
336 if "__GNUC__" in config_h.read():
337 return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn
338 else:
339 return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn
340 finally:
341 config_h.close()
342 except OSError as exc:
343 return (CONFIG_H_UNCERTAIN, "couldn't read '{}': {}".format(fn, exc.strerror))
344
345
346def is_cygwincc(cc):
347 '''Try to determine if the compiler that would be used is from cygwin.'''
348 out_string = check_output(shlex.split(cc) + ['-dumpmachine'])
349 return out_string.strip().endswith(b'cygwin')
350
351
352get_versions = None
353"""
354A stand-in for the previous get_versions() function to prevent failures
355when monkeypatched. See pypa/setuptools#2969.
356"""