17db96d56Sopenharmony_ci# Autodetecting setup.py script for building the Python extensions 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciimport argparse 47db96d56Sopenharmony_ciimport importlib._bootstrap 57db96d56Sopenharmony_ciimport importlib.machinery 67db96d56Sopenharmony_ciimport importlib.util 77db96d56Sopenharmony_ciimport logging 87db96d56Sopenharmony_ciimport os 97db96d56Sopenharmony_ciimport re 107db96d56Sopenharmony_ciimport shlex 117db96d56Sopenharmony_ciimport sys 127db96d56Sopenharmony_ciimport sysconfig 137db96d56Sopenharmony_ciimport warnings 147db96d56Sopenharmony_cifrom glob import glob, escape 157db96d56Sopenharmony_ciimport _osx_support 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_citry: 197db96d56Sopenharmony_ci import subprocess 207db96d56Sopenharmony_ci del subprocess 217db96d56Sopenharmony_ci SUBPROCESS_BOOTSTRAP = False 227db96d56Sopenharmony_ciexcept ImportError: 237db96d56Sopenharmony_ci # Bootstrap Python: distutils.spawn uses subprocess to build C extensions, 247db96d56Sopenharmony_ci # subprocess requires C extensions built by setup.py like _posixsubprocess. 257db96d56Sopenharmony_ci # 267db96d56Sopenharmony_ci # Use _bootsubprocess which only uses the os module. 277db96d56Sopenharmony_ci # 287db96d56Sopenharmony_ci # It is dropped from sys.modules as soon as all C extension modules 297db96d56Sopenharmony_ci # are built. 307db96d56Sopenharmony_ci import _bootsubprocess 317db96d56Sopenharmony_ci sys.modules['subprocess'] = _bootsubprocess 327db96d56Sopenharmony_ci del _bootsubprocess 337db96d56Sopenharmony_ci SUBPROCESS_BOOTSTRAP = True 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ciwith warnings.catch_warnings(): 377db96d56Sopenharmony_ci # bpo-41282 (PEP 632) deprecated distutils but setup.py still uses it 387db96d56Sopenharmony_ci warnings.filterwarnings( 397db96d56Sopenharmony_ci "ignore", 407db96d56Sopenharmony_ci "The distutils package is deprecated", 417db96d56Sopenharmony_ci DeprecationWarning 427db96d56Sopenharmony_ci ) 437db96d56Sopenharmony_ci warnings.filterwarnings( 447db96d56Sopenharmony_ci "ignore", 457db96d56Sopenharmony_ci "The distutils.sysconfig module is deprecated, use sysconfig instead", 467db96d56Sopenharmony_ci DeprecationWarning 477db96d56Sopenharmony_ci ) 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci from distutils.command.build_ext import build_ext 507db96d56Sopenharmony_ci from distutils.command.build_scripts import build_scripts 517db96d56Sopenharmony_ci from distutils.command.install import install 527db96d56Sopenharmony_ci from distutils.command.install_lib import install_lib 537db96d56Sopenharmony_ci from distutils.core import Extension, setup 547db96d56Sopenharmony_ci from distutils.errors import CCompilerError, DistutilsError 557db96d56Sopenharmony_ci from distutils.spawn import find_executable 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci# This global variable is used to hold the list of modules to be disabled. 597db96d56Sopenharmony_ciDISABLED_MODULE_LIST = [] 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci# --list-module-names option used by Tools/scripts/generate_module_names.py 627db96d56Sopenharmony_ciLIST_MODULE_NAMES = False 637db96d56Sopenharmony_ci 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_cilogging.basicConfig(format='%(message)s', level=logging.INFO) 667db96d56Sopenharmony_cilog = logging.getLogger('setup') 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_cidef get_platform(): 707db96d56Sopenharmony_ci # Cross compiling 717db96d56Sopenharmony_ci if "_PYTHON_HOST_PLATFORM" in os.environ: 727db96d56Sopenharmony_ci return os.environ["_PYTHON_HOST_PLATFORM"] 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci # Get value of sys.platform 757db96d56Sopenharmony_ci if sys.platform.startswith('osf1'): 767db96d56Sopenharmony_ci return 'osf1' 777db96d56Sopenharmony_ci return sys.platform 787db96d56Sopenharmony_ci 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_ciCROSS_COMPILING = ("_PYTHON_HOST_PLATFORM" in os.environ) 817db96d56Sopenharmony_ciHOST_PLATFORM = get_platform() 827db96d56Sopenharmony_ciMS_WINDOWS = (HOST_PLATFORM == 'win32') 837db96d56Sopenharmony_ciCYGWIN = (HOST_PLATFORM == 'cygwin') 847db96d56Sopenharmony_ciMACOS = (HOST_PLATFORM == 'darwin') 857db96d56Sopenharmony_ciAIX = (HOST_PLATFORM.startswith('aix')) 867db96d56Sopenharmony_ciVXWORKS = ('vxworks' in HOST_PLATFORM) 877db96d56Sopenharmony_ciEMSCRIPTEN = HOST_PLATFORM == 'emscripten-wasm32' 887db96d56Sopenharmony_ciCC = os.environ.get("CC") 897db96d56Sopenharmony_ciif not CC: 907db96d56Sopenharmony_ci CC = sysconfig.get_config_var("CC") 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ciif EMSCRIPTEN: 937db96d56Sopenharmony_ci # emcc is a Python script from a different Python interpreter. 947db96d56Sopenharmony_ci os.environ.pop("PYTHONPATH", None) 957db96d56Sopenharmony_ci 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ciSUMMARY = """ 987db96d56Sopenharmony_ciPython is an interpreted, interactive, object-oriented programming 997db96d56Sopenharmony_cilanguage. It is often compared to Tcl, Perl, Scheme or Java. 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ciPython combines remarkable power with very clear syntax. It has 1027db96d56Sopenharmony_cimodules, classes, exceptions, very high level dynamic data types, and 1037db96d56Sopenharmony_cidynamic typing. There are interfaces to many system calls and 1047db96d56Sopenharmony_cilibraries, as well as to various windowing systems (X11, Motif, Tk, 1057db96d56Sopenharmony_ciMac, MFC). New built-in modules are easily written in C or C++. Python 1067db96d56Sopenharmony_ciis also usable as an extension language for applications that need a 1077db96d56Sopenharmony_ciprogrammable interface. 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ciThe Python implementation is portable: it runs on many brands of UNIX, 1107db96d56Sopenharmony_cion Windows, DOS, Mac, Amiga... If your favorite system isn't 1117db96d56Sopenharmony_cilisted here, it may still be supported, if there's a C compiler for 1127db96d56Sopenharmony_ciit. Ask around on comp.lang.python -- or just try compiling Python 1137db96d56Sopenharmony_ciyourself. 1147db96d56Sopenharmony_ci""" 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_ciCLASSIFIERS = """ 1177db96d56Sopenharmony_ciDevelopment Status :: 6 - Mature 1187db96d56Sopenharmony_ciLicense :: OSI Approved :: Python Software Foundation License 1197db96d56Sopenharmony_ciNatural Language :: English 1207db96d56Sopenharmony_ciProgramming Language :: C 1217db96d56Sopenharmony_ciProgramming Language :: Python 1227db96d56Sopenharmony_ciTopic :: Software Development 1237db96d56Sopenharmony_ci""" 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ci 1267db96d56Sopenharmony_cidef run_command(cmd): 1277db96d56Sopenharmony_ci status = os.system(cmd) 1287db96d56Sopenharmony_ci return os.waitstatus_to_exitcode(status) 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci 1317db96d56Sopenharmony_ci# Set common compiler and linker flags derived from the Makefile, 1327db96d56Sopenharmony_ci# reserved for building the interpreter and the stdlib modules. 1337db96d56Sopenharmony_ci# See bpo-21121 and bpo-35257 1347db96d56Sopenharmony_cidef set_compiler_flags(compiler_flags, compiler_py_flags_nodist): 1357db96d56Sopenharmony_ci flags = sysconfig.get_config_var(compiler_flags) 1367db96d56Sopenharmony_ci py_flags_nodist = sysconfig.get_config_var(compiler_py_flags_nodist) 1377db96d56Sopenharmony_ci sysconfig.get_config_vars()[compiler_flags] = flags + ' ' + py_flags_nodist 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_cidef add_dir_to_list(dirlist, dir): 1417db96d56Sopenharmony_ci """Add the directory 'dir' to the list 'dirlist' (after any relative 1427db96d56Sopenharmony_ci directories) if: 1437db96d56Sopenharmony_ci 1447db96d56Sopenharmony_ci 1) 'dir' is not already in 'dirlist' 1457db96d56Sopenharmony_ci 2) 'dir' actually exists, and is a directory. 1467db96d56Sopenharmony_ci """ 1477db96d56Sopenharmony_ci if dir is None or not os.path.isdir(dir) or dir in dirlist: 1487db96d56Sopenharmony_ci return 1497db96d56Sopenharmony_ci for i, path in enumerate(dirlist): 1507db96d56Sopenharmony_ci if not os.path.isabs(path): 1517db96d56Sopenharmony_ci dirlist.insert(i + 1, dir) 1527db96d56Sopenharmony_ci return 1537db96d56Sopenharmony_ci dirlist.insert(0, dir) 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_cidef sysroot_paths(make_vars, subdirs): 1577db96d56Sopenharmony_ci """Get the paths of sysroot sub-directories. 1587db96d56Sopenharmony_ci 1597db96d56Sopenharmony_ci * make_vars: a sequence of names of variables of the Makefile where 1607db96d56Sopenharmony_ci sysroot may be set. 1617db96d56Sopenharmony_ci * subdirs: a sequence of names of subdirectories used as the location for 1627db96d56Sopenharmony_ci headers or libraries. 1637db96d56Sopenharmony_ci """ 1647db96d56Sopenharmony_ci 1657db96d56Sopenharmony_ci dirs = [] 1667db96d56Sopenharmony_ci for var_name in make_vars: 1677db96d56Sopenharmony_ci var = sysconfig.get_config_var(var_name) 1687db96d56Sopenharmony_ci if var is not None: 1697db96d56Sopenharmony_ci m = re.search(r'--sysroot=([^"]\S*|"[^"]+")', var) 1707db96d56Sopenharmony_ci if m is not None: 1717db96d56Sopenharmony_ci sysroot = m.group(1).strip('"') 1727db96d56Sopenharmony_ci for subdir in subdirs: 1737db96d56Sopenharmony_ci if os.path.isabs(subdir): 1747db96d56Sopenharmony_ci subdir = subdir[1:] 1757db96d56Sopenharmony_ci path = os.path.join(sysroot, subdir) 1767db96d56Sopenharmony_ci if os.path.isdir(path): 1777db96d56Sopenharmony_ci dirs.append(path) 1787db96d56Sopenharmony_ci break 1797db96d56Sopenharmony_ci return dirs 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_ciMACOS_SDK_ROOT = None 1837db96d56Sopenharmony_ciMACOS_SDK_SPECIFIED = None 1847db96d56Sopenharmony_ci 1857db96d56Sopenharmony_cidef macosx_sdk_root(): 1867db96d56Sopenharmony_ci """Return the directory of the current macOS SDK. 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci If no SDK was explicitly configured, call the compiler to find which 1897db96d56Sopenharmony_ci include files paths are being searched by default. Use '/' if the 1907db96d56Sopenharmony_ci compiler is searching /usr/include (meaning system header files are 1917db96d56Sopenharmony_ci installed) or use the root of an SDK if that is being searched. 1927db96d56Sopenharmony_ci (The SDK may be supplied via Xcode or via the Command Line Tools). 1937db96d56Sopenharmony_ci The SDK paths used by Apple-supplied tool chains depend on the 1947db96d56Sopenharmony_ci setting of various variables; see the xcrun man page for more info. 1957db96d56Sopenharmony_ci Also sets MACOS_SDK_SPECIFIED for use by macosx_sdk_specified(). 1967db96d56Sopenharmony_ci """ 1977db96d56Sopenharmony_ci global MACOS_SDK_ROOT, MACOS_SDK_SPECIFIED 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci # If already called, return cached result. 2007db96d56Sopenharmony_ci if MACOS_SDK_ROOT: 2017db96d56Sopenharmony_ci return MACOS_SDK_ROOT 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci cflags = sysconfig.get_config_var('CFLAGS') 2047db96d56Sopenharmony_ci m = re.search(r'-isysroot\s*(\S+)', cflags) 2057db96d56Sopenharmony_ci if m is not None: 2067db96d56Sopenharmony_ci MACOS_SDK_ROOT = m.group(1) 2077db96d56Sopenharmony_ci MACOS_SDK_SPECIFIED = MACOS_SDK_ROOT != '/' 2087db96d56Sopenharmony_ci else: 2097db96d56Sopenharmony_ci MACOS_SDK_ROOT = _osx_support._default_sysroot( 2107db96d56Sopenharmony_ci sysconfig.get_config_var('CC')) 2117db96d56Sopenharmony_ci MACOS_SDK_SPECIFIED = False 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci return MACOS_SDK_ROOT 2147db96d56Sopenharmony_ci 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_cidef is_macosx_sdk_path(path): 2177db96d56Sopenharmony_ci """ 2187db96d56Sopenharmony_ci Returns True if 'path' can be located in a macOS SDK 2197db96d56Sopenharmony_ci """ 2207db96d56Sopenharmony_ci return ( (path.startswith('/usr/') and not path.startswith('/usr/local')) 2217db96d56Sopenharmony_ci or path.startswith('/System/Library') 2227db96d56Sopenharmony_ci or path.startswith('/System/iOSSupport') ) 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ci 2257db96d56Sopenharmony_cidef grep_headers_for(function, headers): 2267db96d56Sopenharmony_ci for header in headers: 2277db96d56Sopenharmony_ci with open(header, 'r', errors='surrogateescape') as f: 2287db96d56Sopenharmony_ci if function in f.read(): 2297db96d56Sopenharmony_ci return True 2307db96d56Sopenharmony_ci return False 2317db96d56Sopenharmony_ci 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_cidef find_file(filename, std_dirs, paths): 2347db96d56Sopenharmony_ci """Searches for the directory where a given file is located, 2357db96d56Sopenharmony_ci and returns a possibly-empty list of additional directories, or None 2367db96d56Sopenharmony_ci if the file couldn't be found at all. 2377db96d56Sopenharmony_ci 2387db96d56Sopenharmony_ci 'filename' is the name of a file, such as readline.h or libcrypto.a. 2397db96d56Sopenharmony_ci 'std_dirs' is the list of standard system directories; if the 2407db96d56Sopenharmony_ci file is found in one of them, no additional directives are needed. 2417db96d56Sopenharmony_ci 'paths' is a list of additional locations to check; if the file is 2427db96d56Sopenharmony_ci found in one of them, the resulting list will contain the directory. 2437db96d56Sopenharmony_ci """ 2447db96d56Sopenharmony_ci if MACOS: 2457db96d56Sopenharmony_ci # Honor the MacOSX SDK setting when one was specified. 2467db96d56Sopenharmony_ci # An SDK is a directory with the same structure as a real 2477db96d56Sopenharmony_ci # system, but with only header files and libraries. 2487db96d56Sopenharmony_ci sysroot = macosx_sdk_root() 2497db96d56Sopenharmony_ci 2507db96d56Sopenharmony_ci # Check the standard locations 2517db96d56Sopenharmony_ci for dir_ in std_dirs: 2527db96d56Sopenharmony_ci f = os.path.join(dir_, filename) 2537db96d56Sopenharmony_ci 2547db96d56Sopenharmony_ci if MACOS and is_macosx_sdk_path(dir_): 2557db96d56Sopenharmony_ci f = os.path.join(sysroot, dir_[1:], filename) 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ci if os.path.exists(f): return [] 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci # Check the additional directories 2607db96d56Sopenharmony_ci for dir_ in paths: 2617db96d56Sopenharmony_ci f = os.path.join(dir_, filename) 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci if MACOS and is_macosx_sdk_path(dir_): 2647db96d56Sopenharmony_ci f = os.path.join(sysroot, dir_[1:], filename) 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci if os.path.exists(f): 2677db96d56Sopenharmony_ci return [dir_] 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_ci # Not found anywhere 2707db96d56Sopenharmony_ci return None 2717db96d56Sopenharmony_ci 2727db96d56Sopenharmony_ci 2737db96d56Sopenharmony_cidef validate_tzpath(): 2747db96d56Sopenharmony_ci base_tzpath = sysconfig.get_config_var('TZPATH') 2757db96d56Sopenharmony_ci if not base_tzpath: 2767db96d56Sopenharmony_ci return 2777db96d56Sopenharmony_ci 2787db96d56Sopenharmony_ci tzpaths = base_tzpath.split(os.pathsep) 2797db96d56Sopenharmony_ci bad_paths = [tzpath for tzpath in tzpaths if not os.path.isabs(tzpath)] 2807db96d56Sopenharmony_ci if bad_paths: 2817db96d56Sopenharmony_ci raise ValueError('TZPATH must contain only absolute paths, ' 2827db96d56Sopenharmony_ci + f'found:\n{tzpaths!r}\nwith invalid paths:\n' 2837db96d56Sopenharmony_ci + f'{bad_paths!r}') 2847db96d56Sopenharmony_ci 2857db96d56Sopenharmony_ci 2867db96d56Sopenharmony_cidef find_module_file(module, dirlist): 2877db96d56Sopenharmony_ci """Find a module in a set of possible folders. If it is not found 2887db96d56Sopenharmony_ci return the unadorned filename""" 2897db96d56Sopenharmony_ci dirs = find_file(module, [], dirlist) 2907db96d56Sopenharmony_ci if not dirs: 2917db96d56Sopenharmony_ci return module 2927db96d56Sopenharmony_ci if len(dirs) > 1: 2937db96d56Sopenharmony_ci log.info(f"WARNING: multiple copies of {module} found") 2947db96d56Sopenharmony_ci return os.path.abspath(os.path.join(dirs[0], module)) 2957db96d56Sopenharmony_ci 2967db96d56Sopenharmony_ci 2977db96d56Sopenharmony_ciclass PyBuildExt(build_ext): 2987db96d56Sopenharmony_ci 2997db96d56Sopenharmony_ci def __init__(self, dist): 3007db96d56Sopenharmony_ci build_ext.__init__(self, dist) 3017db96d56Sopenharmony_ci self.srcdir = None 3027db96d56Sopenharmony_ci self.lib_dirs = None 3037db96d56Sopenharmony_ci self.inc_dirs = None 3047db96d56Sopenharmony_ci self.config_h_vars = None 3057db96d56Sopenharmony_ci self.failed = [] 3067db96d56Sopenharmony_ci self.failed_on_import = [] 3077db96d56Sopenharmony_ci self.missing = [] 3087db96d56Sopenharmony_ci self.disabled_configure = [] 3097db96d56Sopenharmony_ci if '-j' in os.environ.get('MAKEFLAGS', ''): 3107db96d56Sopenharmony_ci self.parallel = True 3117db96d56Sopenharmony_ci 3127db96d56Sopenharmony_ci def add(self, ext): 3137db96d56Sopenharmony_ci self.extensions.append(ext) 3147db96d56Sopenharmony_ci 3157db96d56Sopenharmony_ci def addext(self, ext, *, update_flags=True): 3167db96d56Sopenharmony_ci """Add extension with Makefile MODULE_{name} support 3177db96d56Sopenharmony_ci """ 3187db96d56Sopenharmony_ci if update_flags: 3197db96d56Sopenharmony_ci self.update_extension_flags(ext) 3207db96d56Sopenharmony_ci 3217db96d56Sopenharmony_ci state = sysconfig.get_config_var(f"MODULE_{ext.name.upper()}_STATE") 3227db96d56Sopenharmony_ci if state == "yes": 3237db96d56Sopenharmony_ci self.extensions.append(ext) 3247db96d56Sopenharmony_ci elif state == "disabled": 3257db96d56Sopenharmony_ci self.disabled_configure.append(ext.name) 3267db96d56Sopenharmony_ci elif state == "missing": 3277db96d56Sopenharmony_ci self.missing.append(ext.name) 3287db96d56Sopenharmony_ci elif state == "n/a": 3297db96d56Sopenharmony_ci # not available on current platform 3307db96d56Sopenharmony_ci pass 3317db96d56Sopenharmony_ci else: 3327db96d56Sopenharmony_ci # not migrated to MODULE_{name}_STATE yet. 3337db96d56Sopenharmony_ci self.announce( 3347db96d56Sopenharmony_ci f'WARNING: Makefile is missing module variable for "{ext.name}"', 3357db96d56Sopenharmony_ci level=2 3367db96d56Sopenharmony_ci ) 3377db96d56Sopenharmony_ci self.extensions.append(ext) 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_ci def update_extension_flags(self, ext): 3407db96d56Sopenharmony_ci """Update extension flags with module CFLAGS and LDFLAGS 3417db96d56Sopenharmony_ci 3427db96d56Sopenharmony_ci Reads MODULE_{name}_CFLAGS and _LDFLAGS 3437db96d56Sopenharmony_ci 3447db96d56Sopenharmony_ci Distutils appends extra args to the compiler arguments. Some flags like 3457db96d56Sopenharmony_ci -I must appear earlier, otherwise the pre-processor picks up files 3467db96d56Sopenharmony_ci from system include directories. 3477db96d56Sopenharmony_ci """ 3487db96d56Sopenharmony_ci upper_name = ext.name.upper() 3497db96d56Sopenharmony_ci # Parse compiler flags (-I, -D, -U, extra args) 3507db96d56Sopenharmony_ci cflags = sysconfig.get_config_var(f"MODULE_{upper_name}_CFLAGS") 3517db96d56Sopenharmony_ci if cflags: 3527db96d56Sopenharmony_ci for token in shlex.split(cflags): 3537db96d56Sopenharmony_ci switch = token[0:2] 3547db96d56Sopenharmony_ci value = token[2:] 3557db96d56Sopenharmony_ci if switch == '-I': 3567db96d56Sopenharmony_ci ext.include_dirs.append(value) 3577db96d56Sopenharmony_ci elif switch == '-D': 3587db96d56Sopenharmony_ci key, _, val = value.partition("=") 3597db96d56Sopenharmony_ci if not val: 3607db96d56Sopenharmony_ci val = None 3617db96d56Sopenharmony_ci ext.define_macros.append((key, val)) 3627db96d56Sopenharmony_ci elif switch == '-U': 3637db96d56Sopenharmony_ci ext.undef_macros.append(value) 3647db96d56Sopenharmony_ci else: 3657db96d56Sopenharmony_ci ext.extra_compile_args.append(token) 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci # Parse linker flags (-L, -l, extra objects, extra args) 3687db96d56Sopenharmony_ci ldflags = sysconfig.get_config_var(f"MODULE_{upper_name}_LDFLAGS") 3697db96d56Sopenharmony_ci if ldflags: 3707db96d56Sopenharmony_ci for token in shlex.split(ldflags): 3717db96d56Sopenharmony_ci switch = token[0:2] 3727db96d56Sopenharmony_ci value = token[2:] 3737db96d56Sopenharmony_ci if switch == '-L': 3747db96d56Sopenharmony_ci ext.library_dirs.append(value) 3757db96d56Sopenharmony_ci elif switch == '-l': 3767db96d56Sopenharmony_ci ext.libraries.append(value) 3777db96d56Sopenharmony_ci elif ( 3787db96d56Sopenharmony_ci token[0] != '-' and 3797db96d56Sopenharmony_ci token.endswith(('.a', '.o', '.so', '.sl', '.dylib')) 3807db96d56Sopenharmony_ci ): 3817db96d56Sopenharmony_ci ext.extra_objects.append(token) 3827db96d56Sopenharmony_ci else: 3837db96d56Sopenharmony_ci ext.extra_link_args.append(token) 3847db96d56Sopenharmony_ci 3857db96d56Sopenharmony_ci return ext 3867db96d56Sopenharmony_ci 3877db96d56Sopenharmony_ci def set_srcdir(self): 3887db96d56Sopenharmony_ci self.srcdir = sysconfig.get_config_var('srcdir') 3897db96d56Sopenharmony_ci if not self.srcdir: 3907db96d56Sopenharmony_ci # Maybe running on Windows but not using CYGWIN? 3917db96d56Sopenharmony_ci raise ValueError("No source directory; cannot proceed.") 3927db96d56Sopenharmony_ci self.srcdir = os.path.abspath(self.srcdir) 3937db96d56Sopenharmony_ci 3947db96d56Sopenharmony_ci def remove_disabled(self): 3957db96d56Sopenharmony_ci # Remove modules that are present on the disabled list 3967db96d56Sopenharmony_ci extensions = [ext for ext in self.extensions 3977db96d56Sopenharmony_ci if ext.name not in DISABLED_MODULE_LIST] 3987db96d56Sopenharmony_ci # move ctypes to the end, it depends on other modules 3997db96d56Sopenharmony_ci ext_map = dict((ext.name, i) for i, ext in enumerate(extensions)) 4007db96d56Sopenharmony_ci if "_ctypes" in ext_map: 4017db96d56Sopenharmony_ci ctypes = extensions.pop(ext_map["_ctypes"]) 4027db96d56Sopenharmony_ci extensions.append(ctypes) 4037db96d56Sopenharmony_ci self.extensions = extensions 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci def update_sources_depends(self): 4067db96d56Sopenharmony_ci # Fix up the autodetected modules, prefixing all the source files 4077db96d56Sopenharmony_ci # with Modules/. 4087db96d56Sopenharmony_ci # Add dependencies from MODULE_{name}_DEPS variable 4097db96d56Sopenharmony_ci moddirlist = [ 4107db96d56Sopenharmony_ci # files in Modules/ directory 4117db96d56Sopenharmony_ci os.path.join(self.srcdir, 'Modules'), 4127db96d56Sopenharmony_ci # files relative to build base, e.g. libmpdec.a, libexpat.a 4137db96d56Sopenharmony_ci os.getcwd() 4147db96d56Sopenharmony_ci ] 4157db96d56Sopenharmony_ci 4167db96d56Sopenharmony_ci # Fix up the paths for scripts, too 4177db96d56Sopenharmony_ci self.distribution.scripts = [os.path.join(self.srcdir, filename) 4187db96d56Sopenharmony_ci for filename in self.distribution.scripts] 4197db96d56Sopenharmony_ci 4207db96d56Sopenharmony_ci # Python header files 4217db96d56Sopenharmony_ci include_dir = escape(sysconfig.get_path('include')) 4227db96d56Sopenharmony_ci headers = [sysconfig.get_config_h_filename()] 4237db96d56Sopenharmony_ci headers.extend(glob(os.path.join(include_dir, "*.h"))) 4247db96d56Sopenharmony_ci headers.extend(glob(os.path.join(include_dir, "cpython", "*.h"))) 4257db96d56Sopenharmony_ci headers.extend(glob(os.path.join(include_dir, "internal", "*.h"))) 4267db96d56Sopenharmony_ci 4277db96d56Sopenharmony_ci for ext in self.extensions: 4287db96d56Sopenharmony_ci ext.sources = [ find_module_file(filename, moddirlist) 4297db96d56Sopenharmony_ci for filename in ext.sources ] 4307db96d56Sopenharmony_ci # Update dependencies from Makefile 4317db96d56Sopenharmony_ci makedeps = sysconfig.get_config_var(f"MODULE_{ext.name.upper()}_DEPS") 4327db96d56Sopenharmony_ci if makedeps: 4337db96d56Sopenharmony_ci # remove backslashes from line break continuations 4347db96d56Sopenharmony_ci ext.depends.extend( 4357db96d56Sopenharmony_ci dep for dep in makedeps.split() if dep != "\\" 4367db96d56Sopenharmony_ci ) 4377db96d56Sopenharmony_ci ext.depends = [ 4387db96d56Sopenharmony_ci find_module_file(filename, moddirlist) for filename in ext.depends 4397db96d56Sopenharmony_ci ] 4407db96d56Sopenharmony_ci # re-compile extensions if a header file has been changed 4417db96d56Sopenharmony_ci ext.depends.extend(headers) 4427db96d56Sopenharmony_ci 4437db96d56Sopenharmony_ci def handle_configured_extensions(self): 4447db96d56Sopenharmony_ci # The sysconfig variables built by makesetup that list the already 4457db96d56Sopenharmony_ci # built modules and the disabled modules as configured by the Setup 4467db96d56Sopenharmony_ci # files. 4477db96d56Sopenharmony_ci sysconf_built = set(sysconfig.get_config_var('MODBUILT_NAMES').split()) 4487db96d56Sopenharmony_ci sysconf_shared = set(sysconfig.get_config_var('MODSHARED_NAMES').split()) 4497db96d56Sopenharmony_ci sysconf_dis = set(sysconfig.get_config_var('MODDISABLED_NAMES').split()) 4507db96d56Sopenharmony_ci 4517db96d56Sopenharmony_ci mods_built = [] 4527db96d56Sopenharmony_ci mods_disabled = [] 4537db96d56Sopenharmony_ci for ext in self.extensions: 4547db96d56Sopenharmony_ci # If a module has already been built or has been disabled in the 4557db96d56Sopenharmony_ci # Setup files, don't build it here. 4567db96d56Sopenharmony_ci if ext.name in sysconf_built: 4577db96d56Sopenharmony_ci mods_built.append(ext) 4587db96d56Sopenharmony_ci if ext.name in sysconf_dis: 4597db96d56Sopenharmony_ci mods_disabled.append(ext) 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_ci mods_configured = mods_built + mods_disabled 4627db96d56Sopenharmony_ci if mods_configured: 4637db96d56Sopenharmony_ci self.extensions = [x for x in self.extensions if x not in 4647db96d56Sopenharmony_ci mods_configured] 4657db96d56Sopenharmony_ci # Remove the shared libraries built by a previous build. 4667db96d56Sopenharmony_ci for ext in mods_configured: 4677db96d56Sopenharmony_ci # Don't remove shared extensions which have been built 4687db96d56Sopenharmony_ci # by Modules/Setup 4697db96d56Sopenharmony_ci if ext.name in sysconf_shared: 4707db96d56Sopenharmony_ci continue 4717db96d56Sopenharmony_ci fullpath = self.get_ext_fullpath(ext.name) 4727db96d56Sopenharmony_ci if os.path.lexists(fullpath): 4737db96d56Sopenharmony_ci os.unlink(fullpath) 4747db96d56Sopenharmony_ci 4757db96d56Sopenharmony_ci return mods_built, mods_disabled 4767db96d56Sopenharmony_ci 4777db96d56Sopenharmony_ci def set_compiler_executables(self): 4787db96d56Sopenharmony_ci # When you run "make CC=altcc" or something similar, you really want 4797db96d56Sopenharmony_ci # those environment variables passed into the setup.py phase. Here's 4807db96d56Sopenharmony_ci # a small set of useful ones. 4817db96d56Sopenharmony_ci compiler = os.environ.get('CC') 4827db96d56Sopenharmony_ci args = {} 4837db96d56Sopenharmony_ci # unfortunately, distutils doesn't let us provide separate C and C++ 4847db96d56Sopenharmony_ci # compilers 4857db96d56Sopenharmony_ci if compiler is not None: 4867db96d56Sopenharmony_ci (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS') 4877db96d56Sopenharmony_ci args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags 4887db96d56Sopenharmony_ci self.compiler.set_executables(**args) 4897db96d56Sopenharmony_ci 4907db96d56Sopenharmony_ci def build_extensions(self): 4917db96d56Sopenharmony_ci self.set_srcdir() 4927db96d56Sopenharmony_ci self.set_compiler_executables() 4937db96d56Sopenharmony_ci self.configure_compiler() 4947db96d56Sopenharmony_ci self.init_inc_lib_dirs() 4957db96d56Sopenharmony_ci 4967db96d56Sopenharmony_ci # Detect which modules should be compiled 4977db96d56Sopenharmony_ci self.detect_modules() 4987db96d56Sopenharmony_ci 4997db96d56Sopenharmony_ci if not LIST_MODULE_NAMES: 5007db96d56Sopenharmony_ci self.remove_disabled() 5017db96d56Sopenharmony_ci 5027db96d56Sopenharmony_ci self.update_sources_depends() 5037db96d56Sopenharmony_ci mods_built, mods_disabled = self.handle_configured_extensions() 5047db96d56Sopenharmony_ci 5057db96d56Sopenharmony_ci if LIST_MODULE_NAMES: 5067db96d56Sopenharmony_ci for ext in self.extensions: 5077db96d56Sopenharmony_ci print(ext.name) 5087db96d56Sopenharmony_ci for name in self.missing: 5097db96d56Sopenharmony_ci print(name) 5107db96d56Sopenharmony_ci return 5117db96d56Sopenharmony_ci 5127db96d56Sopenharmony_ci build_ext.build_extensions(self) 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ci if SUBPROCESS_BOOTSTRAP: 5157db96d56Sopenharmony_ci # Drop our custom subprocess module: 5167db96d56Sopenharmony_ci # use the newly built subprocess module 5177db96d56Sopenharmony_ci del sys.modules['subprocess'] 5187db96d56Sopenharmony_ci 5197db96d56Sopenharmony_ci for ext in self.extensions: 5207db96d56Sopenharmony_ci self.check_extension_import(ext) 5217db96d56Sopenharmony_ci 5227db96d56Sopenharmony_ci self.summary(mods_built, mods_disabled) 5237db96d56Sopenharmony_ci 5247db96d56Sopenharmony_ci def summary(self, mods_built, mods_disabled): 5257db96d56Sopenharmony_ci longest = max([len(e.name) for e in self.extensions], default=0) 5267db96d56Sopenharmony_ci if self.failed or self.failed_on_import: 5277db96d56Sopenharmony_ci all_failed = self.failed + self.failed_on_import 5287db96d56Sopenharmony_ci longest = max(longest, max([len(name) for name in all_failed])) 5297db96d56Sopenharmony_ci 5307db96d56Sopenharmony_ci def print_three_column(lst): 5317db96d56Sopenharmony_ci lst.sort(key=str.lower) 5327db96d56Sopenharmony_ci # guarantee zip() doesn't drop anything 5337db96d56Sopenharmony_ci while len(lst) % 3: 5347db96d56Sopenharmony_ci lst.append("") 5357db96d56Sopenharmony_ci for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]): 5367db96d56Sopenharmony_ci print("%-*s %-*s %-*s" % (longest, e, longest, f, 5377db96d56Sopenharmony_ci longest, g)) 5387db96d56Sopenharmony_ci 5397db96d56Sopenharmony_ci if self.missing: 5407db96d56Sopenharmony_ci print() 5417db96d56Sopenharmony_ci print("The necessary bits to build these optional modules were not " 5427db96d56Sopenharmony_ci "found:") 5437db96d56Sopenharmony_ci print_three_column(self.missing) 5447db96d56Sopenharmony_ci print("To find the necessary bits, look in setup.py in" 5457db96d56Sopenharmony_ci " detect_modules() for the module's name.") 5467db96d56Sopenharmony_ci print() 5477db96d56Sopenharmony_ci 5487db96d56Sopenharmony_ci if mods_built: 5497db96d56Sopenharmony_ci print() 5507db96d56Sopenharmony_ci print("The following modules found by detect_modules() in" 5517db96d56Sopenharmony_ci " setup.py, have been") 5527db96d56Sopenharmony_ci print("built by the Makefile instead, as configured by the" 5537db96d56Sopenharmony_ci " Setup files:") 5547db96d56Sopenharmony_ci print_three_column([ext.name for ext in mods_built]) 5557db96d56Sopenharmony_ci print() 5567db96d56Sopenharmony_ci 5577db96d56Sopenharmony_ci if mods_disabled: 5587db96d56Sopenharmony_ci print() 5597db96d56Sopenharmony_ci print("The following modules found by detect_modules() in" 5607db96d56Sopenharmony_ci " setup.py have not") 5617db96d56Sopenharmony_ci print("been built, they are *disabled* in the Setup files:") 5627db96d56Sopenharmony_ci print_three_column([ext.name for ext in mods_disabled]) 5637db96d56Sopenharmony_ci print() 5647db96d56Sopenharmony_ci 5657db96d56Sopenharmony_ci if self.disabled_configure: 5667db96d56Sopenharmony_ci print() 5677db96d56Sopenharmony_ci print("The following modules found by detect_modules() in" 5687db96d56Sopenharmony_ci " setup.py have not") 5697db96d56Sopenharmony_ci print("been built, they are *disabled* by configure:") 5707db96d56Sopenharmony_ci print_three_column(self.disabled_configure) 5717db96d56Sopenharmony_ci print() 5727db96d56Sopenharmony_ci 5737db96d56Sopenharmony_ci if self.failed: 5747db96d56Sopenharmony_ci failed = self.failed[:] 5757db96d56Sopenharmony_ci print() 5767db96d56Sopenharmony_ci print("Failed to build these modules:") 5777db96d56Sopenharmony_ci print_three_column(failed) 5787db96d56Sopenharmony_ci print() 5797db96d56Sopenharmony_ci 5807db96d56Sopenharmony_ci if self.failed_on_import: 5817db96d56Sopenharmony_ci failed = self.failed_on_import[:] 5827db96d56Sopenharmony_ci print() 5837db96d56Sopenharmony_ci print("Following modules built successfully" 5847db96d56Sopenharmony_ci " but were removed because they could not be imported:") 5857db96d56Sopenharmony_ci print_three_column(failed) 5867db96d56Sopenharmony_ci print() 5877db96d56Sopenharmony_ci 5887db96d56Sopenharmony_ci if any('_ssl' in l 5897db96d56Sopenharmony_ci for l in (self.missing, self.failed, self.failed_on_import)): 5907db96d56Sopenharmony_ci print() 5917db96d56Sopenharmony_ci print("Could not build the ssl module!") 5927db96d56Sopenharmony_ci print("Python requires a OpenSSL 1.1.1 or newer") 5937db96d56Sopenharmony_ci if sysconfig.get_config_var("OPENSSL_LDFLAGS"): 5947db96d56Sopenharmony_ci print("Custom linker flags may require --with-openssl-rpath=auto") 5957db96d56Sopenharmony_ci print() 5967db96d56Sopenharmony_ci 5977db96d56Sopenharmony_ci if os.environ.get("PYTHONSTRICTEXTENSIONBUILD") and ( 5987db96d56Sopenharmony_ci self.failed or self.failed_on_import or self.missing 5997db96d56Sopenharmony_ci ): 6007db96d56Sopenharmony_ci raise RuntimeError("Failed to build some stdlib modules") 6017db96d56Sopenharmony_ci 6027db96d56Sopenharmony_ci def build_extension(self, ext): 6037db96d56Sopenharmony_ci 6047db96d56Sopenharmony_ci if ext.name == '_ctypes': 6057db96d56Sopenharmony_ci if not self.configure_ctypes(ext): 6067db96d56Sopenharmony_ci self.failed.append(ext.name) 6077db96d56Sopenharmony_ci return 6087db96d56Sopenharmony_ci 6097db96d56Sopenharmony_ci try: 6107db96d56Sopenharmony_ci build_ext.build_extension(self, ext) 6117db96d56Sopenharmony_ci except (CCompilerError, DistutilsError) as why: 6127db96d56Sopenharmony_ci self.announce('WARNING: building of extension "%s" failed: %s' % 6137db96d56Sopenharmony_ci (ext.name, why)) 6147db96d56Sopenharmony_ci self.failed.append(ext.name) 6157db96d56Sopenharmony_ci return 6167db96d56Sopenharmony_ci 6177db96d56Sopenharmony_ci def check_extension_import(self, ext): 6187db96d56Sopenharmony_ci # Don't try to import an extension that has failed to compile 6197db96d56Sopenharmony_ci if ext.name in self.failed: 6207db96d56Sopenharmony_ci self.announce( 6217db96d56Sopenharmony_ci 'WARNING: skipping import check for failed build "%s"' % 6227db96d56Sopenharmony_ci ext.name, level=1) 6237db96d56Sopenharmony_ci return 6247db96d56Sopenharmony_ci 6257db96d56Sopenharmony_ci # Workaround for Mac OS X: The Carbon-based modules cannot be 6267db96d56Sopenharmony_ci # reliably imported into a command-line Python 6277db96d56Sopenharmony_ci if 'Carbon' in ext.extra_link_args: 6287db96d56Sopenharmony_ci self.announce( 6297db96d56Sopenharmony_ci 'WARNING: skipping import check for Carbon-based "%s"' % 6307db96d56Sopenharmony_ci ext.name) 6317db96d56Sopenharmony_ci return 6327db96d56Sopenharmony_ci 6337db96d56Sopenharmony_ci if MACOS and ( 6347db96d56Sopenharmony_ci sys.maxsize > 2**32 and '-arch' in ext.extra_link_args): 6357db96d56Sopenharmony_ci # Don't bother doing an import check when an extension was 6367db96d56Sopenharmony_ci # build with an explicit '-arch' flag on OSX. That's currently 6377db96d56Sopenharmony_ci # only used to build 32-bit only extensions in a 4-way 6387db96d56Sopenharmony_ci # universal build and loading 32-bit code into a 64-bit 6397db96d56Sopenharmony_ci # process will fail. 6407db96d56Sopenharmony_ci self.announce( 6417db96d56Sopenharmony_ci 'WARNING: skipping import check for "%s"' % 6427db96d56Sopenharmony_ci ext.name) 6437db96d56Sopenharmony_ci return 6447db96d56Sopenharmony_ci 6457db96d56Sopenharmony_ci # Workaround for Cygwin: Cygwin currently has fork issues when many 6467db96d56Sopenharmony_ci # modules have been imported 6477db96d56Sopenharmony_ci if CYGWIN: 6487db96d56Sopenharmony_ci self.announce('WARNING: skipping import check for Cygwin-based "%s"' 6497db96d56Sopenharmony_ci % ext.name) 6507db96d56Sopenharmony_ci return 6517db96d56Sopenharmony_ci ext_filename = os.path.join( 6527db96d56Sopenharmony_ci self.build_lib, 6537db96d56Sopenharmony_ci self.get_ext_filename(self.get_ext_fullname(ext.name))) 6547db96d56Sopenharmony_ci 6557db96d56Sopenharmony_ci # If the build directory didn't exist when setup.py was 6567db96d56Sopenharmony_ci # started, sys.path_importer_cache has a negative result 6577db96d56Sopenharmony_ci # cached. Clear that cache before trying to import. 6587db96d56Sopenharmony_ci sys.path_importer_cache.clear() 6597db96d56Sopenharmony_ci 6607db96d56Sopenharmony_ci # Don't try to load extensions for cross builds 6617db96d56Sopenharmony_ci if CROSS_COMPILING: 6627db96d56Sopenharmony_ci return 6637db96d56Sopenharmony_ci 6647db96d56Sopenharmony_ci loader = importlib.machinery.ExtensionFileLoader(ext.name, ext_filename) 6657db96d56Sopenharmony_ci spec = importlib.util.spec_from_file_location(ext.name, ext_filename, 6667db96d56Sopenharmony_ci loader=loader) 6677db96d56Sopenharmony_ci try: 6687db96d56Sopenharmony_ci importlib._bootstrap._load(spec) 6697db96d56Sopenharmony_ci except ImportError as why: 6707db96d56Sopenharmony_ci self.failed_on_import.append(ext.name) 6717db96d56Sopenharmony_ci self.announce('*** WARNING: renaming "%s" since importing it' 6727db96d56Sopenharmony_ci ' failed: %s' % (ext.name, why), level=3) 6737db96d56Sopenharmony_ci assert not self.inplace 6747db96d56Sopenharmony_ci basename, tail = os.path.splitext(ext_filename) 6757db96d56Sopenharmony_ci newname = basename + "_failed" + tail 6767db96d56Sopenharmony_ci if os.path.exists(newname): 6777db96d56Sopenharmony_ci os.remove(newname) 6787db96d56Sopenharmony_ci os.rename(ext_filename, newname) 6797db96d56Sopenharmony_ci 6807db96d56Sopenharmony_ci except: 6817db96d56Sopenharmony_ci exc_type, why, tb = sys.exc_info() 6827db96d56Sopenharmony_ci self.announce('*** WARNING: importing extension "%s" ' 6837db96d56Sopenharmony_ci 'failed with %s: %s' % (ext.name, exc_type, why), 6847db96d56Sopenharmony_ci level=3) 6857db96d56Sopenharmony_ci self.failed.append(ext.name) 6867db96d56Sopenharmony_ci 6877db96d56Sopenharmony_ci def add_multiarch_paths(self): 6887db96d56Sopenharmony_ci # Debian/Ubuntu multiarch support. 6897db96d56Sopenharmony_ci # https://wiki.ubuntu.com/MultiarchSpec 6907db96d56Sopenharmony_ci tmpfile = os.path.join(self.build_temp, 'multiarch') 6917db96d56Sopenharmony_ci if not os.path.exists(self.build_temp): 6927db96d56Sopenharmony_ci os.makedirs(self.build_temp) 6937db96d56Sopenharmony_ci ret = run_command( 6947db96d56Sopenharmony_ci '%s -print-multiarch > %s 2> /dev/null' % (CC, tmpfile)) 6957db96d56Sopenharmony_ci multiarch_path_component = '' 6967db96d56Sopenharmony_ci try: 6977db96d56Sopenharmony_ci if ret == 0: 6987db96d56Sopenharmony_ci with open(tmpfile) as fp: 6997db96d56Sopenharmony_ci multiarch_path_component = fp.readline().strip() 7007db96d56Sopenharmony_ci finally: 7017db96d56Sopenharmony_ci os.unlink(tmpfile) 7027db96d56Sopenharmony_ci 7037db96d56Sopenharmony_ci if multiarch_path_component != '': 7047db96d56Sopenharmony_ci add_dir_to_list(self.compiler.library_dirs, 7057db96d56Sopenharmony_ci '/usr/lib/' + multiarch_path_component) 7067db96d56Sopenharmony_ci add_dir_to_list(self.compiler.include_dirs, 7077db96d56Sopenharmony_ci '/usr/include/' + multiarch_path_component) 7087db96d56Sopenharmony_ci return 7097db96d56Sopenharmony_ci 7107db96d56Sopenharmony_ci if not find_executable('dpkg-architecture'): 7117db96d56Sopenharmony_ci return 7127db96d56Sopenharmony_ci opt = '' 7137db96d56Sopenharmony_ci if CROSS_COMPILING: 7147db96d56Sopenharmony_ci opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE') 7157db96d56Sopenharmony_ci tmpfile = os.path.join(self.build_temp, 'multiarch') 7167db96d56Sopenharmony_ci if not os.path.exists(self.build_temp): 7177db96d56Sopenharmony_ci os.makedirs(self.build_temp) 7187db96d56Sopenharmony_ci ret = run_command( 7197db96d56Sopenharmony_ci 'dpkg-architecture %s -qDEB_HOST_MULTIARCH > %s 2> /dev/null' % 7207db96d56Sopenharmony_ci (opt, tmpfile)) 7217db96d56Sopenharmony_ci try: 7227db96d56Sopenharmony_ci if ret == 0: 7237db96d56Sopenharmony_ci with open(tmpfile) as fp: 7247db96d56Sopenharmony_ci multiarch_path_component = fp.readline().strip() 7257db96d56Sopenharmony_ci add_dir_to_list(self.compiler.library_dirs, 7267db96d56Sopenharmony_ci '/usr/lib/' + multiarch_path_component) 7277db96d56Sopenharmony_ci add_dir_to_list(self.compiler.include_dirs, 7287db96d56Sopenharmony_ci '/usr/include/' + multiarch_path_component) 7297db96d56Sopenharmony_ci finally: 7307db96d56Sopenharmony_ci os.unlink(tmpfile) 7317db96d56Sopenharmony_ci 7327db96d56Sopenharmony_ci def add_wrcc_search_dirs(self): 7337db96d56Sopenharmony_ci # add library search path by wr-cc, the compiler wrapper 7347db96d56Sopenharmony_ci 7357db96d56Sopenharmony_ci def convert_mixed_path(path): 7367db96d56Sopenharmony_ci # convert path like C:\folder1\folder2/folder3/folder4 7377db96d56Sopenharmony_ci # to msys style /c/folder1/folder2/folder3/folder4 7387db96d56Sopenharmony_ci drive = path[0].lower() 7397db96d56Sopenharmony_ci left = path[2:].replace("\\", "/") 7407db96d56Sopenharmony_ci return "/" + drive + left 7417db96d56Sopenharmony_ci 7427db96d56Sopenharmony_ci def add_search_path(line): 7437db96d56Sopenharmony_ci # On Windows building machine, VxWorks does 7447db96d56Sopenharmony_ci # cross builds under msys2 environment. 7457db96d56Sopenharmony_ci pathsep = (";" if sys.platform == "msys" else ":") 7467db96d56Sopenharmony_ci for d in line.strip().split("=")[1].split(pathsep): 7477db96d56Sopenharmony_ci d = d.strip() 7487db96d56Sopenharmony_ci if sys.platform == "msys": 7497db96d56Sopenharmony_ci # On Windows building machine, compiler 7507db96d56Sopenharmony_ci # returns mixed style path like: 7517db96d56Sopenharmony_ci # C:\folder1\folder2/folder3/folder4 7527db96d56Sopenharmony_ci d = convert_mixed_path(d) 7537db96d56Sopenharmony_ci d = os.path.normpath(d) 7547db96d56Sopenharmony_ci add_dir_to_list(self.compiler.library_dirs, d) 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_ci tmpfile = os.path.join(self.build_temp, 'wrccpaths') 7577db96d56Sopenharmony_ci os.makedirs(self.build_temp, exist_ok=True) 7587db96d56Sopenharmony_ci try: 7597db96d56Sopenharmony_ci ret = run_command('%s --print-search-dirs >%s' % (CC, tmpfile)) 7607db96d56Sopenharmony_ci if ret: 7617db96d56Sopenharmony_ci return 7627db96d56Sopenharmony_ci with open(tmpfile) as fp: 7637db96d56Sopenharmony_ci # Parse paths in libraries line. The line is like: 7647db96d56Sopenharmony_ci # On Linux, "libraries: = path1:path2:path3" 7657db96d56Sopenharmony_ci # On Windows, "libraries: = path1;path2;path3" 7667db96d56Sopenharmony_ci for line in fp: 7677db96d56Sopenharmony_ci if not line.startswith("libraries"): 7687db96d56Sopenharmony_ci continue 7697db96d56Sopenharmony_ci add_search_path(line) 7707db96d56Sopenharmony_ci finally: 7717db96d56Sopenharmony_ci try: 7727db96d56Sopenharmony_ci os.unlink(tmpfile) 7737db96d56Sopenharmony_ci except OSError: 7747db96d56Sopenharmony_ci pass 7757db96d56Sopenharmony_ci 7767db96d56Sopenharmony_ci def add_cross_compiling_paths(self): 7777db96d56Sopenharmony_ci tmpfile = os.path.join(self.build_temp, 'ccpaths') 7787db96d56Sopenharmony_ci if not os.path.exists(self.build_temp): 7797db96d56Sopenharmony_ci os.makedirs(self.build_temp) 7807db96d56Sopenharmony_ci # bpo-38472: With a German locale, GCC returns "gcc-Version 9.1.0 7817db96d56Sopenharmony_ci # (GCC)", whereas it returns "gcc version 9.1.0" with the C locale. 7827db96d56Sopenharmony_ci ret = run_command('LC_ALL=C %s -E -v - </dev/null 2>%s 1>/dev/null' % (CC, tmpfile)) 7837db96d56Sopenharmony_ci is_gcc = False 7847db96d56Sopenharmony_ci is_clang = False 7857db96d56Sopenharmony_ci in_incdirs = False 7867db96d56Sopenharmony_ci try: 7877db96d56Sopenharmony_ci if ret == 0: 7887db96d56Sopenharmony_ci with open(tmpfile) as fp: 7897db96d56Sopenharmony_ci for line in fp.readlines(): 7907db96d56Sopenharmony_ci if line.startswith("gcc version"): 7917db96d56Sopenharmony_ci is_gcc = True 7927db96d56Sopenharmony_ci elif line.startswith("clang version"): 7937db96d56Sopenharmony_ci is_clang = True 7947db96d56Sopenharmony_ci elif line.startswith("#include <...>"): 7957db96d56Sopenharmony_ci in_incdirs = True 7967db96d56Sopenharmony_ci elif line.startswith("End of search list"): 7977db96d56Sopenharmony_ci in_incdirs = False 7987db96d56Sopenharmony_ci elif (is_gcc or is_clang) and line.startswith("LIBRARY_PATH"): 7997db96d56Sopenharmony_ci for d in line.strip().split("=")[1].split(":"): 8007db96d56Sopenharmony_ci d = os.path.normpath(d) 8017db96d56Sopenharmony_ci if '/gcc/' not in d: 8027db96d56Sopenharmony_ci add_dir_to_list(self.compiler.library_dirs, 8037db96d56Sopenharmony_ci d) 8047db96d56Sopenharmony_ci elif (is_gcc or is_clang) and in_incdirs and '/gcc/' not in line and '/clang/' not in line: 8057db96d56Sopenharmony_ci add_dir_to_list(self.compiler.include_dirs, 8067db96d56Sopenharmony_ci line.strip()) 8077db96d56Sopenharmony_ci finally: 8087db96d56Sopenharmony_ci os.unlink(tmpfile) 8097db96d56Sopenharmony_ci 8107db96d56Sopenharmony_ci if VXWORKS: 8117db96d56Sopenharmony_ci self.add_wrcc_search_dirs() 8127db96d56Sopenharmony_ci 8137db96d56Sopenharmony_ci def add_ldflags_cppflags(self): 8147db96d56Sopenharmony_ci # Add paths specified in the environment variables LDFLAGS and 8157db96d56Sopenharmony_ci # CPPFLAGS for header and library files. 8167db96d56Sopenharmony_ci # We must get the values from the Makefile and not the environment 8177db96d56Sopenharmony_ci # directly since an inconsistently reproducible issue comes up where 8187db96d56Sopenharmony_ci # the environment variable is not set even though the value were passed 8197db96d56Sopenharmony_ci # into configure and stored in the Makefile (issue found on OS X 10.3). 8207db96d56Sopenharmony_ci for env_var, arg_name, dir_list in ( 8217db96d56Sopenharmony_ci ('LDFLAGS', '-R', self.compiler.runtime_library_dirs), 8227db96d56Sopenharmony_ci ('LDFLAGS', '-L', self.compiler.library_dirs), 8237db96d56Sopenharmony_ci ('CPPFLAGS', '-I', self.compiler.include_dirs)): 8247db96d56Sopenharmony_ci env_val = sysconfig.get_config_var(env_var) 8257db96d56Sopenharmony_ci if env_val: 8267db96d56Sopenharmony_ci parser = argparse.ArgumentParser() 8277db96d56Sopenharmony_ci parser.add_argument(arg_name, dest="dirs", action="append") 8287db96d56Sopenharmony_ci 8297db96d56Sopenharmony_ci # To prevent argparse from raising an exception about any 8307db96d56Sopenharmony_ci # options in env_val that it mistakes for known option, we 8317db96d56Sopenharmony_ci # strip out all double dashes and any dashes followed by a 8327db96d56Sopenharmony_ci # character that is not for the option we are dealing with. 8337db96d56Sopenharmony_ci # 8347db96d56Sopenharmony_ci # Please note that order of the regex is important! We must 8357db96d56Sopenharmony_ci # strip out double-dashes first so that we don't end up with 8367db96d56Sopenharmony_ci # substituting "--Long" to "-Long" and thus lead to "ong" being 8377db96d56Sopenharmony_ci # used for a library directory. 8387db96d56Sopenharmony_ci env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1], 8397db96d56Sopenharmony_ci ' ', env_val) 8407db96d56Sopenharmony_ci options, _ = parser.parse_known_args(env_val.split()) 8417db96d56Sopenharmony_ci if options.dirs: 8427db96d56Sopenharmony_ci for directory in reversed(options.dirs): 8437db96d56Sopenharmony_ci add_dir_to_list(dir_list, directory) 8447db96d56Sopenharmony_ci 8457db96d56Sopenharmony_ci def configure_compiler(self): 8467db96d56Sopenharmony_ci # Ensure that /usr/local is always used, but the local build 8477db96d56Sopenharmony_ci # directories (i.e. '.' and 'Include') must be first. See issue 8487db96d56Sopenharmony_ci # 10520. 8497db96d56Sopenharmony_ci if not CROSS_COMPILING: 8507db96d56Sopenharmony_ci add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') 8517db96d56Sopenharmony_ci add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') 8527db96d56Sopenharmony_ci # only change this for cross builds for 3.3, issues on Mageia 8537db96d56Sopenharmony_ci if CROSS_COMPILING: 8547db96d56Sopenharmony_ci self.add_cross_compiling_paths() 8557db96d56Sopenharmony_ci self.add_multiarch_paths() 8567db96d56Sopenharmony_ci self.add_ldflags_cppflags() 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_ci def init_inc_lib_dirs(self): 8597db96d56Sopenharmony_ci if (not CROSS_COMPILING and 8607db96d56Sopenharmony_ci os.path.normpath(sys.base_prefix) != '/usr' and 8617db96d56Sopenharmony_ci not sysconfig.get_config_var('PYTHONFRAMEWORK')): 8627db96d56Sopenharmony_ci # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework 8637db96d56Sopenharmony_ci # (PYTHONFRAMEWORK is set) to avoid # linking problems when 8647db96d56Sopenharmony_ci # building a framework with different architectures than 8657db96d56Sopenharmony_ci # the one that is currently installed (issue #7473) 8667db96d56Sopenharmony_ci add_dir_to_list(self.compiler.library_dirs, 8677db96d56Sopenharmony_ci sysconfig.get_config_var("LIBDIR")) 8687db96d56Sopenharmony_ci add_dir_to_list(self.compiler.include_dirs, 8697db96d56Sopenharmony_ci sysconfig.get_config_var("INCLUDEDIR")) 8707db96d56Sopenharmony_ci 8717db96d56Sopenharmony_ci system_lib_dirs = ['/lib64', '/usr/lib64', '/lib', '/usr/lib'] 8727db96d56Sopenharmony_ci system_include_dirs = ['/usr/include'] 8737db96d56Sopenharmony_ci # lib_dirs and inc_dirs are used to search for files; 8747db96d56Sopenharmony_ci # if a file is found in one of those directories, it can 8757db96d56Sopenharmony_ci # be assumed that no additional -I,-L directives are needed. 8767db96d56Sopenharmony_ci if not CROSS_COMPILING: 8777db96d56Sopenharmony_ci self.lib_dirs = self.compiler.library_dirs + system_lib_dirs 8787db96d56Sopenharmony_ci self.inc_dirs = self.compiler.include_dirs + system_include_dirs 8797db96d56Sopenharmony_ci else: 8807db96d56Sopenharmony_ci # Add the sysroot paths. 'sysroot' is a compiler option used to 8817db96d56Sopenharmony_ci # set the logical path of the standard system headers and 8827db96d56Sopenharmony_ci # libraries. 8837db96d56Sopenharmony_ci self.lib_dirs = (self.compiler.library_dirs + 8847db96d56Sopenharmony_ci sysroot_paths(('LDFLAGS', 'CC'), system_lib_dirs)) 8857db96d56Sopenharmony_ci self.inc_dirs = (self.compiler.include_dirs + 8867db96d56Sopenharmony_ci sysroot_paths(('CPPFLAGS', 'CFLAGS', 'CC'), 8877db96d56Sopenharmony_ci system_include_dirs)) 8887db96d56Sopenharmony_ci 8897db96d56Sopenharmony_ci config_h = sysconfig.get_config_h_filename() 8907db96d56Sopenharmony_ci with open(config_h) as file: 8917db96d56Sopenharmony_ci self.config_h_vars = sysconfig.parse_config_h(file) 8927db96d56Sopenharmony_ci 8937db96d56Sopenharmony_ci # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb) 8947db96d56Sopenharmony_ci if HOST_PLATFORM in ['osf1', 'unixware7', 'openunix8']: 8957db96d56Sopenharmony_ci self.lib_dirs += ['/usr/ccs/lib'] 8967db96d56Sopenharmony_ci 8977db96d56Sopenharmony_ci # HP-UX11iv3 keeps files in lib/hpux folders. 8987db96d56Sopenharmony_ci if HOST_PLATFORM == 'hp-ux11': 8997db96d56Sopenharmony_ci self.lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32'] 9007db96d56Sopenharmony_ci 9017db96d56Sopenharmony_ci if MACOS: 9027db96d56Sopenharmony_ci # This should work on any unixy platform ;-) 9037db96d56Sopenharmony_ci # If the user has bothered specifying additional -I and -L flags 9047db96d56Sopenharmony_ci # in OPT and LDFLAGS we might as well use them here. 9057db96d56Sopenharmony_ci # 9067db96d56Sopenharmony_ci # NOTE: using shlex.split would technically be more correct, but 9077db96d56Sopenharmony_ci # also gives a bootstrap problem. Let's hope nobody uses 9087db96d56Sopenharmony_ci # directories with whitespace in the name to store libraries. 9097db96d56Sopenharmony_ci cflags, ldflags = sysconfig.get_config_vars( 9107db96d56Sopenharmony_ci 'CFLAGS', 'LDFLAGS') 9117db96d56Sopenharmony_ci for item in cflags.split(): 9127db96d56Sopenharmony_ci if item.startswith('-I'): 9137db96d56Sopenharmony_ci self.inc_dirs.append(item[2:]) 9147db96d56Sopenharmony_ci 9157db96d56Sopenharmony_ci for item in ldflags.split(): 9167db96d56Sopenharmony_ci if item.startswith('-L'): 9177db96d56Sopenharmony_ci self.lib_dirs.append(item[2:]) 9187db96d56Sopenharmony_ci 9197db96d56Sopenharmony_ci def detect_simple_extensions(self): 9207db96d56Sopenharmony_ci # 9217db96d56Sopenharmony_ci # The following modules are all pretty straightforward, and compile 9227db96d56Sopenharmony_ci # on pretty much any POSIXish platform. 9237db96d56Sopenharmony_ci # 9247db96d56Sopenharmony_ci 9257db96d56Sopenharmony_ci # array objects 9267db96d56Sopenharmony_ci self.addext(Extension('array', ['arraymodule.c'])) 9277db96d56Sopenharmony_ci 9287db96d56Sopenharmony_ci # Context Variables 9297db96d56Sopenharmony_ci self.addext(Extension('_contextvars', ['_contextvarsmodule.c'])) 9307db96d56Sopenharmony_ci 9317db96d56Sopenharmony_ci # math library functions, e.g. sin() 9327db96d56Sopenharmony_ci self.addext(Extension('math', ['mathmodule.c'])) 9337db96d56Sopenharmony_ci 9347db96d56Sopenharmony_ci # complex math library functions 9357db96d56Sopenharmony_ci self.addext(Extension('cmath', ['cmathmodule.c'])) 9367db96d56Sopenharmony_ci 9377db96d56Sopenharmony_ci # libm is needed by delta_new() that uses round() and by accum() that 9387db96d56Sopenharmony_ci # uses modf(). 9397db96d56Sopenharmony_ci self.addext(Extension('_datetime', ['_datetimemodule.c'])) 9407db96d56Sopenharmony_ci self.addext(Extension('_zoneinfo', ['_zoneinfo.c'])) 9417db96d56Sopenharmony_ci # random number generator implemented in C 9427db96d56Sopenharmony_ci self.addext(Extension("_random", ["_randommodule.c"])) 9437db96d56Sopenharmony_ci self.addext(Extension("_bisect", ["_bisectmodule.c"])) 9447db96d56Sopenharmony_ci self.addext(Extension("_heapq", ["_heapqmodule.c"])) 9457db96d56Sopenharmony_ci # C-optimized pickle replacement 9467db96d56Sopenharmony_ci self.addext(Extension("_pickle", ["_pickle.c"])) 9477db96d56Sopenharmony_ci # _json speedups 9487db96d56Sopenharmony_ci self.addext(Extension("_json", ["_json.c"])) 9497db96d56Sopenharmony_ci 9507db96d56Sopenharmony_ci # profiler (_lsprof is for cProfile.py) 9517db96d56Sopenharmony_ci self.addext(Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c'])) 9527db96d56Sopenharmony_ci # static Unicode character database 9537db96d56Sopenharmony_ci self.addext(Extension('unicodedata', ['unicodedata.c'])) 9547db96d56Sopenharmony_ci self.addext(Extension('_opcode', ['_opcode.c'])) 9557db96d56Sopenharmony_ci 9567db96d56Sopenharmony_ci # asyncio speedups 9577db96d56Sopenharmony_ci self.addext(Extension("_asyncio", ["_asynciomodule.c"])) 9587db96d56Sopenharmony_ci 9597db96d56Sopenharmony_ci self.addext(Extension("_queue", ["_queuemodule.c"])) 9607db96d56Sopenharmony_ci self.addext(Extension("_statistics", ["_statisticsmodule.c"])) 9617db96d56Sopenharmony_ci self.addext(Extension("_struct", ["_struct.c"])) 9627db96d56Sopenharmony_ci self.addext(Extension("_typing", ["_typingmodule.c"])) 9637db96d56Sopenharmony_ci 9647db96d56Sopenharmony_ci # Modules with some UNIX dependencies -- on by default: 9657db96d56Sopenharmony_ci # (If you have a really backward UNIX, select and socket may not be 9667db96d56Sopenharmony_ci # supported...) 9677db96d56Sopenharmony_ci 9687db96d56Sopenharmony_ci # fcntl(2) and ioctl(2) 9697db96d56Sopenharmony_ci self.addext(Extension('fcntl', ['fcntlmodule.c'])) 9707db96d56Sopenharmony_ci # grp(3) 9717db96d56Sopenharmony_ci self.addext(Extension('grp', ['grpmodule.c'])) 9727db96d56Sopenharmony_ci 9737db96d56Sopenharmony_ci self.addext(Extension('_socket', ['socketmodule.c'])) 9747db96d56Sopenharmony_ci self.addext(Extension('spwd', ['spwdmodule.c'])) 9757db96d56Sopenharmony_ci 9767db96d56Sopenharmony_ci # select(2); not on ancient System V 9777db96d56Sopenharmony_ci self.addext(Extension('select', ['selectmodule.c'])) 9787db96d56Sopenharmony_ci 9797db96d56Sopenharmony_ci # Memory-mapped files (also works on Win32). 9807db96d56Sopenharmony_ci self.addext(Extension('mmap', ['mmapmodule.c'])) 9817db96d56Sopenharmony_ci 9827db96d56Sopenharmony_ci # Lance Ellinghaus's syslog module 9837db96d56Sopenharmony_ci # syslog daemon interface 9847db96d56Sopenharmony_ci self.addext(Extension('syslog', ['syslogmodule.c'])) 9857db96d56Sopenharmony_ci 9867db96d56Sopenharmony_ci # Python interface to subinterpreter C-API. 9877db96d56Sopenharmony_ci self.addext(Extension('_xxsubinterpreters', ['_xxsubinterpretersmodule.c'])) 9887db96d56Sopenharmony_ci 9897db96d56Sopenharmony_ci # 9907db96d56Sopenharmony_ci # Here ends the simple stuff. From here on, modules need certain 9917db96d56Sopenharmony_ci # libraries, are platform-specific, or present other surprises. 9927db96d56Sopenharmony_ci # 9937db96d56Sopenharmony_ci 9947db96d56Sopenharmony_ci # Multimedia modules 9957db96d56Sopenharmony_ci # These don't work for 64-bit platforms!!! 9967db96d56Sopenharmony_ci # These represent audio samples or images as strings: 9977db96d56Sopenharmony_ci # 9987db96d56Sopenharmony_ci # Operations on audio samples 9997db96d56Sopenharmony_ci # According to #993173, this one should actually work fine on 10007db96d56Sopenharmony_ci # 64-bit platforms. 10017db96d56Sopenharmony_ci # 10027db96d56Sopenharmony_ci # audioop needs libm for floor() in multiple functions. 10037db96d56Sopenharmony_ci self.addext(Extension('audioop', ['audioop.c'])) 10047db96d56Sopenharmony_ci 10057db96d56Sopenharmony_ci # CSV files 10067db96d56Sopenharmony_ci self.addext(Extension('_csv', ['_csv.c'])) 10077db96d56Sopenharmony_ci 10087db96d56Sopenharmony_ci # POSIX subprocess module helper. 10097db96d56Sopenharmony_ci self.addext(Extension('_posixsubprocess', ['_posixsubprocess.c'])) 10107db96d56Sopenharmony_ci 10117db96d56Sopenharmony_ci def detect_test_extensions(self): 10127db96d56Sopenharmony_ci # Python C API test module 10137db96d56Sopenharmony_ci self.addext(Extension('_testcapi', ['_testcapimodule.c'])) 10147db96d56Sopenharmony_ci 10157db96d56Sopenharmony_ci # Python Argument Clinc functional test module 10167db96d56Sopenharmony_ci self.addext(Extension('_testclinic', ['_testclinic.c'])) 10177db96d56Sopenharmony_ci 10187db96d56Sopenharmony_ci # Python Internal C API test module 10197db96d56Sopenharmony_ci self.addext(Extension('_testinternalcapi', ['_testinternalcapi.c'])) 10207db96d56Sopenharmony_ci 10217db96d56Sopenharmony_ci # Python PEP-3118 (buffer protocol) test module 10227db96d56Sopenharmony_ci self.addext(Extension('_testbuffer', ['_testbuffer.c'])) 10237db96d56Sopenharmony_ci 10247db96d56Sopenharmony_ci # Test loading multiple modules from one compiled file (https://bugs.python.org/issue16421) 10257db96d56Sopenharmony_ci self.addext(Extension('_testimportmultiple', ['_testimportmultiple.c'])) 10267db96d56Sopenharmony_ci 10277db96d56Sopenharmony_ci # Test multi-phase extension module init (PEP 489) 10287db96d56Sopenharmony_ci self.addext(Extension('_testmultiphase', ['_testmultiphase.c'])) 10297db96d56Sopenharmony_ci 10307db96d56Sopenharmony_ci # Fuzz tests. 10317db96d56Sopenharmony_ci self.addext(Extension( 10327db96d56Sopenharmony_ci '_xxtestfuzz', 10337db96d56Sopenharmony_ci ['_xxtestfuzz/_xxtestfuzz.c', '_xxtestfuzz/fuzzer.c'] 10347db96d56Sopenharmony_ci )) 10357db96d56Sopenharmony_ci 10367db96d56Sopenharmony_ci def detect_readline_curses(self): 10377db96d56Sopenharmony_ci # readline 10387db96d56Sopenharmony_ci readline_termcap_library = "" 10397db96d56Sopenharmony_ci curses_library = "" 10407db96d56Sopenharmony_ci # Cannot use os.popen here in py3k. 10417db96d56Sopenharmony_ci tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') 10427db96d56Sopenharmony_ci if not os.path.exists(self.build_temp): 10437db96d56Sopenharmony_ci os.makedirs(self.build_temp) 10447db96d56Sopenharmony_ci # Determine if readline is already linked against curses or tinfo. 10457db96d56Sopenharmony_ci if sysconfig.get_config_var('HAVE_LIBREADLINE'): 10467db96d56Sopenharmony_ci if sysconfig.get_config_var('WITH_EDITLINE'): 10477db96d56Sopenharmony_ci readline_lib = 'edit' 10487db96d56Sopenharmony_ci else: 10497db96d56Sopenharmony_ci readline_lib = 'readline' 10507db96d56Sopenharmony_ci do_readline = self.compiler.find_library_file(self.lib_dirs, 10517db96d56Sopenharmony_ci readline_lib) 10527db96d56Sopenharmony_ci if CROSS_COMPILING: 10537db96d56Sopenharmony_ci ret = run_command("%s -d %s | grep '(NEEDED)' > %s" 10547db96d56Sopenharmony_ci % (sysconfig.get_config_var('READELF'), 10557db96d56Sopenharmony_ci do_readline, tmpfile)) 10567db96d56Sopenharmony_ci elif find_executable('ldd'): 10577db96d56Sopenharmony_ci ret = run_command("ldd %s > %s" % (do_readline, tmpfile)) 10587db96d56Sopenharmony_ci else: 10597db96d56Sopenharmony_ci ret = 1 10607db96d56Sopenharmony_ci if ret == 0: 10617db96d56Sopenharmony_ci with open(tmpfile) as fp: 10627db96d56Sopenharmony_ci for ln in fp: 10637db96d56Sopenharmony_ci if 'curses' in ln: 10647db96d56Sopenharmony_ci readline_termcap_library = re.sub( 10657db96d56Sopenharmony_ci r'.*lib(n?cursesw?)\.so.*', r'\1', ln 10667db96d56Sopenharmony_ci ).rstrip() 10677db96d56Sopenharmony_ci break 10687db96d56Sopenharmony_ci # termcap interface split out from ncurses 10697db96d56Sopenharmony_ci if 'tinfo' in ln: 10707db96d56Sopenharmony_ci readline_termcap_library = 'tinfo' 10717db96d56Sopenharmony_ci break 10727db96d56Sopenharmony_ci if os.path.exists(tmpfile): 10737db96d56Sopenharmony_ci os.unlink(tmpfile) 10747db96d56Sopenharmony_ci else: 10757db96d56Sopenharmony_ci do_readline = False 10767db96d56Sopenharmony_ci # Issue 7384: If readline is already linked against curses, 10777db96d56Sopenharmony_ci # use the same library for the readline and curses modules. 10787db96d56Sopenharmony_ci if 'curses' in readline_termcap_library: 10797db96d56Sopenharmony_ci curses_library = readline_termcap_library 10807db96d56Sopenharmony_ci elif self.compiler.find_library_file(self.lib_dirs, 'ncursesw'): 10817db96d56Sopenharmony_ci curses_library = 'ncursesw' 10827db96d56Sopenharmony_ci # Issue 36210: OSS provided ncurses does not link on AIX 10837db96d56Sopenharmony_ci # Use IBM supplied 'curses' for successful build of _curses 10847db96d56Sopenharmony_ci elif AIX and self.compiler.find_library_file(self.lib_dirs, 'curses'): 10857db96d56Sopenharmony_ci curses_library = 'curses' 10867db96d56Sopenharmony_ci elif self.compiler.find_library_file(self.lib_dirs, 'ncurses'): 10877db96d56Sopenharmony_ci curses_library = 'ncurses' 10887db96d56Sopenharmony_ci elif self.compiler.find_library_file(self.lib_dirs, 'curses'): 10897db96d56Sopenharmony_ci curses_library = 'curses' 10907db96d56Sopenharmony_ci 10917db96d56Sopenharmony_ci if MACOS: 10927db96d56Sopenharmony_ci os_release = int(os.uname()[2].split('.')[0]) 10937db96d56Sopenharmony_ci dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') 10947db96d56Sopenharmony_ci if (dep_target and 10957db96d56Sopenharmony_ci (tuple(int(n) for n in dep_target.split('.')[0:2]) 10967db96d56Sopenharmony_ci < (10, 5) ) ): 10977db96d56Sopenharmony_ci os_release = 8 10987db96d56Sopenharmony_ci if os_release < 9: 10997db96d56Sopenharmony_ci # MacOSX 10.4 has a broken readline. Don't try to build 11007db96d56Sopenharmony_ci # the readline module unless the user has installed a fixed 11017db96d56Sopenharmony_ci # readline package 11027db96d56Sopenharmony_ci if find_file('readline/rlconf.h', self.inc_dirs, []) is None: 11037db96d56Sopenharmony_ci do_readline = False 11047db96d56Sopenharmony_ci if do_readline: 11057db96d56Sopenharmony_ci readline_libs = [readline_lib] 11067db96d56Sopenharmony_ci if readline_termcap_library: 11077db96d56Sopenharmony_ci pass # Issue 7384: Already linked against curses or tinfo. 11087db96d56Sopenharmony_ci elif curses_library: 11097db96d56Sopenharmony_ci readline_libs.append(curses_library) 11107db96d56Sopenharmony_ci elif self.compiler.find_library_file(self.lib_dirs + 11117db96d56Sopenharmony_ci ['/usr/lib/termcap'], 11127db96d56Sopenharmony_ci 'termcap'): 11137db96d56Sopenharmony_ci readline_libs.append('termcap') 11147db96d56Sopenharmony_ci self.add(Extension('readline', ['readline.c'], 11157db96d56Sopenharmony_ci library_dirs=['/usr/lib/termcap'], 11167db96d56Sopenharmony_ci libraries=readline_libs)) 11177db96d56Sopenharmony_ci else: 11187db96d56Sopenharmony_ci self.missing.append('readline') 11197db96d56Sopenharmony_ci 11207db96d56Sopenharmony_ci # Curses support, requiring the System V version of curses, often 11217db96d56Sopenharmony_ci # provided by the ncurses library. 11227db96d56Sopenharmony_ci curses_defines = [] 11237db96d56Sopenharmony_ci curses_includes = [] 11247db96d56Sopenharmony_ci panel_library = 'panel' 11257db96d56Sopenharmony_ci if curses_library == 'ncursesw': 11267db96d56Sopenharmony_ci curses_defines.append(('HAVE_NCURSESW', '1')) 11277db96d56Sopenharmony_ci if not CROSS_COMPILING: 11287db96d56Sopenharmony_ci curses_includes.append('/usr/include/ncursesw') 11297db96d56Sopenharmony_ci # Bug 1464056: If _curses.so links with ncursesw, 11307db96d56Sopenharmony_ci # _curses_panel.so must link with panelw. 11317db96d56Sopenharmony_ci panel_library = 'panelw' 11327db96d56Sopenharmony_ci if MACOS: 11337db96d56Sopenharmony_ci # On OS X, there is no separate /usr/lib/libncursesw nor 11347db96d56Sopenharmony_ci # libpanelw. If we are here, we found a locally-supplied 11357db96d56Sopenharmony_ci # version of libncursesw. There should also be a 11367db96d56Sopenharmony_ci # libpanelw. _XOPEN_SOURCE defines are usually excluded 11377db96d56Sopenharmony_ci # for OS X but we need _XOPEN_SOURCE_EXTENDED here for 11387db96d56Sopenharmony_ci # ncurses wide char support 11397db96d56Sopenharmony_ci curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1')) 11407db96d56Sopenharmony_ci elif MACOS and curses_library == 'ncurses': 11417db96d56Sopenharmony_ci # Building with the system-suppied combined libncurses/libpanel 11427db96d56Sopenharmony_ci curses_defines.append(('HAVE_NCURSESW', '1')) 11437db96d56Sopenharmony_ci curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1')) 11447db96d56Sopenharmony_ci 11457db96d56Sopenharmony_ci curses_enabled = True 11467db96d56Sopenharmony_ci if curses_library.startswith('ncurses'): 11477db96d56Sopenharmony_ci curses_libs = [curses_library] 11487db96d56Sopenharmony_ci self.add(Extension('_curses', ['_cursesmodule.c'], 11497db96d56Sopenharmony_ci include_dirs=curses_includes, 11507db96d56Sopenharmony_ci define_macros=curses_defines, 11517db96d56Sopenharmony_ci libraries=curses_libs)) 11527db96d56Sopenharmony_ci elif curses_library == 'curses' and not MACOS: 11537db96d56Sopenharmony_ci # OSX has an old Berkeley curses, not good enough for 11547db96d56Sopenharmony_ci # the _curses module. 11557db96d56Sopenharmony_ci if (self.compiler.find_library_file(self.lib_dirs, 'terminfo')): 11567db96d56Sopenharmony_ci curses_libs = ['curses', 'terminfo'] 11577db96d56Sopenharmony_ci elif (self.compiler.find_library_file(self.lib_dirs, 'termcap')): 11587db96d56Sopenharmony_ci curses_libs = ['curses', 'termcap'] 11597db96d56Sopenharmony_ci else: 11607db96d56Sopenharmony_ci curses_libs = ['curses'] 11617db96d56Sopenharmony_ci 11627db96d56Sopenharmony_ci self.add(Extension('_curses', ['_cursesmodule.c'], 11637db96d56Sopenharmony_ci define_macros=curses_defines, 11647db96d56Sopenharmony_ci libraries=curses_libs)) 11657db96d56Sopenharmony_ci else: 11667db96d56Sopenharmony_ci curses_enabled = False 11677db96d56Sopenharmony_ci self.missing.append('_curses') 11687db96d56Sopenharmony_ci 11697db96d56Sopenharmony_ci # If the curses module is enabled, check for the panel module 11707db96d56Sopenharmony_ci # _curses_panel needs some form of ncurses 11717db96d56Sopenharmony_ci skip_curses_panel = True if AIX else False 11727db96d56Sopenharmony_ci if (curses_enabled and not skip_curses_panel and 11737db96d56Sopenharmony_ci self.compiler.find_library_file(self.lib_dirs, panel_library)): 11747db96d56Sopenharmony_ci self.add(Extension('_curses_panel', ['_curses_panel.c'], 11757db96d56Sopenharmony_ci include_dirs=curses_includes, 11767db96d56Sopenharmony_ci define_macros=curses_defines, 11777db96d56Sopenharmony_ci libraries=[panel_library, *curses_libs])) 11787db96d56Sopenharmony_ci elif not skip_curses_panel: 11797db96d56Sopenharmony_ci self.missing.append('_curses_panel') 11807db96d56Sopenharmony_ci 11817db96d56Sopenharmony_ci def detect_crypt(self): 11827db96d56Sopenharmony_ci self.addext(Extension('_crypt', ['_cryptmodule.c'])) 11837db96d56Sopenharmony_ci 11847db96d56Sopenharmony_ci def detect_dbm_gdbm(self): 11857db96d56Sopenharmony_ci # Modules that provide persistent dictionary-like semantics. You will 11867db96d56Sopenharmony_ci # probably want to arrange for at least one of them to be available on 11877db96d56Sopenharmony_ci # your machine, though none are defined by default because of library 11887db96d56Sopenharmony_ci # dependencies. The Python module dbm/__init__.py provides an 11897db96d56Sopenharmony_ci # implementation independent wrapper for these; dbm/dumb.py provides 11907db96d56Sopenharmony_ci # similar functionality (but slower of course) implemented in Python. 11917db96d56Sopenharmony_ci 11927db96d56Sopenharmony_ci dbm_setup_debug = False # verbose debug prints from this script? 11937db96d56Sopenharmony_ci dbm_order = ['gdbm'] 11947db96d56Sopenharmony_ci 11957db96d56Sopenharmony_ci # libdb, gdbm and ndbm headers and libraries 11967db96d56Sopenharmony_ci have_ndbm_h = sysconfig.get_config_var("HAVE_NDBM_H") 11977db96d56Sopenharmony_ci have_gdbm_ndbm_h = sysconfig.get_config_var("HAVE_GDBM_NDBM_H") 11987db96d56Sopenharmony_ci have_gdbm_dash_ndbm_h = sysconfig.get_config_var("HAVE_GDBM_DASH_NDBM_H") 11997db96d56Sopenharmony_ci have_libndbm = sysconfig.get_config_var("HAVE_LIBNDBM") 12007db96d56Sopenharmony_ci have_libgdbm_compat = sysconfig.get_config_var("HAVE_LIBGDBM_COMPAT") 12017db96d56Sopenharmony_ci have_libdb = sysconfig.get_config_var("HAVE_LIBDB") 12027db96d56Sopenharmony_ci 12037db96d56Sopenharmony_ci # The standard Unix dbm module: 12047db96d56Sopenharmony_ci if not CYGWIN: 12057db96d56Sopenharmony_ci config_args = [arg.strip("'") 12067db96d56Sopenharmony_ci for arg in sysconfig.get_config_var("CONFIG_ARGS").split()] 12077db96d56Sopenharmony_ci dbm_args = [arg for arg in config_args 12087db96d56Sopenharmony_ci if arg.startswith('--with-dbmliborder=')] 12097db96d56Sopenharmony_ci if dbm_args: 12107db96d56Sopenharmony_ci dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":") 12117db96d56Sopenharmony_ci else: 12127db96d56Sopenharmony_ci dbm_order = "gdbm:ndbm:bdb".split(":") 12137db96d56Sopenharmony_ci dbmext = None 12147db96d56Sopenharmony_ci for cand in dbm_order: 12157db96d56Sopenharmony_ci if cand == "ndbm": 12167db96d56Sopenharmony_ci if have_ndbm_h: 12177db96d56Sopenharmony_ci # Some systems have -lndbm, others have -lgdbm_compat, 12187db96d56Sopenharmony_ci # others don't have either 12197db96d56Sopenharmony_ci if have_libndbm: 12207db96d56Sopenharmony_ci ndbm_libs = ['ndbm'] 12217db96d56Sopenharmony_ci elif have_libgdbm_compat: 12227db96d56Sopenharmony_ci ndbm_libs = ['gdbm_compat'] 12237db96d56Sopenharmony_ci else: 12247db96d56Sopenharmony_ci ndbm_libs = [] 12257db96d56Sopenharmony_ci if dbm_setup_debug: print("building dbm using ndbm") 12267db96d56Sopenharmony_ci dbmext = Extension( 12277db96d56Sopenharmony_ci '_dbm', ['_dbmmodule.c'], 12287db96d56Sopenharmony_ci define_macros=[('USE_NDBM', None)], 12297db96d56Sopenharmony_ci libraries=ndbm_libs 12307db96d56Sopenharmony_ci ) 12317db96d56Sopenharmony_ci break 12327db96d56Sopenharmony_ci elif cand == "gdbm": 12337db96d56Sopenharmony_ci # dbm_open() is provided by libgdbm_compat, which wraps libgdbm 12347db96d56Sopenharmony_ci if have_libgdbm_compat and (have_gdbm_ndbm_h or have_gdbm_dash_ndbm_h): 12357db96d56Sopenharmony_ci if dbm_setup_debug: print("building dbm using gdbm") 12367db96d56Sopenharmony_ci dbmext = Extension( 12377db96d56Sopenharmony_ci '_dbm', ['_dbmmodule.c'], 12387db96d56Sopenharmony_ci define_macros=[('USE_GDBM_COMPAT', None)], 12397db96d56Sopenharmony_ci libraries=['gdbm_compat'] 12407db96d56Sopenharmony_ci ) 12417db96d56Sopenharmony_ci break 12427db96d56Sopenharmony_ci elif cand == "bdb": 12437db96d56Sopenharmony_ci if have_libdb: 12447db96d56Sopenharmony_ci if dbm_setup_debug: print("building dbm using bdb") 12457db96d56Sopenharmony_ci dbmext = Extension( 12467db96d56Sopenharmony_ci '_dbm', ['_dbmmodule.c'], 12477db96d56Sopenharmony_ci define_macros=[('USE_BERKDB', None)], 12487db96d56Sopenharmony_ci libraries=['db'] 12497db96d56Sopenharmony_ci ) 12507db96d56Sopenharmony_ci break 12517db96d56Sopenharmony_ci if dbmext is not None: 12527db96d56Sopenharmony_ci self.add(dbmext) 12537db96d56Sopenharmony_ci else: 12547db96d56Sopenharmony_ci self.missing.append('_dbm') 12557db96d56Sopenharmony_ci 12567db96d56Sopenharmony_ci # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm: 12577db96d56Sopenharmony_ci self.addext(Extension('_gdbm', ['_gdbmmodule.c'])) 12587db96d56Sopenharmony_ci 12597db96d56Sopenharmony_ci def detect_sqlite(self): 12607db96d56Sopenharmony_ci sources = [ 12617db96d56Sopenharmony_ci "_sqlite/blob.c", 12627db96d56Sopenharmony_ci "_sqlite/connection.c", 12637db96d56Sopenharmony_ci "_sqlite/cursor.c", 12647db96d56Sopenharmony_ci "_sqlite/microprotocols.c", 12657db96d56Sopenharmony_ci "_sqlite/module.c", 12667db96d56Sopenharmony_ci "_sqlite/prepare_protocol.c", 12677db96d56Sopenharmony_ci "_sqlite/row.c", 12687db96d56Sopenharmony_ci "_sqlite/statement.c", 12697db96d56Sopenharmony_ci "_sqlite/util.c", 12707db96d56Sopenharmony_ci ] 12717db96d56Sopenharmony_ci self.addext(Extension("_sqlite3", sources=sources)) 12727db96d56Sopenharmony_ci 12737db96d56Sopenharmony_ci def detect_platform_specific_exts(self): 12747db96d56Sopenharmony_ci # Unix-only modules 12757db96d56Sopenharmony_ci # Steen Lumholt's termios module 12767db96d56Sopenharmony_ci self.addext(Extension('termios', ['termios.c'])) 12777db96d56Sopenharmony_ci # Jeremy Hylton's rlimit interface 12787db96d56Sopenharmony_ci self.addext(Extension('resource', ['resource.c'])) 12797db96d56Sopenharmony_ci # linux/soundcard.h or sys/soundcard.h 12807db96d56Sopenharmony_ci self.addext(Extension('ossaudiodev', ['ossaudiodev.c'])) 12817db96d56Sopenharmony_ci 12827db96d56Sopenharmony_ci # macOS-only, needs SystemConfiguration and CoreFoundation framework 12837db96d56Sopenharmony_ci self.addext(Extension('_scproxy', ['_scproxy.c'])) 12847db96d56Sopenharmony_ci 12857db96d56Sopenharmony_ci def detect_compress_exts(self): 12867db96d56Sopenharmony_ci # Andrew Kuchling's zlib module. 12877db96d56Sopenharmony_ci self.addext(Extension('zlib', ['zlibmodule.c'])) 12887db96d56Sopenharmony_ci 12897db96d56Sopenharmony_ci # Helper module for various ascii-encoders. Uses zlib for an optimized 12907db96d56Sopenharmony_ci # crc32 if we have it. Otherwise binascii uses its own. 12917db96d56Sopenharmony_ci self.addext(Extension('binascii', ['binascii.c'])) 12927db96d56Sopenharmony_ci 12937db96d56Sopenharmony_ci # Gustavo Niemeyer's bz2 module. 12947db96d56Sopenharmony_ci self.addext(Extension('_bz2', ['_bz2module.c'])) 12957db96d56Sopenharmony_ci 12967db96d56Sopenharmony_ci # LZMA compression support. 12977db96d56Sopenharmony_ci self.addext(Extension('_lzma', ['_lzmamodule.c'])) 12987db96d56Sopenharmony_ci 12997db96d56Sopenharmony_ci def detect_expat_elementtree(self): 13007db96d56Sopenharmony_ci # Interface to the Expat XML parser 13017db96d56Sopenharmony_ci # 13027db96d56Sopenharmony_ci # Expat was written by James Clark and is now maintained by a group of 13037db96d56Sopenharmony_ci # developers on SourceForge; see www.libexpat.org for more information. 13047db96d56Sopenharmony_ci # The pyexpat module was written by Paul Prescod after a prototype by 13057db96d56Sopenharmony_ci # Jack Jansen. The Expat source is included in Modules/expat/. Usage 13067db96d56Sopenharmony_ci # of a system shared libexpat.so is possible with --with-system-expat 13077db96d56Sopenharmony_ci # configure option. 13087db96d56Sopenharmony_ci # 13097db96d56Sopenharmony_ci # More information on Expat can be found at www.libexpat.org. 13107db96d56Sopenharmony_ci # 13117db96d56Sopenharmony_ci self.addext(Extension('pyexpat', sources=['pyexpat.c'])) 13127db96d56Sopenharmony_ci 13137db96d56Sopenharmony_ci # Fredrik Lundh's cElementTree module. Note that this also 13147db96d56Sopenharmony_ci # uses expat (via the CAPI hook in pyexpat). 13157db96d56Sopenharmony_ci self.addext(Extension('_elementtree', sources=['_elementtree.c'])) 13167db96d56Sopenharmony_ci 13177db96d56Sopenharmony_ci def detect_multibytecodecs(self): 13187db96d56Sopenharmony_ci # Hye-Shik Chang's CJKCodecs modules. 13197db96d56Sopenharmony_ci self.addext(Extension('_multibytecodec', 13207db96d56Sopenharmony_ci ['cjkcodecs/multibytecodec.c'])) 13217db96d56Sopenharmony_ci for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'): 13227db96d56Sopenharmony_ci self.addext(Extension( 13237db96d56Sopenharmony_ci f'_codecs_{loc}', [f'cjkcodecs/_codecs_{loc}.c'] 13247db96d56Sopenharmony_ci )) 13257db96d56Sopenharmony_ci 13267db96d56Sopenharmony_ci def detect_multiprocessing(self): 13277db96d56Sopenharmony_ci # Richard Oudkerk's multiprocessing module 13287db96d56Sopenharmony_ci multiprocessing_srcs = ['_multiprocessing/multiprocessing.c'] 13297db96d56Sopenharmony_ci if ( 13307db96d56Sopenharmony_ci sysconfig.get_config_var('HAVE_SEM_OPEN') and not 13317db96d56Sopenharmony_ci sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED') 13327db96d56Sopenharmony_ci ): 13337db96d56Sopenharmony_ci multiprocessing_srcs.append('_multiprocessing/semaphore.c') 13347db96d56Sopenharmony_ci self.addext(Extension('_multiprocessing', multiprocessing_srcs)) 13357db96d56Sopenharmony_ci self.addext(Extension('_posixshmem', ['_multiprocessing/posixshmem.c'])) 13367db96d56Sopenharmony_ci 13377db96d56Sopenharmony_ci def detect_uuid(self): 13387db96d56Sopenharmony_ci # Build the _uuid module if possible 13397db96d56Sopenharmony_ci self.addext(Extension('_uuid', ['_uuidmodule.c'])) 13407db96d56Sopenharmony_ci 13417db96d56Sopenharmony_ci def detect_modules(self): 13427db96d56Sopenharmony_ci # remove dummy extension 13437db96d56Sopenharmony_ci self.extensions = [] 13447db96d56Sopenharmony_ci 13457db96d56Sopenharmony_ci # Some C extensions are built by entries in Modules/Setup.bootstrap. 13467db96d56Sopenharmony_ci # These are extensions are required to bootstrap the interpreter or 13477db96d56Sopenharmony_ci # build process. 13487db96d56Sopenharmony_ci self.detect_simple_extensions() 13497db96d56Sopenharmony_ci self.detect_test_extensions() 13507db96d56Sopenharmony_ci self.detect_readline_curses() 13517db96d56Sopenharmony_ci self.detect_crypt() 13527db96d56Sopenharmony_ci self.detect_openssl_hashlib() 13537db96d56Sopenharmony_ci self.detect_hash_builtins() 13547db96d56Sopenharmony_ci self.detect_dbm_gdbm() 13557db96d56Sopenharmony_ci self.detect_sqlite() 13567db96d56Sopenharmony_ci self.detect_platform_specific_exts() 13577db96d56Sopenharmony_ci self.detect_nis() 13587db96d56Sopenharmony_ci self.detect_compress_exts() 13597db96d56Sopenharmony_ci self.detect_expat_elementtree() 13607db96d56Sopenharmony_ci self.detect_multibytecodecs() 13617db96d56Sopenharmony_ci self.detect_decimal() 13627db96d56Sopenharmony_ci self.detect_ctypes() 13637db96d56Sopenharmony_ci self.detect_multiprocessing() 13647db96d56Sopenharmony_ci self.detect_tkinter() 13657db96d56Sopenharmony_ci self.detect_uuid() 13667db96d56Sopenharmony_ci 13677db96d56Sopenharmony_ci # Uncomment the next line if you want to play with xxmodule.c 13687db96d56Sopenharmony_ci# self.add(Extension('xx', ['xxmodule.c'])) 13697db96d56Sopenharmony_ci 13707db96d56Sopenharmony_ci self.addext(Extension('xxlimited', ['xxlimited.c'])) 13717db96d56Sopenharmony_ci self.addext(Extension('xxlimited_35', ['xxlimited_35.c'])) 13727db96d56Sopenharmony_ci 13737db96d56Sopenharmony_ci def detect_tkinter(self): 13747db96d56Sopenharmony_ci self.addext(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'])) 13757db96d56Sopenharmony_ci 13767db96d56Sopenharmony_ci def configure_ctypes(self, ext): 13777db96d56Sopenharmony_ci return True 13787db96d56Sopenharmony_ci 13797db96d56Sopenharmony_ci def detect_ctypes(self): 13807db96d56Sopenharmony_ci # Thomas Heller's _ctypes module 13817db96d56Sopenharmony_ci 13827db96d56Sopenharmony_ci if (not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and MACOS): 13837db96d56Sopenharmony_ci self.use_system_libffi = True 13847db96d56Sopenharmony_ci else: 13857db96d56Sopenharmony_ci self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS") 13867db96d56Sopenharmony_ci 13877db96d56Sopenharmony_ci include_dirs = [] 13887db96d56Sopenharmony_ci extra_compile_args = [] 13897db96d56Sopenharmony_ci extra_link_args = [] 13907db96d56Sopenharmony_ci sources = ['_ctypes/_ctypes.c', 13917db96d56Sopenharmony_ci '_ctypes/callbacks.c', 13927db96d56Sopenharmony_ci '_ctypes/callproc.c', 13937db96d56Sopenharmony_ci '_ctypes/stgdict.c', 13947db96d56Sopenharmony_ci '_ctypes/cfield.c'] 13957db96d56Sopenharmony_ci 13967db96d56Sopenharmony_ci if MACOS: 13977db96d56Sopenharmony_ci sources.append('_ctypes/malloc_closure.c') 13987db96d56Sopenharmony_ci extra_compile_args.append('-DUSING_MALLOC_CLOSURE_DOT_C=1') 13997db96d56Sopenharmony_ci extra_compile_args.append('-DMACOSX') 14007db96d56Sopenharmony_ci include_dirs.append('_ctypes/darwin') 14017db96d56Sopenharmony_ci 14027db96d56Sopenharmony_ci elif HOST_PLATFORM == 'sunos5': 14037db96d56Sopenharmony_ci # XXX This shouldn't be necessary; it appears that some 14047db96d56Sopenharmony_ci # of the assembler code is non-PIC (i.e. it has relocations 14057db96d56Sopenharmony_ci # when it shouldn't. The proper fix would be to rewrite 14067db96d56Sopenharmony_ci # the assembler code to be PIC. 14077db96d56Sopenharmony_ci # This only works with GCC; the Sun compiler likely refuses 14087db96d56Sopenharmony_ci # this option. If you want to compile ctypes with the Sun 14097db96d56Sopenharmony_ci # compiler, please research a proper solution, instead of 14107db96d56Sopenharmony_ci # finding some -z option for the Sun compiler. 14117db96d56Sopenharmony_ci extra_link_args.append('-mimpure-text') 14127db96d56Sopenharmony_ci 14137db96d56Sopenharmony_ci ext = Extension('_ctypes', 14147db96d56Sopenharmony_ci include_dirs=include_dirs, 14157db96d56Sopenharmony_ci extra_compile_args=extra_compile_args, 14167db96d56Sopenharmony_ci extra_link_args=extra_link_args, 14177db96d56Sopenharmony_ci libraries=[], 14187db96d56Sopenharmony_ci sources=sources) 14197db96d56Sopenharmony_ci self.add(ext) 14207db96d56Sopenharmony_ci # function my_sqrt() needs libm for sqrt() 14217db96d56Sopenharmony_ci self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'])) 14227db96d56Sopenharmony_ci 14237db96d56Sopenharmony_ci ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR") 14247db96d56Sopenharmony_ci ffi_lib = None 14257db96d56Sopenharmony_ci 14267db96d56Sopenharmony_ci ffi_inc_dirs = self.inc_dirs.copy() 14277db96d56Sopenharmony_ci if MACOS: 14287db96d56Sopenharmony_ci ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi") 14297db96d56Sopenharmony_ci 14307db96d56Sopenharmony_ci if not ffi_inc: 14317db96d56Sopenharmony_ci if os.path.exists(ffi_in_sdk): 14327db96d56Sopenharmony_ci ext.extra_compile_args.append("-DUSING_APPLE_OS_LIBFFI=1") 14337db96d56Sopenharmony_ci ffi_inc = ffi_in_sdk 14347db96d56Sopenharmony_ci ffi_lib = 'ffi' 14357db96d56Sopenharmony_ci else: 14367db96d56Sopenharmony_ci # OS X 10.5 comes with libffi.dylib; the include files are 14377db96d56Sopenharmony_ci # in /usr/include/ffi 14387db96d56Sopenharmony_ci ffi_inc_dirs.append('/usr/include/ffi') 14397db96d56Sopenharmony_ci 14407db96d56Sopenharmony_ci if not ffi_inc: 14417db96d56Sopenharmony_ci found = find_file('ffi.h', [], ffi_inc_dirs) 14427db96d56Sopenharmony_ci if found: 14437db96d56Sopenharmony_ci ffi_inc = found[0] 14447db96d56Sopenharmony_ci if ffi_inc: 14457db96d56Sopenharmony_ci ffi_h = ffi_inc + '/ffi.h' 14467db96d56Sopenharmony_ci if not os.path.exists(ffi_h): 14477db96d56Sopenharmony_ci ffi_inc = None 14487db96d56Sopenharmony_ci print('Header file {} does not exist'.format(ffi_h)) 14497db96d56Sopenharmony_ci if ffi_lib is None and ffi_inc: 14507db96d56Sopenharmony_ci for lib_name in ('ffi', 'ffi_pic'): 14517db96d56Sopenharmony_ci if (self.compiler.find_library_file(self.lib_dirs, lib_name)): 14527db96d56Sopenharmony_ci ffi_lib = lib_name 14537db96d56Sopenharmony_ci break 14547db96d56Sopenharmony_ci 14557db96d56Sopenharmony_ci if ffi_inc and ffi_lib: 14567db96d56Sopenharmony_ci ffi_headers = glob(os.path.join(ffi_inc, '*.h')) 14577db96d56Sopenharmony_ci if grep_headers_for('ffi_prep_cif_var', ffi_headers): 14587db96d56Sopenharmony_ci ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1") 14597db96d56Sopenharmony_ci if grep_headers_for('ffi_prep_closure_loc', ffi_headers): 14607db96d56Sopenharmony_ci ext.extra_compile_args.append("-DHAVE_FFI_PREP_CLOSURE_LOC=1") 14617db96d56Sopenharmony_ci if grep_headers_for('ffi_closure_alloc', ffi_headers): 14627db96d56Sopenharmony_ci ext.extra_compile_args.append("-DHAVE_FFI_CLOSURE_ALLOC=1") 14637db96d56Sopenharmony_ci 14647db96d56Sopenharmony_ci ext.include_dirs.append(ffi_inc) 14657db96d56Sopenharmony_ci ext.libraries.append(ffi_lib) 14667db96d56Sopenharmony_ci self.use_system_libffi = True 14677db96d56Sopenharmony_ci 14687db96d56Sopenharmony_ci if sysconfig.get_config_var('HAVE_LIBDL'): 14697db96d56Sopenharmony_ci # for dlopen, see bpo-32647 14707db96d56Sopenharmony_ci ext.libraries.append('dl') 14717db96d56Sopenharmony_ci 14727db96d56Sopenharmony_ci def detect_decimal(self): 14737db96d56Sopenharmony_ci # Stefan Krah's _decimal module 14747db96d56Sopenharmony_ci self.addext( 14757db96d56Sopenharmony_ci Extension( 14767db96d56Sopenharmony_ci '_decimal', 14777db96d56Sopenharmony_ci ['_decimal/_decimal.c'], 14787db96d56Sopenharmony_ci # Uncomment for extra functionality: 14797db96d56Sopenharmony_ci # define_macros=[('EXTRA_FUNCTIONALITY', 1)] 14807db96d56Sopenharmony_ci ) 14817db96d56Sopenharmony_ci ) 14827db96d56Sopenharmony_ci 14837db96d56Sopenharmony_ci def detect_openssl_hashlib(self): 14847db96d56Sopenharmony_ci self.addext(Extension('_ssl', ['_ssl.c'])) 14857db96d56Sopenharmony_ci self.addext(Extension('_hashlib', ['_hashopenssl.c'])) 14867db96d56Sopenharmony_ci 14877db96d56Sopenharmony_ci def detect_hash_builtins(self): 14887db96d56Sopenharmony_ci # By default we always compile these even when OpenSSL is available 14897db96d56Sopenharmony_ci # (issue #14693). It's harmless and the object code is tiny 14907db96d56Sopenharmony_ci # (40-50 KiB per module, only loaded when actually used). Modules can 14917db96d56Sopenharmony_ci # be disabled via the --with-builtin-hashlib-hashes configure flag. 14927db96d56Sopenharmony_ci 14937db96d56Sopenharmony_ci self.addext(Extension('_md5', ['md5module.c'])) 14947db96d56Sopenharmony_ci self.addext(Extension('_sha1', ['sha1module.c'])) 14957db96d56Sopenharmony_ci self.addext(Extension('_sha256', ['sha256module.c'])) 14967db96d56Sopenharmony_ci self.addext(Extension('_sha512', ['sha512module.c'])) 14977db96d56Sopenharmony_ci self.addext(Extension('_sha3', ['_sha3/sha3module.c'])) 14987db96d56Sopenharmony_ci self.addext(Extension('_blake2', 14997db96d56Sopenharmony_ci [ 15007db96d56Sopenharmony_ci '_blake2/blake2module.c', 15017db96d56Sopenharmony_ci '_blake2/blake2b_impl.c', 15027db96d56Sopenharmony_ci '_blake2/blake2s_impl.c' 15037db96d56Sopenharmony_ci ] 15047db96d56Sopenharmony_ci )) 15057db96d56Sopenharmony_ci 15067db96d56Sopenharmony_ci def detect_nis(self): 15077db96d56Sopenharmony_ci self.addext(Extension('nis', ['nismodule.c'])) 15087db96d56Sopenharmony_ci 15097db96d56Sopenharmony_ci 15107db96d56Sopenharmony_ciclass PyBuildInstall(install): 15117db96d56Sopenharmony_ci # Suppress the warning about installation into the lib_dynload 15127db96d56Sopenharmony_ci # directory, which is not in sys.path when running Python during 15137db96d56Sopenharmony_ci # installation: 15147db96d56Sopenharmony_ci def initialize_options (self): 15157db96d56Sopenharmony_ci install.initialize_options(self) 15167db96d56Sopenharmony_ci self.warn_dir=0 15177db96d56Sopenharmony_ci 15187db96d56Sopenharmony_ci # Customize subcommands to not install an egg-info file for Python 15197db96d56Sopenharmony_ci sub_commands = [('install_lib', install.has_lib), 15207db96d56Sopenharmony_ci ('install_headers', install.has_headers), 15217db96d56Sopenharmony_ci ('install_scripts', install.has_scripts), 15227db96d56Sopenharmony_ci ('install_data', install.has_data)] 15237db96d56Sopenharmony_ci 15247db96d56Sopenharmony_ci 15257db96d56Sopenharmony_ciclass PyBuildInstallLib(install_lib): 15267db96d56Sopenharmony_ci # Do exactly what install_lib does but make sure correct access modes get 15277db96d56Sopenharmony_ci # set on installed directories and files. All installed files with get 15287db96d56Sopenharmony_ci # mode 644 unless they are a shared library in which case they will get 15297db96d56Sopenharmony_ci # mode 755. All installed directories will get mode 755. 15307db96d56Sopenharmony_ci 15317db96d56Sopenharmony_ci # this is works for EXT_SUFFIX too, which ends with SHLIB_SUFFIX 15327db96d56Sopenharmony_ci shlib_suffix = sysconfig.get_config_var("SHLIB_SUFFIX") 15337db96d56Sopenharmony_ci 15347db96d56Sopenharmony_ci def install(self): 15357db96d56Sopenharmony_ci outfiles = install_lib.install(self) 15367db96d56Sopenharmony_ci self.set_file_modes(outfiles, 0o644, 0o755) 15377db96d56Sopenharmony_ci self.set_dir_modes(self.install_dir, 0o755) 15387db96d56Sopenharmony_ci return outfiles 15397db96d56Sopenharmony_ci 15407db96d56Sopenharmony_ci def set_file_modes(self, files, defaultMode, sharedLibMode): 15417db96d56Sopenharmony_ci if not files: return 15427db96d56Sopenharmony_ci 15437db96d56Sopenharmony_ci for filename in files: 15447db96d56Sopenharmony_ci if os.path.islink(filename): continue 15457db96d56Sopenharmony_ci mode = defaultMode 15467db96d56Sopenharmony_ci if filename.endswith(self.shlib_suffix): mode = sharedLibMode 15477db96d56Sopenharmony_ci log.info("changing mode of %s to %o", filename, mode) 15487db96d56Sopenharmony_ci if not self.dry_run: os.chmod(filename, mode) 15497db96d56Sopenharmony_ci 15507db96d56Sopenharmony_ci def set_dir_modes(self, dirname, mode): 15517db96d56Sopenharmony_ci for dirpath, dirnames, fnames in os.walk(dirname): 15527db96d56Sopenharmony_ci if os.path.islink(dirpath): 15537db96d56Sopenharmony_ci continue 15547db96d56Sopenharmony_ci log.info("changing mode of %s to %o", dirpath, mode) 15557db96d56Sopenharmony_ci if not self.dry_run: os.chmod(dirpath, mode) 15567db96d56Sopenharmony_ci 15577db96d56Sopenharmony_ci 15587db96d56Sopenharmony_ciclass PyBuildScripts(build_scripts): 15597db96d56Sopenharmony_ci def copy_scripts(self): 15607db96d56Sopenharmony_ci outfiles, updated_files = build_scripts.copy_scripts(self) 15617db96d56Sopenharmony_ci fullversion = '-{0[0]}.{0[1]}'.format(sys.version_info) 15627db96d56Sopenharmony_ci minoronly = '.{0[1]}'.format(sys.version_info) 15637db96d56Sopenharmony_ci newoutfiles = [] 15647db96d56Sopenharmony_ci newupdated_files = [] 15657db96d56Sopenharmony_ci for filename in outfiles: 15667db96d56Sopenharmony_ci if filename.endswith('2to3'): 15677db96d56Sopenharmony_ci newfilename = filename + fullversion 15687db96d56Sopenharmony_ci else: 15697db96d56Sopenharmony_ci newfilename = filename + minoronly 15707db96d56Sopenharmony_ci log.info(f'renaming {filename} to {newfilename}') 15717db96d56Sopenharmony_ci os.rename(filename, newfilename) 15727db96d56Sopenharmony_ci newoutfiles.append(newfilename) 15737db96d56Sopenharmony_ci if filename in updated_files: 15747db96d56Sopenharmony_ci newupdated_files.append(newfilename) 15757db96d56Sopenharmony_ci return newoutfiles, newupdated_files 15767db96d56Sopenharmony_ci 15777db96d56Sopenharmony_ci 15787db96d56Sopenharmony_cidef main(): 15797db96d56Sopenharmony_ci global LIST_MODULE_NAMES 15807db96d56Sopenharmony_ci 15817db96d56Sopenharmony_ci if "--list-module-names" in sys.argv: 15827db96d56Sopenharmony_ci LIST_MODULE_NAMES = True 15837db96d56Sopenharmony_ci sys.argv.remove("--list-module-names") 15847db96d56Sopenharmony_ci 15857db96d56Sopenharmony_ci set_compiler_flags('CFLAGS', 'PY_CFLAGS_NODIST') 15867db96d56Sopenharmony_ci set_compiler_flags('LDFLAGS', 'PY_LDFLAGS_NODIST') 15877db96d56Sopenharmony_ci 15887db96d56Sopenharmony_ci class DummyProcess: 15897db96d56Sopenharmony_ci """Hack for parallel build""" 15907db96d56Sopenharmony_ci ProcessPoolExecutor = None 15917db96d56Sopenharmony_ci 15927db96d56Sopenharmony_ci sys.modules['concurrent.futures.process'] = DummyProcess 15937db96d56Sopenharmony_ci validate_tzpath() 15947db96d56Sopenharmony_ci 15957db96d56Sopenharmony_ci # turn off warnings when deprecated modules are imported 15967db96d56Sopenharmony_ci import warnings 15977db96d56Sopenharmony_ci warnings.filterwarnings("ignore",category=DeprecationWarning) 15987db96d56Sopenharmony_ci setup(# PyPI Metadata (PEP 301) 15997db96d56Sopenharmony_ci name = "Python", 16007db96d56Sopenharmony_ci version = sys.version.split()[0], 16017db96d56Sopenharmony_ci url = "https://www.python.org/%d.%d" % sys.version_info[:2], 16027db96d56Sopenharmony_ci maintainer = "Guido van Rossum and the Python community", 16037db96d56Sopenharmony_ci maintainer_email = "python-dev@python.org", 16047db96d56Sopenharmony_ci description = "A high-level object-oriented programming language", 16057db96d56Sopenharmony_ci long_description = SUMMARY.strip(), 16067db96d56Sopenharmony_ci license = "PSF license", 16077db96d56Sopenharmony_ci classifiers = [x for x in CLASSIFIERS.split("\n") if x], 16087db96d56Sopenharmony_ci platforms = ["Many"], 16097db96d56Sopenharmony_ci 16107db96d56Sopenharmony_ci # Build info 16117db96d56Sopenharmony_ci cmdclass = {'build_ext': PyBuildExt, 16127db96d56Sopenharmony_ci 'build_scripts': PyBuildScripts, 16137db96d56Sopenharmony_ci 'install': PyBuildInstall, 16147db96d56Sopenharmony_ci 'install_lib': PyBuildInstallLib}, 16157db96d56Sopenharmony_ci # A dummy module is defined here, because build_ext won't be 16167db96d56Sopenharmony_ci # called unless there's at least one extension module defined. 16177db96d56Sopenharmony_ci ext_modules=[Extension('_dummy', ['_dummy.c'])], 16187db96d56Sopenharmony_ci 16197db96d56Sopenharmony_ci # If you change the scripts installed here, you also need to 16207db96d56Sopenharmony_ci # check the PyBuildScripts command above, and change the links 16217db96d56Sopenharmony_ci # created by the bininstall target in Makefile.pre.in 16227db96d56Sopenharmony_ci scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3", 16237db96d56Sopenharmony_ci "Tools/scripts/2to3"] 16247db96d56Sopenharmony_ci ) 16257db96d56Sopenharmony_ci 16267db96d56Sopenharmony_ci# --install-platlib 16277db96d56Sopenharmony_ciif __name__ == '__main__': 16287db96d56Sopenharmony_ci main() 1629