comparison env/lib/python3.9/site-packages/setuptools/_distutils/sysconfig.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 """Provide access to Python's configuration information. The specific
2 configuration variables available depend heavily on the platform and
3 configuration. The values may be retrieved using
4 get_config_var(name), and the list of variables is available via
5 get_config_vars().keys(). Additional convenience functions are also
6 available.
7
8 Written by: Fred L. Drake, Jr.
9 Email: <fdrake@acm.org>
10 """
11
12 import _imp
13 import os
14 import re
15 import sys
16
17 from .errors import DistutilsPlatformError
18
19 IS_PYPY = '__pypy__' in sys.builtin_module_names
20
21 # These are needed in a couple of spots, so just compute them once.
22 PREFIX = os.path.normpath(sys.prefix)
23 EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
24 BASE_PREFIX = os.path.normpath(sys.base_prefix)
25 BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix)
26
27 # Path to the base directory of the project. On Windows the binary may
28 # live in project/PCbuild/win32 or project/PCbuild/amd64.
29 # set for cross builds
30 if "_PYTHON_PROJECT_BASE" in os.environ:
31 project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"])
32 else:
33 if sys.executable:
34 project_base = os.path.dirname(os.path.abspath(sys.executable))
35 else:
36 # sys.executable can be empty if argv[0] has been changed and Python is
37 # unable to retrieve the real program name
38 project_base = os.getcwd()
39
40
41 # python_build: (Boolean) if true, we're either building Python or
42 # building an extension with an un-installed Python, so we use
43 # different (hard-wired) directories.
44 def _is_python_source_dir(d):
45 for fn in ("Setup", "Setup.local"):
46 if os.path.isfile(os.path.join(d, "Modules", fn)):
47 return True
48 return False
49
50 _sys_home = getattr(sys, '_home', None)
51
52 if os.name == 'nt':
53 def _fix_pcbuild(d):
54 if d and os.path.normcase(d).startswith(
55 os.path.normcase(os.path.join(PREFIX, "PCbuild"))):
56 return PREFIX
57 return d
58 project_base = _fix_pcbuild(project_base)
59 _sys_home = _fix_pcbuild(_sys_home)
60
61 def _python_build():
62 if _sys_home:
63 return _is_python_source_dir(_sys_home)
64 return _is_python_source_dir(project_base)
65
66 python_build = _python_build()
67
68
69 # Calculate the build qualifier flags if they are defined. Adding the flags
70 # to the include and lib directories only makes sense for an installation, not
71 # an in-source build.
72 build_flags = ''
73 try:
74 if not python_build:
75 build_flags = sys.abiflags
76 except AttributeError:
77 # It's not a configure-based build, so the sys module doesn't have
78 # this attribute, which is fine.
79 pass
80
81 def get_python_version():
82 """Return a string containing the major and minor Python version,
83 leaving off the patchlevel. Sample return values could be '1.5'
84 or '2.2'.
85 """
86 return '%d.%d' % sys.version_info[:2]
87
88
89 def get_python_inc(plat_specific=0, prefix=None):
90 """Return the directory containing installed Python header files.
91
92 If 'plat_specific' is false (the default), this is the path to the
93 non-platform-specific header files, i.e. Python.h and so on;
94 otherwise, this is the path to platform-specific header files
95 (namely pyconfig.h).
96
97 If 'prefix' is supplied, use it instead of sys.base_prefix or
98 sys.base_exec_prefix -- i.e., ignore 'plat_specific'.
99 """
100 if prefix is None:
101 prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
102 if IS_PYPY:
103 return os.path.join(prefix, 'include')
104 elif os.name == "posix":
105 if python_build:
106 # Assume the executable is in the build directory. The
107 # pyconfig.h file should be in the same directory. Since
108 # the build directory may not be the source directory, we
109 # must use "srcdir" from the makefile to find the "Include"
110 # directory.
111 if plat_specific:
112 return _sys_home or project_base
113 else:
114 incdir = os.path.join(get_config_var('srcdir'), 'Include')
115 return os.path.normpath(incdir)
116 python_dir = 'python' + get_python_version() + build_flags
117 return os.path.join(prefix, "include", python_dir)
118 elif os.name == "nt":
119 if python_build:
120 # Include both the include and PC dir to ensure we can find
121 # pyconfig.h
122 return (os.path.join(prefix, "include") + os.path.pathsep +
123 os.path.join(prefix, "PC"))
124 return os.path.join(prefix, "include")
125 else:
126 raise DistutilsPlatformError(
127 "I don't know where Python installs its C header files "
128 "on platform '%s'" % os.name)
129
130
131 def get_python_lib(plat_specific=0, standard_lib=0, prefix=None):
132 """Return the directory containing the Python library (standard or
133 site additions).
134
135 If 'plat_specific' is true, return the directory containing
136 platform-specific modules, i.e. any module from a non-pure-Python
137 module distribution; otherwise, return the platform-shared library
138 directory. If 'standard_lib' is true, return the directory
139 containing standard Python library modules; otherwise, return the
140 directory for site-specific modules.
141
142 If 'prefix' is supplied, use it instead of sys.base_prefix or
143 sys.base_exec_prefix -- i.e., ignore 'plat_specific'.
144 """
145 if IS_PYPY:
146 # PyPy-specific schema
147 if prefix is None:
148 prefix = PREFIX
149 if standard_lib:
150 return os.path.join(prefix, "lib-python", sys.version[0])
151 return os.path.join(prefix, 'site-packages')
152
153 if prefix is None:
154 if standard_lib:
155 prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX
156 else:
157 prefix = plat_specific and EXEC_PREFIX or PREFIX
158
159 if os.name == "posix":
160 if plat_specific or standard_lib:
161 # Platform-specific modules (any module from a non-pure-Python
162 # module distribution) or standard Python library modules.
163 libdir = getattr(sys, "platlibdir", "lib")
164 else:
165 # Pure Python
166 libdir = "lib"
167 libpython = os.path.join(prefix, libdir,
168 "python" + get_python_version())
169 if standard_lib:
170 return libpython
171 else:
172 return os.path.join(libpython, "site-packages")
173 elif os.name == "nt":
174 if standard_lib:
175 return os.path.join(prefix, "Lib")
176 else:
177 return os.path.join(prefix, "Lib", "site-packages")
178 else:
179 raise DistutilsPlatformError(
180 "I don't know where Python installs its library "
181 "on platform '%s'" % os.name)
182
183
184
185 def customize_compiler(compiler):
186 """Do any platform-specific customization of a CCompiler instance.
187
188 Mainly needed on Unix, so we can plug in the information that
189 varies across Unices and is stored in Python's Makefile.
190 """
191 if compiler.compiler_type == "unix":
192 if sys.platform == "darwin":
193 # Perform first-time customization of compiler-related
194 # config vars on OS X now that we know we need a compiler.
195 # This is primarily to support Pythons from binary
196 # installers. The kind and paths to build tools on
197 # the user system may vary significantly from the system
198 # that Python itself was built on. Also the user OS
199 # version and build tools may not support the same set
200 # of CPU architectures for universal builds.
201 global _config_vars
202 # Use get_config_var() to ensure _config_vars is initialized.
203 if not get_config_var('CUSTOMIZED_OSX_COMPILER'):
204 import _osx_support
205 _osx_support.customize_compiler(_config_vars)
206 _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True'
207
208 (cc, cxx, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \
209 get_config_vars('CC', 'CXX', 'CFLAGS',
210 'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS')
211
212 if 'CC' in os.environ:
213 newcc = os.environ['CC']
214 if (sys.platform == 'darwin'
215 and 'LDSHARED' not in os.environ
216 and ldshared.startswith(cc)):
217 # On OS X, if CC is overridden, use that as the default
218 # command for LDSHARED as well
219 ldshared = newcc + ldshared[len(cc):]
220 cc = newcc
221 if 'CXX' in os.environ:
222 cxx = os.environ['CXX']
223 if 'LDSHARED' in os.environ:
224 ldshared = os.environ['LDSHARED']
225 if 'CPP' in os.environ:
226 cpp = os.environ['CPP']
227 else:
228 cpp = cc + " -E" # not always
229 if 'LDFLAGS' in os.environ:
230 ldshared = ldshared + ' ' + os.environ['LDFLAGS']
231 if 'CFLAGS' in os.environ:
232 cflags = cflags + ' ' + os.environ['CFLAGS']
233 ldshared = ldshared + ' ' + os.environ['CFLAGS']
234 if 'CPPFLAGS' in os.environ:
235 cpp = cpp + ' ' + os.environ['CPPFLAGS']
236 cflags = cflags + ' ' + os.environ['CPPFLAGS']
237 ldshared = ldshared + ' ' + os.environ['CPPFLAGS']
238 if 'AR' in os.environ:
239 ar = os.environ['AR']
240 if 'ARFLAGS' in os.environ:
241 archiver = ar + ' ' + os.environ['ARFLAGS']
242 else:
243 archiver = ar + ' ' + ar_flags
244
245 cc_cmd = cc + ' ' + cflags
246 compiler.set_executables(
247 preprocessor=cpp,
248 compiler=cc_cmd,
249 compiler_so=cc_cmd + ' ' + ccshared,
250 compiler_cxx=cxx,
251 linker_so=ldshared,
252 linker_exe=cc,
253 archiver=archiver)
254
255 compiler.shared_lib_extension = shlib_suffix
256
257
258 def get_config_h_filename():
259 """Return full pathname of installed pyconfig.h file."""
260 if python_build:
261 if os.name == "nt":
262 inc_dir = os.path.join(_sys_home or project_base, "PC")
263 else:
264 inc_dir = _sys_home or project_base
265 else:
266 inc_dir = get_python_inc(plat_specific=1)
267
268 return os.path.join(inc_dir, 'pyconfig.h')
269
270
271 def get_makefile_filename():
272 """Return full pathname of installed Makefile from the Python build."""
273 if python_build:
274 return os.path.join(_sys_home or project_base, "Makefile")
275 lib_dir = get_python_lib(plat_specific=0, standard_lib=1)
276 config_file = 'config-{}{}'.format(get_python_version(), build_flags)
277 if hasattr(sys.implementation, '_multiarch'):
278 config_file += '-%s' % sys.implementation._multiarch
279 return os.path.join(lib_dir, config_file, 'Makefile')
280
281
282 def parse_config_h(fp, g=None):
283 """Parse a config.h-style file.
284
285 A dictionary containing name/value pairs is returned. If an
286 optional dictionary is passed in as the second argument, it is
287 used instead of a new dictionary.
288 """
289 if g is None:
290 g = {}
291 define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n")
292 undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n")
293 #
294 while True:
295 line = fp.readline()
296 if not line:
297 break
298 m = define_rx.match(line)
299 if m:
300 n, v = m.group(1, 2)
301 try: v = int(v)
302 except ValueError: pass
303 g[n] = v
304 else:
305 m = undef_rx.match(line)
306 if m:
307 g[m.group(1)] = 0
308 return g
309
310
311 # Regexes needed for parsing Makefile (and similar syntaxes,
312 # like old-style Setup files).
313 _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)")
314 _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)")
315 _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}")
316
317 def parse_makefile(fn, g=None):
318 """Parse a Makefile-style file.
319
320 A dictionary containing name/value pairs is returned. If an
321 optional dictionary is passed in as the second argument, it is
322 used instead of a new dictionary.
323 """
324 from distutils.text_file import TextFile
325 fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape")
326
327 if g is None:
328 g = {}
329 done = {}
330 notdone = {}
331
332 while True:
333 line = fp.readline()
334 if line is None: # eof
335 break
336 m = _variable_rx.match(line)
337 if m:
338 n, v = m.group(1, 2)
339 v = v.strip()
340 # `$$' is a literal `$' in make
341 tmpv = v.replace('$$', '')
342
343 if "$" in tmpv:
344 notdone[n] = v
345 else:
346 try:
347 v = int(v)
348 except ValueError:
349 # insert literal `$'
350 done[n] = v.replace('$$', '$')
351 else:
352 done[n] = v
353
354 # Variables with a 'PY_' prefix in the makefile. These need to
355 # be made available without that prefix through sysconfig.
356 # Special care is needed to ensure that variable expansion works, even
357 # if the expansion uses the name without a prefix.
358 renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS')
359
360 # do variable interpolation here
361 while notdone:
362 for name in list(notdone):
363 value = notdone[name]
364 m = _findvar1_rx.search(value) or _findvar2_rx.search(value)
365 if m:
366 n = m.group(1)
367 found = True
368 if n in done:
369 item = str(done[n])
370 elif n in notdone:
371 # get it on a subsequent round
372 found = False
373 elif n in os.environ:
374 # do it like make: fall back to environment
375 item = os.environ[n]
376
377 elif n in renamed_variables:
378 if name.startswith('PY_') and name[3:] in renamed_variables:
379 item = ""
380
381 elif 'PY_' + n in notdone:
382 found = False
383
384 else:
385 item = str(done['PY_' + n])
386 else:
387 done[n] = item = ""
388 if found:
389 after = value[m.end():]
390 value = value[:m.start()] + item + after
391 if "$" in after:
392 notdone[name] = value
393 else:
394 try: value = int(value)
395 except ValueError:
396 done[name] = value.strip()
397 else:
398 done[name] = value
399 del notdone[name]
400
401 if name.startswith('PY_') \
402 and name[3:] in renamed_variables:
403
404 name = name[3:]
405 if name not in done:
406 done[name] = value
407 else:
408 # bogus variable reference; just drop it since we can't deal
409 del notdone[name]
410
411 fp.close()
412
413 # strip spurious spaces
414 for k, v in done.items():
415 if isinstance(v, str):
416 done[k] = v.strip()
417
418 # save the results in the global dictionary
419 g.update(done)
420 return g
421
422
423 def expand_makefile_vars(s, vars):
424 """Expand Makefile-style variables -- "${foo}" or "$(foo)" -- in
425 'string' according to 'vars' (a dictionary mapping variable names to
426 values). Variables not present in 'vars' are silently expanded to the
427 empty string. The variable values in 'vars' should not contain further
428 variable expansions; if 'vars' is the output of 'parse_makefile()',
429 you're fine. Returns a variable-expanded version of 's'.
430 """
431
432 # This algorithm does multiple expansion, so if vars['foo'] contains
433 # "${bar}", it will expand ${foo} to ${bar}, and then expand
434 # ${bar}... and so forth. This is fine as long as 'vars' comes from
435 # 'parse_makefile()', which takes care of such expansions eagerly,
436 # according to make's variable expansion semantics.
437
438 while True:
439 m = _findvar1_rx.search(s) or _findvar2_rx.search(s)
440 if m:
441 (beg, end) = m.span()
442 s = s[0:beg] + vars.get(m.group(1)) + s[end:]
443 else:
444 break
445 return s
446
447
448 _config_vars = None
449
450 def _init_posix():
451 """Initialize the module as appropriate for POSIX systems."""
452 # _sysconfigdata is generated at build time, see the sysconfig module
453 name = os.environ.get('_PYTHON_SYSCONFIGDATA_NAME',
454 '_sysconfigdata_{abi}_{platform}_{multiarch}'.format(
455 abi=sys.abiflags,
456 platform=sys.platform,
457 multiarch=getattr(sys.implementation, '_multiarch', ''),
458 ))
459 try:
460 _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
461 except ImportError:
462 # Python 3.5 and pypy 7.3.1
463 _temp = __import__(
464 '_sysconfigdata', globals(), locals(), ['build_time_vars'], 0)
465 build_time_vars = _temp.build_time_vars
466 global _config_vars
467 _config_vars = {}
468 _config_vars.update(build_time_vars)
469
470
471 def _init_nt():
472 """Initialize the module as appropriate for NT"""
473 g = {}
474 # set basic install directories
475 g['LIBDEST'] = get_python_lib(plat_specific=0, standard_lib=1)
476 g['BINLIBDEST'] = get_python_lib(plat_specific=1, standard_lib=1)
477
478 # XXX hmmm.. a normal install puts include files here
479 g['INCLUDEPY'] = get_python_inc(plat_specific=0)
480
481 g['EXT_SUFFIX'] = _imp.extension_suffixes()[0]
482 g['EXE'] = ".exe"
483 g['VERSION'] = get_python_version().replace(".", "")
484 g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
485
486 global _config_vars
487 _config_vars = g
488
489
490 def get_config_vars(*args):
491 """With no arguments, return a dictionary of all configuration
492 variables relevant for the current platform. Generally this includes
493 everything needed to build extensions and install both pure modules and
494 extensions. On Unix, this means every variable defined in Python's
495 installed Makefile; on Windows it's a much smaller set.
496
497 With arguments, return a list of values that result from looking up
498 each argument in the configuration variable dictionary.
499 """
500 global _config_vars
501 if _config_vars is None:
502 func = globals().get("_init_" + os.name)
503 if func:
504 func()
505 else:
506 _config_vars = {}
507
508 # Normalized versions of prefix and exec_prefix are handy to have;
509 # in fact, these are the standard versions used most places in the
510 # Distutils.
511 _config_vars['prefix'] = PREFIX
512 _config_vars['exec_prefix'] = EXEC_PREFIX
513
514 if not IS_PYPY:
515 # For backward compatibility, see issue19555
516 SO = _config_vars.get('EXT_SUFFIX')
517 if SO is not None:
518 _config_vars['SO'] = SO
519
520 # Always convert srcdir to an absolute path
521 srcdir = _config_vars.get('srcdir', project_base)
522 if os.name == 'posix':
523 if python_build:
524 # If srcdir is a relative path (typically '.' or '..')
525 # then it should be interpreted relative to the directory
526 # containing Makefile.
527 base = os.path.dirname(get_makefile_filename())
528 srcdir = os.path.join(base, srcdir)
529 else:
530 # srcdir is not meaningful since the installation is
531 # spread about the filesystem. We choose the
532 # directory containing the Makefile since we know it
533 # exists.
534 srcdir = os.path.dirname(get_makefile_filename())
535 _config_vars['srcdir'] = os.path.abspath(os.path.normpath(srcdir))
536
537 # Convert srcdir into an absolute path if it appears necessary.
538 # Normally it is relative to the build directory. However, during
539 # testing, for example, we might be running a non-installed python
540 # from a different directory.
541 if python_build and os.name == "posix":
542 base = project_base
543 if (not os.path.isabs(_config_vars['srcdir']) and
544 base != os.getcwd()):
545 # srcdir is relative and we are not in the same directory
546 # as the executable. Assume executable is in the build
547 # directory and make srcdir absolute.
548 srcdir = os.path.join(base, _config_vars['srcdir'])
549 _config_vars['srcdir'] = os.path.normpath(srcdir)
550
551 # OS X platforms require special customization to handle
552 # multi-architecture, multi-os-version installers
553 if sys.platform == 'darwin':
554 import _osx_support
555 _osx_support.customize_config_vars(_config_vars)
556
557 if args:
558 vals = []
559 for name in args:
560 vals.append(_config_vars.get(name))
561 return vals
562 else:
563 return _config_vars
564
565 def get_config_var(name):
566 """Return the value of a single variable using the dictionary
567 returned by 'get_config_vars()'. Equivalent to
568 get_config_vars().get(name)
569 """
570 if name == 'SO':
571 import warnings
572 warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2)
573 return get_config_vars().get(name)