Change venv

This commit is contained in:
Ambulance Clerc
2023-05-31 08:31:22 +02:00
parent fb6f579089
commit fdbb52c96f
466 changed files with 25899 additions and 64721 deletions

View File

@@ -13,18 +13,18 @@ the "typical" Unix-style command-line C compiler:
* link shared library handled by 'cc -shared'
"""
import os, sys, re, shlex
import os
import sys
import re
import shlex
import itertools
from distutils import sysconfig
from distutils.dep_util import newer
from distutils.ccompiler import \
CCompiler, gen_preprocess_options, gen_lib_options
from distutils.errors import \
DistutilsExecError, CompileError, LibError, LinkError
from distutils.ccompiler import CCompiler, gen_preprocess_options, gen_lib_options
from distutils.errors import DistutilsExecError, CompileError, LibError, LinkError
from distutils import log
if sys.platform == 'darwin':
import _osx_support
from ._macos_compat import compiler_fixup
# XXX Things not currently handled:
# * optimization/debug/warning flags; we just use whatever's in Python's
@@ -42,6 +42,66 @@ if sys.platform == 'darwin':
# options and carry on.
def _split_env(cmd):
"""
For macOS, split command into 'env' portion (if any)
and the rest of the linker command.
>>> _split_env(['a', 'b', 'c'])
([], ['a', 'b', 'c'])
>>> _split_env(['/usr/bin/env', 'A=3', 'gcc'])
(['/usr/bin/env', 'A=3'], ['gcc'])
"""
pivot = 0
if os.path.basename(cmd[0]) == "env":
pivot = 1
while '=' in cmd[pivot]:
pivot += 1
return cmd[:pivot], cmd[pivot:]
def _split_aix(cmd):
"""
AIX platforms prefix the compiler with the ld_so_aix
script, so split that from the linker command.
>>> _split_aix(['a', 'b', 'c'])
([], ['a', 'b', 'c'])
>>> _split_aix(['/bin/foo/ld_so_aix', 'gcc'])
(['/bin/foo/ld_so_aix'], ['gcc'])
"""
pivot = os.path.basename(cmd[0]) == 'ld_so_aix'
return cmd[:pivot], cmd[pivot:]
def _linker_params(linker_cmd, compiler_cmd):
"""
The linker command usually begins with the compiler
command (possibly multiple elements), followed by zero or more
params for shared library building.
If the LDSHARED env variable overrides the linker command,
however, the commands may not match.
Return the best guess of the linker parameters by stripping
the linker command. If the compiler command does not
match the linker command, assume the linker command is
just the first element.
>>> _linker_params('gcc foo bar'.split(), ['gcc'])
['foo', 'bar']
>>> _linker_params('gcc foo bar'.split(), ['other'])
['foo', 'bar']
>>> _linker_params('ccache gcc foo bar'.split(), 'ccache gcc'.split())
['foo', 'bar']
>>> _linker_params(['gcc'], ['gcc'])
[]
"""
c_len = len(compiler_cmd)
pivot = c_len if linker_cmd[:c_len] == compiler_cmd else 1
return linker_cmd[pivot:]
class UnixCCompiler(CCompiler):
compiler_type = 'unix'
@@ -52,15 +112,16 @@ class UnixCCompiler(CCompiler):
# are pretty generic; they will probably have to be set by an outsider
# (eg. using information discovered by the sysconfig about building
# Python extensions).
executables = {'preprocessor' : None,
'compiler' : ["cc"],
'compiler_so' : ["cc"],
'compiler_cxx' : ["cc"],
'linker_so' : ["cc", "-shared"],
'linker_exe' : ["cc"],
'archiver' : ["ar", "-cr"],
'ranlib' : None,
}
executables = {
'preprocessor': None,
'compiler': ["cc"],
'compiler_so': ["cc"],
'compiler_cxx': ["cc"],
'linker_so': ["cc", "-shared"],
'linker_exe': ["cc"],
'archiver': ["ar", "-cr"],
'ranlib': None,
}
if sys.platform[:6] == "darwin":
executables['ranlib'] = ["ranlib"]
@@ -71,7 +132,7 @@ class UnixCCompiler(CCompiler):
# reasonable common default here, but it's not necessarily used on all
# Unices!
src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"]
src_extensions = [".c", ".C", ".cc", ".cxx", ".cpp", ".m"]
obj_extension = ".o"
static_lib_extension = ".a"
shared_lib_extension = ".so"
@@ -82,8 +143,15 @@ class UnixCCompiler(CCompiler):
if sys.platform == "cygwin":
exe_extension = ".exe"
def preprocess(self, source, output_file=None, macros=None,
include_dirs=None, extra_preargs=None, extra_postargs=None):
def preprocess(
self,
source,
output_file=None,
macros=None,
include_dirs=None,
extra_preargs=None,
extra_postargs=None,
):
fixed_args = self._fix_compile_args(None, macros, include_dirs)
ignore, macros, include_dirs = fixed_args
pp_opts = gen_preprocess_options(macros, include_dirs)
@@ -96,41 +164,39 @@ class UnixCCompiler(CCompiler):
pp_args.extend(extra_postargs)
pp_args.append(source)
# We need to preprocess: either we're being forced to, or we're
# generating output to stdout, or there's a target output file and
# the source file is newer than the target (or the target doesn't
# exist).
if self.force or output_file is None or newer(source, output_file):
if output_file:
self.mkpath(os.path.dirname(output_file))
try:
self.spawn(pp_args)
except DistutilsExecError as msg:
raise CompileError(msg)
# reasons to preprocess:
# - force is indicated
# - output is directed to stdout
# - source file is newer than the target
preprocess = self.force or output_file is None or newer(source, output_file)
if not preprocess:
return
if output_file:
self.mkpath(os.path.dirname(output_file))
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
compiler_so = self.compiler_so
if sys.platform == 'darwin':
compiler_so = _osx_support.compiler_fixup(compiler_so,
cc_args + extra_postargs)
try:
self.spawn(compiler_so + cc_args + [src, '-o', obj] +
extra_postargs)
self.spawn(pp_args)
except DistutilsExecError as msg:
raise CompileError(msg)
def create_static_lib(self, objects, output_libname,
output_dir=None, debug=0, target_lang=None):
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
compiler_so = compiler_fixup(self.compiler_so, cc_args + extra_postargs)
try:
self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs)
except DistutilsExecError as msg:
raise CompileError(msg)
def create_static_lib(
self, objects, output_libname, output_dir=None, debug=0, target_lang=None
):
objects, output_dir = self._fix_object_args(objects, output_dir)
output_filename = \
self.library_filename(output_libname, output_dir=output_dir)
output_filename = self.library_filename(output_libname, output_dir=output_dir)
if self._need_link(objects, output_filename):
self.mkpath(os.path.dirname(output_filename))
self.spawn(self.archiver +
[output_filename] +
objects + self.objects)
self.spawn(self.archiver + [output_filename] + objects + self.objects)
# Not many Unices required ranlib anymore -- SunOS 4.x is, I
# think the only major Unix that does. Maybe we need some
@@ -145,26 +211,34 @@ class UnixCCompiler(CCompiler):
else:
log.debug("skipping %s (up-to-date)", output_filename)
def link(self, target_desc, objects,
output_filename, output_dir=None, libraries=None,
library_dirs=None, runtime_library_dirs=None,
export_symbols=None, debug=0, extra_preargs=None,
extra_postargs=None, build_temp=None, target_lang=None):
def link(
self,
target_desc,
objects,
output_filename,
output_dir=None,
libraries=None,
library_dirs=None,
runtime_library_dirs=None,
export_symbols=None,
debug=0,
extra_preargs=None,
extra_postargs=None,
build_temp=None,
target_lang=None,
):
objects, output_dir = self._fix_object_args(objects, output_dir)
fixed_args = self._fix_lib_args(libraries, library_dirs,
runtime_library_dirs)
fixed_args = self._fix_lib_args(libraries, library_dirs, runtime_library_dirs)
libraries, library_dirs, runtime_library_dirs = fixed_args
lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs,
libraries)
lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries)
if not isinstance(output_dir, (str, type(None))):
raise TypeError("'output_dir' must be a string or None")
if output_dir is not None:
output_filename = os.path.join(output_dir, output_filename)
if self._need_link(objects, output_filename):
ld_args = (objects + self.objects +
lib_opts + ['-o', output_filename])
ld_args = objects + self.objects + lib_opts + ['-o', output_filename]
if debug:
ld_args[:0] = ['-g']
if extra_preargs:
@@ -173,33 +247,22 @@ class UnixCCompiler(CCompiler):
ld_args.extend(extra_postargs)
self.mkpath(os.path.dirname(output_filename))
try:
if target_desc == CCompiler.EXECUTABLE:
linker = self.linker_exe[:]
else:
linker = self.linker_so[:]
# Select a linker based on context: linker_exe when
# building an executable or linker_so (with shared options)
# when building a shared library.
building_exe = target_desc == CCompiler.EXECUTABLE
linker = (self.linker_exe if building_exe else self.linker_so)[:]
if target_lang == "c++" and self.compiler_cxx:
# skip over environment variable settings if /usr/bin/env
# is used to set up the linker's environment.
# This is needed on OSX. Note: this assumes that the
# normal and C++ compiler have the same environment
# settings.
i = 0
if os.path.basename(linker[0]) == "env":
i = 1
while '=' in linker[i]:
i += 1
env, linker_ne = _split_env(linker)
aix, linker_na = _split_aix(linker_ne)
_, compiler_cxx_ne = _split_env(self.compiler_cxx)
_, linker_exe_ne = _split_env(self.linker_exe)
if os.path.basename(linker[i]) == 'ld_so_aix':
# AIX platforms prefix the compiler with the ld_so_aix
# script, so we need to adjust our linker index
offset = 1
else:
offset = 0
params = _linker_params(linker_na, linker_exe_ne)
linker = env + aix + compiler_cxx_ne + params
linker[i+offset] = self.compiler_cxx[i]
if sys.platform == 'darwin':
linker = _osx_support.compiler_fixup(linker, ld_args)
linker = compiler_fixup(linker, ld_args)
self.spawn(linker + ld_args)
except DistutilsExecError as msg:
@@ -214,8 +277,10 @@ class UnixCCompiler(CCompiler):
def library_dir_option(self, dir):
return "-L" + dir
def _is_gcc(self, compiler_name):
return "gcc" in compiler_name or "g++" in compiler_name
def _is_gcc(self):
cc_var = sysconfig.get_config_var("CC")
compiler = os.path.basename(shlex.split(cc_var)[0])
return "gcc" in compiler or "g++" in compiler
def runtime_library_dir_option(self, dir):
# XXX Hackish, at the very least. See Python bug #445902:
@@ -231,102 +296,106 @@ class UnixCCompiler(CCompiler):
# this time, there's no way to determine this information from
# the configuration data stored in the Python installation, so
# we use this hack.
compiler = os.path.basename(shlex.split(sysconfig.get_config_var("CC"))[0])
if sys.platform[:6] == "darwin":
from distutils.util import get_macosx_target_ver, split_version
macosx_target_ver = get_macosx_target_ver()
if macosx_target_ver and split_version(macosx_target_ver) >= [10, 5]:
return "-Wl,-rpath," + dir
else: # no support for -rpath on earlier macOS versions
else: # no support for -rpath on earlier macOS versions
return "-L" + dir
elif sys.platform[:7] == "freebsd":
return "-Wl,-rpath=" + dir
elif sys.platform[:5] == "hp-ux":
if self._is_gcc(compiler):
return ["-Wl,+s", "-L" + dir]
return ["+s", "-L" + dir]
return [
"-Wl,+s" if self._is_gcc() else "+s",
"-L" + dir,
]
# For all compilers, `-Wl` is the presumed way to
# pass a compiler option to the linker and `-R` is
# the way to pass an RPATH.
if sysconfig.get_config_var("GNULD") == "yes":
# GNU ld needs an extra option to get a RUNPATH
# instead of just an RPATH.
return "-Wl,--enable-new-dtags,-R" + dir
else:
if self._is_gcc(compiler):
# gcc on non-GNU systems does not need -Wl, but can
# use it anyway. Since distutils has always passed in
# -Wl whenever gcc was used in the past it is probably
# safest to keep doing so.
if sysconfig.get_config_var("GNULD") == "yes":
# GNU ld needs an extra option to get a RUNPATH
# instead of just an RPATH.
return "-Wl,--enable-new-dtags,-R" + dir
else:
return "-Wl,-R" + dir
else:
# No idea how --enable-new-dtags would be passed on to
# ld if this system was using GNU ld. Don't know if a
# system like this even exists.
return "-R" + dir
return "-Wl,-R" + dir
def library_option(self, lib):
return "-l" + lib
@staticmethod
def _library_root(dir):
"""
macOS users can specify an alternate SDK using'-isysroot'.
Calculate the SDK root if it is specified.
Note that, as of Xcode 7, Apple SDKs may contain textual stub
libraries with .tbd extensions rather than the normal .dylib
shared libraries installed in /. The Apple compiler tool
chain handles this transparently but it can cause problems
for programs that are being built with an SDK and searching
for specific libraries. Callers of find_library_file need to
keep in mind that the base filename of the returned SDK library
file might have a different extension from that of the library
file installed on the running system, for example:
/Applications/Xcode.app/Contents/Developer/Platforms/
MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/
usr/lib/libedit.tbd
vs
/usr/lib/libedit.dylib
"""
cflags = sysconfig.get_config_var('CFLAGS')
match = re.search(r'-isysroot\s*(\S+)', cflags)
apply_root = (
sys.platform == 'darwin'
and match
and (
dir.startswith('/System/')
or (dir.startswith('/usr/') and not dir.startswith('/usr/local/'))
)
)
return os.path.join(match.group(1), dir[1:]) if apply_root else dir
def find_library_file(self, dirs, lib, debug=0):
shared_f = self.library_filename(lib, lib_type='shared')
dylib_f = self.library_filename(lib, lib_type='dylib')
xcode_stub_f = self.library_filename(lib, lib_type='xcode_stub')
static_f = self.library_filename(lib, lib_type='static')
r"""
Second-guess the linker with not much hard
data to go on: GCC seems to prefer the shared library, so
assume that *all* Unix C compilers do,
ignoring even GCC's "-static" option.
if sys.platform == 'darwin':
# On OSX users can specify an alternate SDK using
# '-isysroot', calculate the SDK root if it is specified
# (and use it further on)
#
# Note that, as of Xcode 7, Apple SDKs may contain textual stub
# libraries with .tbd extensions rather than the normal .dylib
# shared libraries installed in /. The Apple compiler tool
# chain handles this transparently but it can cause problems
# for programs that are being built with an SDK and searching
# for specific libraries. Callers of find_library_file need to
# keep in mind that the base filename of the returned SDK library
# file might have a different extension from that of the library
# file installed on the running system, for example:
# /Applications/Xcode.app/Contents/Developer/Platforms/
# MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/
# usr/lib/libedit.tbd
# vs
# /usr/lib/libedit.dylib
cflags = sysconfig.get_config_var('CFLAGS')
m = re.search(r'-isysroot\s*(\S+)', cflags)
if m is None:
sysroot = '/'
else:
sysroot = m.group(1)
>>> compiler = UnixCCompiler()
>>> compiler._library_root = lambda dir: dir
>>> monkeypatch = getfixture('monkeypatch')
>>> monkeypatch.setattr(os.path, 'exists', lambda d: 'existing' in d)
>>> dirs = ('/foo/bar/missing', '/foo/bar/existing')
>>> compiler.find_library_file(dirs, 'abc').replace('\\', '/')
'/foo/bar/existing/libabc.dylib'
>>> compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/')
'/foo/bar/existing/libabc.dylib'
>>> monkeypatch.setattr(os.path, 'exists',
... lambda d: 'existing' in d and '.a' in d)
>>> compiler.find_library_file(dirs, 'abc').replace('\\', '/')
'/foo/bar/existing/libabc.a'
>>> compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/')
'/foo/bar/existing/libabc.a'
"""
lib_names = (
self.library_filename(lib, lib_type=type)
for type in 'dylib xcode_stub shared static'.split()
)
roots = map(self._library_root, dirs)
searched = (
os.path.join(root, lib_name)
for root, lib_name in itertools.product(roots, lib_names)
)
for dir in dirs:
shared = os.path.join(dir, shared_f)
dylib = os.path.join(dir, dylib_f)
static = os.path.join(dir, static_f)
xcode_stub = os.path.join(dir, xcode_stub_f)
found = filter(os.path.exists, searched)
if sys.platform == 'darwin' and (
dir.startswith('/System/') or (
dir.startswith('/usr/') and not dir.startswith('/usr/local/'))):
shared = os.path.join(sysroot, dir[1:], shared_f)
dylib = os.path.join(sysroot, dir[1:], dylib_f)
static = os.path.join(sysroot, dir[1:], static_f)
xcode_stub = os.path.join(sysroot, dir[1:], xcode_stub_f)
# We're second-guessing the linker here, with not much hard
# data to go on: GCC seems to prefer the shared library, so I'm
# assuming that *all* Unix C compilers do. And of course I'm
# ignoring even GCC's "-static" option. So sue me.
if os.path.exists(dylib):
return dylib
elif os.path.exists(xcode_stub):
return xcode_stub
elif os.path.exists(shared):
return shared
elif os.path.exists(static):
return static
# Oops, didn't find it in *any* of 'dirs'
return None
# Return None if it could not be found in any dir.
return next(found, None)