1# Autodetecting setup.py script for building the Python extensions 2 3import argparse 4import importlib._bootstrap 5import importlib.machinery 6import importlib.util 7import os 8import re 9import sys 10import sysconfig 11from glob import glob 12 13from distutils import log 14from distutils.command.build_ext import build_ext 15from distutils.command.build_scripts import build_scripts 16from distutils.command.install import install 17from distutils.command.install_lib import install_lib 18from distutils.core import Extension, setup 19from distutils.errors import CCompilerError, DistutilsError 20from distutils.spawn import find_executable 21 22 23# Compile extensions used to test Python? 24TEST_EXTENSIONS = True 25 26# This global variable is used to hold the list of modules to be disabled. 27DISABLED_MODULE_LIST = [] 28 29 30def get_platform(): 31 # Cross compiling 32 if "_PYTHON_HOST_PLATFORM" in os.environ: 33 return os.environ["_PYTHON_HOST_PLATFORM"] 34 35 # Get value of sys.platform 36 if sys.platform.startswith('osf1'): 37 return 'osf1' 38 return sys.platform 39 40 41CROSS_COMPILING = ("_PYTHON_HOST_PLATFORM" in os.environ) 42HOST_PLATFORM = get_platform() 43MS_WINDOWS = (HOST_PLATFORM == 'win32') 44CYGWIN = (HOST_PLATFORM == 'cygwin') 45MACOS = (HOST_PLATFORM == 'darwin') 46AIX = (HOST_PLATFORM.startswith('aix')) 47VXWORKS = ('vxworks' in HOST_PLATFORM) 48 49 50SUMMARY = """ 51Python is an interpreted, interactive, object-oriented programming 52language. It is often compared to Tcl, Perl, Scheme or Java. 53 54Python combines remarkable power with very clear syntax. It has 55modules, classes, exceptions, very high level dynamic data types, and 56dynamic typing. There are interfaces to many system calls and 57libraries, as well as to various windowing systems (X11, Motif, Tk, 58Mac, MFC). New built-in modules are easily written in C or C++. Python 59is also usable as an extension language for applications that need a 60programmable interface. 61 62The Python implementation is portable: it runs on many brands of UNIX, 63on Windows, DOS, Mac, Amiga... If your favorite system isn't 64listed here, it may still be supported, if there's a C compiler for 65it. Ask around on comp.lang.python -- or just try compiling Python 66yourself. 67""" 68 69CLASSIFIERS = """ 70Development Status :: 6 - Mature 71License :: OSI Approved :: Python Software Foundation License 72Natural Language :: English 73Programming Language :: C 74Programming Language :: Python 75Topic :: Software Development 76""" 77 78 79# Set common compiler and linker flags derived from the Makefile, 80# reserved for building the interpreter and the stdlib modules. 81# See bpo-21121 and bpo-35257 82def set_compiler_flags(compiler_flags, compiler_py_flags_nodist): 83 flags = sysconfig.get_config_var(compiler_flags) 84 py_flags_nodist = sysconfig.get_config_var(compiler_py_flags_nodist) 85 sysconfig.get_config_vars()[compiler_flags] = flags + ' ' + py_flags_nodist 86 87 88def add_dir_to_list(dirlist, dir): 89 """Add the directory 'dir' to the list 'dirlist' (after any relative 90 directories) if: 91 92 1) 'dir' is not already in 'dirlist' 93 2) 'dir' actually exists, and is a directory. 94 """ 95 if dir is None or not os.path.isdir(dir) or dir in dirlist: 96 return 97 for i, path in enumerate(dirlist): 98 if not os.path.isabs(path): 99 dirlist.insert(i + 1, dir) 100 return 101 dirlist.insert(0, dir) 102 103 104def sysroot_paths(make_vars, subdirs): 105 """Get the paths of sysroot sub-directories. 106 107 * make_vars: a sequence of names of variables of the Makefile where 108 sysroot may be set. 109 * subdirs: a sequence of names of subdirectories used as the location for 110 headers or libraries. 111 """ 112 113 dirs = [] 114 for var_name in make_vars: 115 var = sysconfig.get_config_var(var_name) 116 if var is not None: 117 m = re.search(r'--sysroot=([^"]\S*|"[^"]+")', var) 118 if m is not None: 119 sysroot = m.group(1).strip('"') 120 for subdir in subdirs: 121 if os.path.isabs(subdir): 122 subdir = subdir[1:] 123 path = os.path.join(sysroot, subdir) 124 if os.path.isdir(path): 125 dirs.append(path) 126 break 127 return dirs 128 129MACOS_SDK_ROOT = None 130 131def macosx_sdk_root(): 132 """Return the directory of the current macOS SDK. 133 134 If no SDK was explicitly configured, call the compiler to find which 135 include files paths are being searched by default. Use '/' if the 136 compiler is searching /usr/include (meaning system header files are 137 installed) or use the root of an SDK if that is being searched. 138 (The SDK may be supplied via Xcode or via the Command Line Tools). 139 The SDK paths used by Apple-supplied tool chains depend on the 140 setting of various variables; see the xcrun man page for more info. 141 """ 142 global MACOS_SDK_ROOT 143 144 # If already called, return cached result. 145 if MACOS_SDK_ROOT: 146 return MACOS_SDK_ROOT 147 148 cflags = sysconfig.get_config_var('CFLAGS') 149 m = re.search(r'-isysroot\s+(\S+)', cflags) 150 if m is not None: 151 MACOS_SDK_ROOT = m.group(1) 152 else: 153 MACOS_SDK_ROOT = '/' 154 cc = sysconfig.get_config_var('CC') 155 tmpfile = '/tmp/setup_sdk_root.%d' % os.getpid() 156 try: 157 os.unlink(tmpfile) 158 except: 159 pass 160 ret = os.system('%s -E -v - </dev/null 2>%s 1>/dev/null' % (cc, tmpfile)) 161 in_incdirs = False 162 try: 163 if ret >> 8 == 0: 164 with open(tmpfile) as fp: 165 for line in fp.readlines(): 166 if line.startswith("#include <...>"): 167 in_incdirs = True 168 elif line.startswith("End of search list"): 169 in_incdirs = False 170 elif in_incdirs: 171 line = line.strip() 172 if line == '/usr/include': 173 MACOS_SDK_ROOT = '/' 174 elif line.endswith(".sdk/usr/include"): 175 MACOS_SDK_ROOT = line[:-12] 176 finally: 177 os.unlink(tmpfile) 178 179 return MACOS_SDK_ROOT 180 181 182def is_macosx_sdk_path(path): 183 """ 184 Returns True if 'path' can be located in an OSX SDK 185 """ 186 return ( (path.startswith('/usr/') and not path.startswith('/usr/local')) 187 or path.startswith('/System/') 188 or path.startswith('/Library/') ) 189 190 191def find_file(filename, std_dirs, paths): 192 """Searches for the directory where a given file is located, 193 and returns a possibly-empty list of additional directories, or None 194 if the file couldn't be found at all. 195 196 'filename' is the name of a file, such as readline.h or libcrypto.a. 197 'std_dirs' is the list of standard system directories; if the 198 file is found in one of them, no additional directives are needed. 199 'paths' is a list of additional locations to check; if the file is 200 found in one of them, the resulting list will contain the directory. 201 """ 202 if MACOS: 203 # Honor the MacOSX SDK setting when one was specified. 204 # An SDK is a directory with the same structure as a real 205 # system, but with only header files and libraries. 206 sysroot = macosx_sdk_root() 207 208 # Check the standard locations 209 for dir in std_dirs: 210 f = os.path.join(dir, filename) 211 212 if MACOS and is_macosx_sdk_path(dir): 213 f = os.path.join(sysroot, dir[1:], filename) 214 215 if os.path.exists(f): return [] 216 217 # Check the additional directories 218 for dir in paths: 219 f = os.path.join(dir, filename) 220 221 if MACOS and is_macosx_sdk_path(dir): 222 f = os.path.join(sysroot, dir[1:], filename) 223 224 if os.path.exists(f): 225 return [dir] 226 227 # Not found anywhere 228 return None 229 230 231def find_library_file(compiler, libname, std_dirs, paths): 232 result = compiler.find_library_file(std_dirs + paths, libname) 233 if result is None: 234 return None 235 236 if MACOS: 237 sysroot = macosx_sdk_root() 238 239 # Check whether the found file is in one of the standard directories 240 dirname = os.path.dirname(result) 241 for p in std_dirs: 242 # Ensure path doesn't end with path separator 243 p = p.rstrip(os.sep) 244 245 if MACOS and is_macosx_sdk_path(p): 246 # Note that, as of Xcode 7, Apple SDKs may contain textual stub 247 # libraries with .tbd extensions rather than the normal .dylib 248 # shared libraries installed in /. The Apple compiler tool 249 # chain handles this transparently but it can cause problems 250 # for programs that are being built with an SDK and searching 251 # for specific libraries. Distutils find_library_file() now 252 # knows to also search for and return .tbd files. But callers 253 # of find_library_file need to keep in mind that the base filename 254 # of the returned SDK library file might have a different extension 255 # from that of the library file installed on the running system, 256 # for example: 257 # /Applications/Xcode.app/Contents/Developer/Platforms/ 258 # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ 259 # usr/lib/libedit.tbd 260 # vs 261 # /usr/lib/libedit.dylib 262 if os.path.join(sysroot, p[1:]) == dirname: 263 return [ ] 264 265 if p == dirname: 266 return [ ] 267 268 # Otherwise, it must have been in one of the additional directories, 269 # so we have to figure out which one. 270 for p in paths: 271 # Ensure path doesn't end with path separator 272 p = p.rstrip(os.sep) 273 274 if MACOS and is_macosx_sdk_path(p): 275 if os.path.join(sysroot, p[1:]) == dirname: 276 return [ p ] 277 278 if p == dirname: 279 return [p] 280 else: 281 assert False, "Internal error: Path not found in std_dirs or paths" 282 283 284def find_module_file(module, dirlist): 285 """Find a module in a set of possible folders. If it is not found 286 return the unadorned filename""" 287 list = find_file(module, [], dirlist) 288 if not list: 289 return module 290 if len(list) > 1: 291 log.info("WARNING: multiple copies of %s found", module) 292 return os.path.join(list[0], module) 293 294 295class PyBuildExt(build_ext): 296 297 def __init__(self, dist): 298 build_ext.__init__(self, dist) 299 self.srcdir = None 300 self.lib_dirs = None 301 self.inc_dirs = None 302 self.config_h_vars = None 303 self.failed = [] 304 self.failed_on_import = [] 305 self.missing = [] 306 if '-j' in os.environ.get('MAKEFLAGS', ''): 307 self.parallel = True 308 309 def add(self, ext): 310 self.extensions.append(ext) 311 312 def build_extensions(self): 313 self.srcdir = sysconfig.get_config_var('srcdir') 314 if not self.srcdir: 315 # Maybe running on Windows but not using CYGWIN? 316 raise ValueError("No source directory; cannot proceed.") 317 self.srcdir = os.path.abspath(self.srcdir) 318 319 # Detect which modules should be compiled 320 self.detect_modules() 321 322 # Remove modules that are present on the disabled list 323 extensions = [ext for ext in self.extensions 324 if ext.name not in DISABLED_MODULE_LIST] 325 # move ctypes to the end, it depends on other modules 326 ext_map = dict((ext.name, i) for i, ext in enumerate(extensions)) 327 if "_ctypes" in ext_map: 328 ctypes = extensions.pop(ext_map["_ctypes"]) 329 extensions.append(ctypes) 330 self.extensions = extensions 331 332 # Fix up the autodetected modules, prefixing all the source files 333 # with Modules/. 334 moddirlist = [os.path.join(self.srcdir, 'Modules')] 335 336 # Fix up the paths for scripts, too 337 self.distribution.scripts = [os.path.join(self.srcdir, filename) 338 for filename in self.distribution.scripts] 339 340 # Python header files 341 headers = [sysconfig.get_config_h_filename()] 342 headers += glob(os.path.join(sysconfig.get_path('include'), "*.h")) 343 344 # The sysconfig variables built by makesetup that list the already 345 # built modules and the disabled modules as configured by the Setup 346 # files. 347 sysconf_built = sysconfig.get_config_var('MODBUILT_NAMES').split() 348 sysconf_dis = sysconfig.get_config_var('MODDISABLED_NAMES').split() 349 350 mods_built = [] 351 mods_disabled = [] 352 for ext in self.extensions: 353 ext.sources = [ find_module_file(filename, moddirlist) 354 for filename in ext.sources ] 355 if ext.depends is not None: 356 ext.depends = [find_module_file(filename, moddirlist) 357 for filename in ext.depends] 358 else: 359 ext.depends = [] 360 # re-compile extensions if a header file has been changed 361 ext.depends.extend(headers) 362 363 # If a module has already been built or has been disabled in the 364 # Setup files, don't build it here. 365 if ext.name in sysconf_built: 366 mods_built.append(ext) 367 if ext.name in sysconf_dis: 368 mods_disabled.append(ext) 369 370 mods_configured = mods_built + mods_disabled 371 if mods_configured: 372 self.extensions = [x for x in self.extensions if x not in 373 mods_configured] 374 # Remove the shared libraries built by a previous build. 375 for ext in mods_configured: 376 fullpath = self.get_ext_fullpath(ext.name) 377 if os.path.exists(fullpath): 378 os.unlink(fullpath) 379 380 # When you run "make CC=altcc" or something similar, you really want 381 # those environment variables passed into the setup.py phase. Here's 382 # a small set of useful ones. 383 compiler = os.environ.get('CC') 384 args = {} 385 # unfortunately, distutils doesn't let us provide separate C and C++ 386 # compilers 387 if compiler is not None: 388 (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS') 389 args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags 390 self.compiler.set_executables(**args) 391 392 build_ext.build_extensions(self) 393 394 for ext in self.extensions: 395 self.check_extension_import(ext) 396 397 longest = max([len(e.name) for e in self.extensions], default=0) 398 if self.failed or self.failed_on_import: 399 all_failed = self.failed + self.failed_on_import 400 longest = max(longest, max([len(name) for name in all_failed])) 401 402 def print_three_column(lst): 403 lst.sort(key=str.lower) 404 # guarantee zip() doesn't drop anything 405 while len(lst) % 3: 406 lst.append("") 407 for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]): 408 print("%-*s %-*s %-*s" % (longest, e, longest, f, 409 longest, g)) 410 411 if self.missing: 412 print() 413 print("Python build finished successfully!") 414 print("The necessary bits to build these optional modules were not " 415 "found:") 416 print_three_column(self.missing) 417 print("To find the necessary bits, look in setup.py in" 418 " detect_modules() for the module's name.") 419 print() 420 421 if mods_built: 422 print() 423 print("The following modules found by detect_modules() in" 424 " setup.py, have been") 425 print("built by the Makefile instead, as configured by the" 426 " Setup files:") 427 print_three_column([ext.name for ext in mods_built]) 428 print() 429 430 if mods_disabled: 431 print() 432 print("The following modules found by detect_modules() in" 433 " setup.py have not") 434 print("been built, they are *disabled* in the Setup files:") 435 print_three_column([ext.name for ext in mods_disabled]) 436 print() 437 438 if self.failed: 439 failed = self.failed[:] 440 print() 441 print("Failed to build these modules:") 442 print_three_column(failed) 443 print() 444 445 if self.failed_on_import: 446 failed = self.failed_on_import[:] 447 print() 448 print("Following modules built successfully" 449 " but were removed because they could not be imported:") 450 print_three_column(failed) 451 print() 452 453 if any('_ssl' in l 454 for l in (self.missing, self.failed, self.failed_on_import)): 455 print() 456 print("Could not build the ssl module!") 457 print("Python requires an OpenSSL 1.0.2 or 1.1 compatible " 458 "libssl with X509_VERIFY_PARAM_set1_host().") 459 print("LibreSSL 2.6.4 and earlier do not provide the necessary " 460 "APIs, https://github.com/libressl-portable/portable/issues/381") 461 print() 462 463 def build_extension(self, ext): 464 465 if ext.name == '_ctypes': 466 if not self.configure_ctypes(ext): 467 self.failed.append(ext.name) 468 return 469 470 try: 471 build_ext.build_extension(self, ext) 472 except (CCompilerError, DistutilsError) as why: 473 self.announce('WARNING: building of extension "%s" failed: %s' % 474 (ext.name, why)) 475 self.failed.append(ext.name) 476 return 477 478 def check_extension_import(self, ext): 479 # Don't try to import an extension that has failed to compile 480 if ext.name in self.failed: 481 self.announce( 482 'WARNING: skipping import check for failed build "%s"' % 483 ext.name, level=1) 484 return 485 486 # Workaround for Mac OS X: The Carbon-based modules cannot be 487 # reliably imported into a command-line Python 488 if 'Carbon' in ext.extra_link_args: 489 self.announce( 490 'WARNING: skipping import check for Carbon-based "%s"' % 491 ext.name) 492 return 493 494 if MACOS and ( 495 sys.maxsize > 2**32 and '-arch' in ext.extra_link_args): 496 # Don't bother doing an import check when an extension was 497 # build with an explicit '-arch' flag on OSX. That's currently 498 # only used to build 32-bit only extensions in a 4-way 499 # universal build and loading 32-bit code into a 64-bit 500 # process will fail. 501 self.announce( 502 'WARNING: skipping import check for "%s"' % 503 ext.name) 504 return 505 506 # Workaround for Cygwin: Cygwin currently has fork issues when many 507 # modules have been imported 508 if CYGWIN: 509 self.announce('WARNING: skipping import check for Cygwin-based "%s"' 510 % ext.name) 511 return 512 ext_filename = os.path.join( 513 self.build_lib, 514 self.get_ext_filename(self.get_ext_fullname(ext.name))) 515 516 # If the build directory didn't exist when setup.py was 517 # started, sys.path_importer_cache has a negative result 518 # cached. Clear that cache before trying to import. 519 sys.path_importer_cache.clear() 520 521 # Don't try to load extensions for cross builds 522 if CROSS_COMPILING: 523 return 524 525 loader = importlib.machinery.ExtensionFileLoader(ext.name, ext_filename) 526 spec = importlib.util.spec_from_file_location(ext.name, ext_filename, 527 loader=loader) 528 try: 529 importlib._bootstrap._load(spec) 530 except ImportError as why: 531 self.failed_on_import.append(ext.name) 532 self.announce('*** WARNING: renaming "%s" since importing it' 533 ' failed: %s' % (ext.name, why), level=3) 534 assert not self.inplace 535 basename, tail = os.path.splitext(ext_filename) 536 newname = basename + "_failed" + tail 537 if os.path.exists(newname): 538 os.remove(newname) 539 os.rename(ext_filename, newname) 540 541 except: 542 exc_type, why, tb = sys.exc_info() 543 self.announce('*** WARNING: importing extension "%s" ' 544 'failed with %s: %s' % (ext.name, exc_type, why), 545 level=3) 546 self.failed.append(ext.name) 547 548 def add_multiarch_paths(self): 549 # Debian/Ubuntu multiarch support. 550 # https://wiki.ubuntu.com/MultiarchSpec 551 cc = sysconfig.get_config_var('CC') 552 tmpfile = os.path.join(self.build_temp, 'multiarch') 553 if not os.path.exists(self.build_temp): 554 os.makedirs(self.build_temp) 555 ret = os.system( 556 '%s -print-multiarch > %s 2> /dev/null' % (cc, tmpfile)) 557 multiarch_path_component = '' 558 try: 559 if ret >> 8 == 0: 560 with open(tmpfile) as fp: 561 multiarch_path_component = fp.readline().strip() 562 finally: 563 os.unlink(tmpfile) 564 565 if multiarch_path_component != '': 566 add_dir_to_list(self.compiler.library_dirs, 567 '/usr/lib/' + multiarch_path_component) 568 add_dir_to_list(self.compiler.include_dirs, 569 '/usr/include/' + multiarch_path_component) 570 return 571 572 if not find_executable('dpkg-architecture'): 573 return 574 opt = '' 575 if CROSS_COMPILING: 576 opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE') 577 tmpfile = os.path.join(self.build_temp, 'multiarch') 578 if not os.path.exists(self.build_temp): 579 os.makedirs(self.build_temp) 580 ret = os.system( 581 'dpkg-architecture %s -qDEB_HOST_MULTIARCH > %s 2> /dev/null' % 582 (opt, tmpfile)) 583 try: 584 if ret >> 8 == 0: 585 with open(tmpfile) as fp: 586 multiarch_path_component = fp.readline().strip() 587 add_dir_to_list(self.compiler.library_dirs, 588 '/usr/lib/' + multiarch_path_component) 589 add_dir_to_list(self.compiler.include_dirs, 590 '/usr/include/' + multiarch_path_component) 591 finally: 592 os.unlink(tmpfile) 593 594 def add_cross_compiling_paths(self): 595 cc = sysconfig.get_config_var('CC') 596 tmpfile = os.path.join(self.build_temp, 'ccpaths') 597 if not os.path.exists(self.build_temp): 598 os.makedirs(self.build_temp) 599 ret = os.system('%s -E -v - </dev/null 2>%s 1>/dev/null' % (cc, tmpfile)) 600 is_gcc = False 601 is_clang = False 602 in_incdirs = False 603 try: 604 if ret >> 8 == 0: 605 with open(tmpfile) as fp: 606 for line in fp.readlines(): 607 if line.startswith("gcc version"): 608 is_gcc = True 609 elif line.startswith("clang version"): 610 is_clang = True 611 elif line.startswith("#include <...>"): 612 in_incdirs = True 613 elif line.startswith("End of search list"): 614 in_incdirs = False 615 elif (is_gcc or is_clang) and line.startswith("LIBRARY_PATH"): 616 for d in line.strip().split("=")[1].split(":"): 617 d = os.path.normpath(d) 618 if '/gcc/' not in d: 619 add_dir_to_list(self.compiler.library_dirs, 620 d) 621 elif (is_gcc or is_clang) and in_incdirs and '/gcc/' not in line and '/clang/' not in line: 622 add_dir_to_list(self.compiler.include_dirs, 623 line.strip()) 624 finally: 625 os.unlink(tmpfile) 626 627 def add_ldflags_cppflags(self): 628 # Add paths specified in the environment variables LDFLAGS and 629 # CPPFLAGS for header and library files. 630 # We must get the values from the Makefile and not the environment 631 # directly since an inconsistently reproducible issue comes up where 632 # the environment variable is not set even though the value were passed 633 # into configure and stored in the Makefile (issue found on OS X 10.3). 634 for env_var, arg_name, dir_list in ( 635 ('LDFLAGS', '-R', self.compiler.runtime_library_dirs), 636 ('LDFLAGS', '-L', self.compiler.library_dirs), 637 ('CPPFLAGS', '-I', self.compiler.include_dirs)): 638 env_val = sysconfig.get_config_var(env_var) 639 if env_val: 640 parser = argparse.ArgumentParser() 641 parser.add_argument(arg_name, dest="dirs", action="append") 642 options, _ = parser.parse_known_args(env_val.split()) 643 if options.dirs: 644 for directory in reversed(options.dirs): 645 add_dir_to_list(dir_list, directory) 646 647 def configure_compiler(self): 648 # Ensure that /usr/local is always used, but the local build 649 # directories (i.e. '.' and 'Include') must be first. See issue 650 # 10520. 651 if not CROSS_COMPILING: 652 add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') 653 add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') 654 # only change this for cross builds for 3.3, issues on Mageia 655 if CROSS_COMPILING: 656 self.add_cross_compiling_paths() 657 self.add_multiarch_paths() 658 self.add_ldflags_cppflags() 659 660 def init_inc_lib_dirs(self): 661 if (not CROSS_COMPILING and 662 os.path.normpath(sys.base_prefix) != '/usr' and 663 not sysconfig.get_config_var('PYTHONFRAMEWORK')): 664 # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework 665 # (PYTHONFRAMEWORK is set) to avoid # linking problems when 666 # building a framework with different architectures than 667 # the one that is currently installed (issue #7473) 668 add_dir_to_list(self.compiler.library_dirs, 669 sysconfig.get_config_var("LIBDIR")) 670 add_dir_to_list(self.compiler.include_dirs, 671 sysconfig.get_config_var("INCLUDEDIR")) 672 673 system_lib_dirs = ['/lib64', '/usr/lib64', '/lib', '/usr/lib'] 674 system_include_dirs = ['/usr/include'] 675 # lib_dirs and inc_dirs are used to search for files; 676 # if a file is found in one of those directories, it can 677 # be assumed that no additional -I,-L directives are needed. 678 if not CROSS_COMPILING: 679 self.lib_dirs = self.compiler.library_dirs + system_lib_dirs 680 self.inc_dirs = self.compiler.include_dirs + system_include_dirs 681 else: 682 # Add the sysroot paths. 'sysroot' is a compiler option used to 683 # set the logical path of the standard system headers and 684 # libraries. 685 self.lib_dirs = (self.compiler.library_dirs + 686 sysroot_paths(('LDFLAGS', 'CC'), system_lib_dirs)) 687 self.inc_dirs = (self.compiler.include_dirs + 688 sysroot_paths(('CPPFLAGS', 'CFLAGS', 'CC'), 689 system_include_dirs)) 690 691 config_h = sysconfig.get_config_h_filename() 692 with open(config_h) as file: 693 self.config_h_vars = sysconfig.parse_config_h(file) 694 695 # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb) 696 if HOST_PLATFORM in ['osf1', 'unixware7', 'openunix8']: 697 self.lib_dirs += ['/usr/ccs/lib'] 698 699 # HP-UX11iv3 keeps files in lib/hpux folders. 700 if HOST_PLATFORM == 'hp-ux11': 701 self.lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32'] 702 703 if MACOS: 704 # This should work on any unixy platform ;-) 705 # If the user has bothered specifying additional -I and -L flags 706 # in OPT and LDFLAGS we might as well use them here. 707 # 708 # NOTE: using shlex.split would technically be more correct, but 709 # also gives a bootstrap problem. Let's hope nobody uses 710 # directories with whitespace in the name to store libraries. 711 cflags, ldflags = sysconfig.get_config_vars( 712 'CFLAGS', 'LDFLAGS') 713 for item in cflags.split(): 714 if item.startswith('-I'): 715 self.inc_dirs.append(item[2:]) 716 717 for item in ldflags.split(): 718 if item.startswith('-L'): 719 self.lib_dirs.append(item[2:]) 720 721 def detect_simple_extensions(self): 722 # 723 # The following modules are all pretty straightforward, and compile 724 # on pretty much any POSIXish platform. 725 # 726 727 # array objects 728 self.add(Extension('array', ['arraymodule.c'])) 729 730 # Context Variables 731 self.add(Extension('_contextvars', ['_contextvarsmodule.c'])) 732 733 shared_math = 'Modules/_math.o' 734 735 # math library functions, e.g. sin() 736 self.add(Extension('math', ['mathmodule.c'], 737 extra_objects=[shared_math], 738 depends=['_math.h', shared_math], 739 libraries=['m'])) 740 741 # complex math library functions 742 self.add(Extension('cmath', ['cmathmodule.c'], 743 extra_objects=[shared_math], 744 depends=['_math.h', shared_math], 745 libraries=['m'])) 746 747 # time libraries: librt may be needed for clock_gettime() 748 time_libs = [] 749 lib = sysconfig.get_config_var('TIMEMODULE_LIB') 750 if lib: 751 time_libs.append(lib) 752 753 # time operations and variables 754 self.add(Extension('time', ['timemodule.c'], 755 libraries=time_libs)) 756 # libm is needed by delta_new() that uses round() and by accum() that 757 # uses modf(). 758 self.add(Extension('_datetime', ['_datetimemodule.c'], 759 libraries=['m'])) 760 # random number generator implemented in C 761 self.add(Extension("_random", ["_randommodule.c"])) 762 # bisect 763 self.add(Extension("_bisect", ["_bisectmodule.c"])) 764 # heapq 765 self.add(Extension("_heapq", ["_heapqmodule.c"])) 766 # C-optimized pickle replacement 767 self.add(Extension("_pickle", ["_pickle.c"], 768 extra_compile_args=['-DPy_BUILD_CORE_MODULE'])) 769 # atexit 770 self.add(Extension("atexit", ["atexitmodule.c"])) 771 # _json speedups 772 self.add(Extension("_json", ["_json.c"], 773 extra_compile_args=['-DPy_BUILD_CORE_MODULE'])) 774 775 # profiler (_lsprof is for cProfile.py) 776 self.add(Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c'])) 777 # static Unicode character database 778 self.add(Extension('unicodedata', ['unicodedata.c'], 779 depends=['unicodedata_db.h', 'unicodename_db.h'])) 780 # _opcode module 781 self.add(Extension('_opcode', ['_opcode.c'])) 782 # asyncio speedups 783 self.add(Extension("_asyncio", ["_asynciomodule.c"])) 784 # _abc speedups 785 self.add(Extension("_abc", ["_abc.c"])) 786 # _queue module 787 self.add(Extension("_queue", ["_queuemodule.c"])) 788 # _statistics module 789 self.add(Extension("_statistics", ["_statisticsmodule.c"])) 790 791 # Modules with some UNIX dependencies -- on by default: 792 # (If you have a really backward UNIX, select and socket may not be 793 # supported...) 794 795 # fcntl(2) and ioctl(2) 796 libs = [] 797 if (self.config_h_vars.get('FLOCK_NEEDS_LIBBSD', False)): 798 # May be necessary on AIX for flock function 799 libs = ['bsd'] 800 self.add(Extension('fcntl', ['fcntlmodule.c'], 801 libraries=libs)) 802 # pwd(3) 803 self.add(Extension('pwd', ['pwdmodule.c'])) 804 # grp(3) 805 if not VXWORKS: 806 self.add(Extension('grp', ['grpmodule.c'])) 807 # spwd, shadow passwords 808 if (self.config_h_vars.get('HAVE_GETSPNAM', False) or 809 self.config_h_vars.get('HAVE_GETSPENT', False)): 810 self.add(Extension('spwd', ['spwdmodule.c'])) 811 # AIX has shadow passwords, but access is not via getspent(), etc. 812 # module support is not expected so it not 'missing' 813 elif not AIX: 814 self.missing.append('spwd') 815 816 # select(2); not on ancient System V 817 self.add(Extension('select', ['selectmodule.c'])) 818 819 # Fred Drake's interface to the Python parser 820 self.add(Extension('parser', ['parsermodule.c'])) 821 822 # Memory-mapped files (also works on Win32). 823 self.add(Extension('mmap', ['mmapmodule.c'])) 824 825 # Lance Ellinghaus's syslog module 826 # syslog daemon interface 827 self.add(Extension('syslog', ['syslogmodule.c'])) 828 829 # Python interface to subinterpreter C-API. 830 self.add(Extension('_xxsubinterpreters', ['_xxsubinterpretersmodule.c'])) 831 832 # 833 # Here ends the simple stuff. From here on, modules need certain 834 # libraries, are platform-specific, or present other surprises. 835 # 836 837 # Multimedia modules 838 # These don't work for 64-bit platforms!!! 839 # These represent audio samples or images as strings: 840 # 841 # Operations on audio samples 842 # According to #993173, this one should actually work fine on 843 # 64-bit platforms. 844 # 845 # audioop needs libm for floor() in multiple functions. 846 self.add(Extension('audioop', ['audioop.c'], 847 libraries=['m'])) 848 849 # CSV files 850 self.add(Extension('_csv', ['_csv.c'])) 851 852 # POSIX subprocess module helper. 853 self.add(Extension('_posixsubprocess', ['_posixsubprocess.c'])) 854 855 def detect_test_extensions(self): 856 # Python C API test module 857 self.add(Extension('_testcapi', ['_testcapimodule.c'], 858 depends=['testcapi_long.h'])) 859 860 # Python Internal C API test module 861 self.add(Extension('_testinternalcapi', ['_testinternalcapi.c'], 862 extra_compile_args=['-DPy_BUILD_CORE_MODULE'])) 863 864 # Python PEP-3118 (buffer protocol) test module 865 self.add(Extension('_testbuffer', ['_testbuffer.c'])) 866 867 # Test loading multiple modules from one compiled file (http://bugs.python.org/issue16421) 868 self.add(Extension('_testimportmultiple', ['_testimportmultiple.c'])) 869 870 # Test multi-phase extension module init (PEP 489) 871 self.add(Extension('_testmultiphase', ['_testmultiphase.c'])) 872 873 # Fuzz tests. 874 self.add(Extension('_xxtestfuzz', 875 ['_xxtestfuzz/_xxtestfuzz.c', 876 '_xxtestfuzz/fuzzer.c'])) 877 878 def detect_readline_curses(self): 879 # readline 880 do_readline = self.compiler.find_library_file(self.lib_dirs, 'readline') 881 readline_termcap_library = "" 882 curses_library = "" 883 # Cannot use os.popen here in py3k. 884 tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') 885 if not os.path.exists(self.build_temp): 886 os.makedirs(self.build_temp) 887 # Determine if readline is already linked against curses or tinfo. 888 if do_readline: 889 if CROSS_COMPILING: 890 ret = os.system("%s -d %s | grep '(NEEDED)' > %s" \ 891 % (sysconfig.get_config_var('READELF'), 892 do_readline, tmpfile)) 893 elif find_executable('ldd'): 894 ret = os.system("ldd %s > %s" % (do_readline, tmpfile)) 895 else: 896 ret = 256 897 if ret >> 8 == 0: 898 with open(tmpfile) as fp: 899 for ln in fp: 900 if 'curses' in ln: 901 readline_termcap_library = re.sub( 902 r'.*lib(n?cursesw?)\.so.*', r'\1', ln 903 ).rstrip() 904 break 905 # termcap interface split out from ncurses 906 if 'tinfo' in ln: 907 readline_termcap_library = 'tinfo' 908 break 909 if os.path.exists(tmpfile): 910 os.unlink(tmpfile) 911 # Issue 7384: If readline is already linked against curses, 912 # use the same library for the readline and curses modules. 913 if 'curses' in readline_termcap_library: 914 curses_library = readline_termcap_library 915 elif self.compiler.find_library_file(self.lib_dirs, 'ncursesw'): 916 curses_library = 'ncursesw' 917 # Issue 36210: OSS provided ncurses does not link on AIX 918 # Use IBM supplied 'curses' for successful build of _curses 919 elif AIX and self.compiler.find_library_file(self.lib_dirs, 'curses'): 920 curses_library = 'curses' 921 elif self.compiler.find_library_file(self.lib_dirs, 'ncurses'): 922 curses_library = 'ncurses' 923 elif self.compiler.find_library_file(self.lib_dirs, 'curses'): 924 curses_library = 'curses' 925 926 if MACOS: 927 os_release = int(os.uname()[2].split('.')[0]) 928 dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') 929 if (dep_target and 930 (tuple(int(n) for n in dep_target.split('.')[0:2]) 931 < (10, 5) ) ): 932 os_release = 8 933 if os_release < 9: 934 # MacOSX 10.4 has a broken readline. Don't try to build 935 # the readline module unless the user has installed a fixed 936 # readline package 937 if find_file('readline/rlconf.h', self.inc_dirs, []) is None: 938 do_readline = False 939 if do_readline: 940 if MACOS and os_release < 9: 941 # In every directory on the search path search for a dynamic 942 # library and then a static library, instead of first looking 943 # for dynamic libraries on the entire path. 944 # This way a statically linked custom readline gets picked up 945 # before the (possibly broken) dynamic library in /usr/lib. 946 readline_extra_link_args = ('-Wl,-search_paths_first',) 947 else: 948 readline_extra_link_args = () 949 950 readline_libs = ['readline'] 951 if readline_termcap_library: 952 pass # Issue 7384: Already linked against curses or tinfo. 953 elif curses_library: 954 readline_libs.append(curses_library) 955 elif self.compiler.find_library_file(self.lib_dirs + 956 ['/usr/lib/termcap'], 957 'termcap'): 958 readline_libs.append('termcap') 959 self.add(Extension('readline', ['readline.c'], 960 library_dirs=['/usr/lib/termcap'], 961 extra_link_args=readline_extra_link_args, 962 libraries=readline_libs)) 963 else: 964 self.missing.append('readline') 965 966 # Curses support, requiring the System V version of curses, often 967 # provided by the ncurses library. 968 curses_defines = [] 969 curses_includes = [] 970 panel_library = 'panel' 971 if curses_library == 'ncursesw': 972 curses_defines.append(('HAVE_NCURSESW', '1')) 973 if not CROSS_COMPILING: 974 curses_includes.append('/usr/include/ncursesw') 975 # Bug 1464056: If _curses.so links with ncursesw, 976 # _curses_panel.so must link with panelw. 977 panel_library = 'panelw' 978 if MACOS: 979 # On OS X, there is no separate /usr/lib/libncursesw nor 980 # libpanelw. If we are here, we found a locally-supplied 981 # version of libncursesw. There should also be a 982 # libpanelw. _XOPEN_SOURCE defines are usually excluded 983 # for OS X but we need _XOPEN_SOURCE_EXTENDED here for 984 # ncurses wide char support 985 curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1')) 986 elif MACOS and curses_library == 'ncurses': 987 # Building with the system-suppied combined libncurses/libpanel 988 curses_defines.append(('HAVE_NCURSESW', '1')) 989 curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1')) 990 991 curses_enabled = True 992 if curses_library.startswith('ncurses'): 993 curses_libs = [curses_library] 994 self.add(Extension('_curses', ['_cursesmodule.c'], 995 include_dirs=curses_includes, 996 define_macros=curses_defines, 997 libraries=curses_libs)) 998 elif curses_library == 'curses' and not MACOS: 999 # OSX has an old Berkeley curses, not good enough for 1000 # the _curses module. 1001 if (self.compiler.find_library_file(self.lib_dirs, 'terminfo')): 1002 curses_libs = ['curses', 'terminfo'] 1003 elif (self.compiler.find_library_file(self.lib_dirs, 'termcap')): 1004 curses_libs = ['curses', 'termcap'] 1005 else: 1006 curses_libs = ['curses'] 1007 1008 self.add(Extension('_curses', ['_cursesmodule.c'], 1009 define_macros=curses_defines, 1010 libraries=curses_libs)) 1011 else: 1012 curses_enabled = False 1013 self.missing.append('_curses') 1014 1015 # If the curses module is enabled, check for the panel module 1016 # _curses_panel needs some form of ncurses 1017 skip_curses_panel = True if AIX else False 1018 if (curses_enabled and not skip_curses_panel and 1019 self.compiler.find_library_file(self.lib_dirs, panel_library)): 1020 self.add(Extension('_curses_panel', ['_curses_panel.c'], 1021 include_dirs=curses_includes, 1022 define_macros=curses_defines, 1023 libraries=[panel_library, *curses_libs])) 1024 elif not skip_curses_panel: 1025 self.missing.append('_curses_panel') 1026 1027 def detect_crypt(self): 1028 # crypt module. 1029 if VXWORKS: 1030 # bpo-31904: crypt() function is not provided by VxWorks. 1031 # DES_crypt() OpenSSL provides is too weak to implement 1032 # the encryption. 1033 return 1034 1035 if self.compiler.find_library_file(self.lib_dirs, 'crypt'): 1036 libs = ['crypt'] 1037 else: 1038 libs = [] 1039 1040 self.add(Extension('_crypt', ['_cryptmodule.c'], 1041 libraries=libs)) 1042 1043 def detect_socket(self): 1044 # socket(2) 1045 if not VXWORKS: 1046 self.add(Extension('_socket', ['socketmodule.c'], 1047 depends=['socketmodule.h'])) 1048 elif self.compiler.find_library_file(self.lib_dirs, 'net'): 1049 libs = ['net'] 1050 self.add(Extension('_socket', ['socketmodule.c'], 1051 depends=['socketmodule.h'], 1052 libraries=libs)) 1053 1054 def detect_dbm_gdbm(self): 1055 # Modules that provide persistent dictionary-like semantics. You will 1056 # probably want to arrange for at least one of them to be available on 1057 # your machine, though none are defined by default because of library 1058 # dependencies. The Python module dbm/__init__.py provides an 1059 # implementation independent wrapper for these; dbm/dumb.py provides 1060 # similar functionality (but slower of course) implemented in Python. 1061 1062 # Sleepycat^WOracle Berkeley DB interface. 1063 # http://www.oracle.com/database/berkeley-db/db/index.html 1064 # 1065 # This requires the Sleepycat^WOracle DB code. The supported versions 1066 # are set below. Visit the URL above to download 1067 # a release. Most open source OSes come with one or more 1068 # versions of BerkeleyDB already installed. 1069 1070 max_db_ver = (5, 3) 1071 min_db_ver = (3, 3) 1072 db_setup_debug = False # verbose debug prints from this script? 1073 1074 def allow_db_ver(db_ver): 1075 """Returns a boolean if the given BerkeleyDB version is acceptable. 1076 1077 Args: 1078 db_ver: A tuple of the version to verify. 1079 """ 1080 if not (min_db_ver <= db_ver <= max_db_ver): 1081 return False 1082 return True 1083 1084 def gen_db_minor_ver_nums(major): 1085 if major == 4: 1086 for x in range(max_db_ver[1]+1): 1087 if allow_db_ver((4, x)): 1088 yield x 1089 elif major == 3: 1090 for x in (3,): 1091 if allow_db_ver((3, x)): 1092 yield x 1093 else: 1094 raise ValueError("unknown major BerkeleyDB version", major) 1095 1096 # construct a list of paths to look for the header file in on 1097 # top of the normal inc_dirs. 1098 db_inc_paths = [ 1099 '/usr/include/db4', 1100 '/usr/local/include/db4', 1101 '/opt/sfw/include/db4', 1102 '/usr/include/db3', 1103 '/usr/local/include/db3', 1104 '/opt/sfw/include/db3', 1105 # Fink defaults (http://fink.sourceforge.net/) 1106 '/sw/include/db4', 1107 '/sw/include/db3', 1108 ] 1109 # 4.x minor number specific paths 1110 for x in gen_db_minor_ver_nums(4): 1111 db_inc_paths.append('/usr/include/db4%d' % x) 1112 db_inc_paths.append('/usr/include/db4.%d' % x) 1113 db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x) 1114 db_inc_paths.append('/usr/local/include/db4%d' % x) 1115 db_inc_paths.append('/pkg/db-4.%d/include' % x) 1116 db_inc_paths.append('/opt/db-4.%d/include' % x) 1117 # MacPorts default (http://www.macports.org/) 1118 db_inc_paths.append('/opt/local/include/db4%d' % x) 1119 # 3.x minor number specific paths 1120 for x in gen_db_minor_ver_nums(3): 1121 db_inc_paths.append('/usr/include/db3%d' % x) 1122 db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x) 1123 db_inc_paths.append('/usr/local/include/db3%d' % x) 1124 db_inc_paths.append('/pkg/db-3.%d/include' % x) 1125 db_inc_paths.append('/opt/db-3.%d/include' % x) 1126 1127 if CROSS_COMPILING: 1128 db_inc_paths = [] 1129 1130 # Add some common subdirectories for Sleepycat DB to the list, 1131 # based on the standard include directories. This way DB3/4 gets 1132 # picked up when it is installed in a non-standard prefix and 1133 # the user has added that prefix into inc_dirs. 1134 std_variants = [] 1135 for dn in self.inc_dirs: 1136 std_variants.append(os.path.join(dn, 'db3')) 1137 std_variants.append(os.path.join(dn, 'db4')) 1138 for x in gen_db_minor_ver_nums(4): 1139 std_variants.append(os.path.join(dn, "db4%d"%x)) 1140 std_variants.append(os.path.join(dn, "db4.%d"%x)) 1141 for x in gen_db_minor_ver_nums(3): 1142 std_variants.append(os.path.join(dn, "db3%d"%x)) 1143 std_variants.append(os.path.join(dn, "db3.%d"%x)) 1144 1145 db_inc_paths = std_variants + db_inc_paths 1146 db_inc_paths = [p for p in db_inc_paths if os.path.exists(p)] 1147 1148 db_ver_inc_map = {} 1149 1150 if MACOS: 1151 sysroot = macosx_sdk_root() 1152 1153 class db_found(Exception): pass 1154 try: 1155 # See whether there is a Sleepycat header in the standard 1156 # search path. 1157 for d in self.inc_dirs + db_inc_paths: 1158 f = os.path.join(d, "db.h") 1159 if MACOS and is_macosx_sdk_path(d): 1160 f = os.path.join(sysroot, d[1:], "db.h") 1161 1162 if db_setup_debug: print("db: looking for db.h in", f) 1163 if os.path.exists(f): 1164 with open(f, 'rb') as file: 1165 f = file.read() 1166 m = re.search(br"#define\WDB_VERSION_MAJOR\W(\d+)", f) 1167 if m: 1168 db_major = int(m.group(1)) 1169 m = re.search(br"#define\WDB_VERSION_MINOR\W(\d+)", f) 1170 db_minor = int(m.group(1)) 1171 db_ver = (db_major, db_minor) 1172 1173 # Avoid 4.6 prior to 4.6.21 due to a BerkeleyDB bug 1174 if db_ver == (4, 6): 1175 m = re.search(br"#define\WDB_VERSION_PATCH\W(\d+)", f) 1176 db_patch = int(m.group(1)) 1177 if db_patch < 21: 1178 print("db.h:", db_ver, "patch", db_patch, 1179 "being ignored (4.6.x must be >= 4.6.21)") 1180 continue 1181 1182 if ( (db_ver not in db_ver_inc_map) and 1183 allow_db_ver(db_ver) ): 1184 # save the include directory with the db.h version 1185 # (first occurrence only) 1186 db_ver_inc_map[db_ver] = d 1187 if db_setup_debug: 1188 print("db.h: found", db_ver, "in", d) 1189 else: 1190 # we already found a header for this library version 1191 if db_setup_debug: print("db.h: ignoring", d) 1192 else: 1193 # ignore this header, it didn't contain a version number 1194 if db_setup_debug: 1195 print("db.h: no version number version in", d) 1196 1197 db_found_vers = list(db_ver_inc_map.keys()) 1198 db_found_vers.sort() 1199 1200 while db_found_vers: 1201 db_ver = db_found_vers.pop() 1202 db_incdir = db_ver_inc_map[db_ver] 1203 1204 # check lib directories parallel to the location of the header 1205 db_dirs_to_check = [ 1206 db_incdir.replace("include", 'lib64'), 1207 db_incdir.replace("include", 'lib'), 1208 ] 1209 1210 if not MACOS: 1211 db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check)) 1212 1213 else: 1214 # Same as other branch, but takes OSX SDK into account 1215 tmp = [] 1216 for dn in db_dirs_to_check: 1217 if is_macosx_sdk_path(dn): 1218 if os.path.isdir(os.path.join(sysroot, dn[1:])): 1219 tmp.append(dn) 1220 else: 1221 if os.path.isdir(dn): 1222 tmp.append(dn) 1223 db_dirs_to_check = tmp 1224 1225 db_dirs_to_check = tmp 1226 1227 # Look for a version specific db-X.Y before an ambiguous dbX 1228 # XXX should we -ever- look for a dbX name? Do any 1229 # systems really not name their library by version and 1230 # symlink to more general names? 1231 for dblib in (('db-%d.%d' % db_ver), 1232 ('db%d%d' % db_ver), 1233 ('db%d' % db_ver[0])): 1234 dblib_file = self.compiler.find_library_file( 1235 db_dirs_to_check + self.lib_dirs, dblib ) 1236 if dblib_file: 1237 dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ] 1238 raise db_found 1239 else: 1240 if db_setup_debug: print("db lib: ", dblib, "not found") 1241 1242 except db_found: 1243 if db_setup_debug: 1244 print("bsddb using BerkeleyDB lib:", db_ver, dblib) 1245 print("bsddb lib dir:", dblib_dir, " inc dir:", db_incdir) 1246 dblibs = [dblib] 1247 # Only add the found library and include directories if they aren't 1248 # already being searched. This avoids an explicit runtime library 1249 # dependency. 1250 if db_incdir in self.inc_dirs: 1251 db_incs = None 1252 else: 1253 db_incs = [db_incdir] 1254 if dblib_dir[0] in self.lib_dirs: 1255 dblib_dir = None 1256 else: 1257 if db_setup_debug: print("db: no appropriate library found") 1258 db_incs = None 1259 dblibs = [] 1260 dblib_dir = None 1261 1262 dbm_setup_debug = False # verbose debug prints from this script? 1263 dbm_order = ['gdbm'] 1264 # The standard Unix dbm module: 1265 if not CYGWIN: 1266 config_args = [arg.strip("'") 1267 for arg in sysconfig.get_config_var("CONFIG_ARGS").split()] 1268 dbm_args = [arg for arg in config_args 1269 if arg.startswith('--with-dbmliborder=')] 1270 if dbm_args: 1271 dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":") 1272 else: 1273 dbm_order = "ndbm:gdbm:bdb".split(":") 1274 dbmext = None 1275 for cand in dbm_order: 1276 if cand == "ndbm": 1277 if find_file("ndbm.h", self.inc_dirs, []) is not None: 1278 # Some systems have -lndbm, others have -lgdbm_compat, 1279 # others don't have either 1280 if self.compiler.find_library_file(self.lib_dirs, 1281 'ndbm'): 1282 ndbm_libs = ['ndbm'] 1283 elif self.compiler.find_library_file(self.lib_dirs, 1284 'gdbm_compat'): 1285 ndbm_libs = ['gdbm_compat'] 1286 else: 1287 ndbm_libs = [] 1288 if dbm_setup_debug: print("building dbm using ndbm") 1289 dbmext = Extension('_dbm', ['_dbmmodule.c'], 1290 define_macros=[ 1291 ('HAVE_NDBM_H',None), 1292 ], 1293 libraries=ndbm_libs) 1294 break 1295 1296 elif cand == "gdbm": 1297 if self.compiler.find_library_file(self.lib_dirs, 'gdbm'): 1298 gdbm_libs = ['gdbm'] 1299 if self.compiler.find_library_file(self.lib_dirs, 1300 'gdbm_compat'): 1301 gdbm_libs.append('gdbm_compat') 1302 if find_file("gdbm/ndbm.h", self.inc_dirs, []) is not None: 1303 if dbm_setup_debug: print("building dbm using gdbm") 1304 dbmext = Extension( 1305 '_dbm', ['_dbmmodule.c'], 1306 define_macros=[ 1307 ('HAVE_GDBM_NDBM_H', None), 1308 ], 1309 libraries = gdbm_libs) 1310 break 1311 if find_file("gdbm-ndbm.h", self.inc_dirs, []) is not None: 1312 if dbm_setup_debug: print("building dbm using gdbm") 1313 dbmext = Extension( 1314 '_dbm', ['_dbmmodule.c'], 1315 define_macros=[ 1316 ('HAVE_GDBM_DASH_NDBM_H', None), 1317 ], 1318 libraries = gdbm_libs) 1319 break 1320 elif cand == "bdb": 1321 if dblibs: 1322 if dbm_setup_debug: print("building dbm using bdb") 1323 dbmext = Extension('_dbm', ['_dbmmodule.c'], 1324 library_dirs=dblib_dir, 1325 runtime_library_dirs=dblib_dir, 1326 include_dirs=db_incs, 1327 define_macros=[ 1328 ('HAVE_BERKDB_H', None), 1329 ('DB_DBM_HSEARCH', None), 1330 ], 1331 libraries=dblibs) 1332 break 1333 if dbmext is not None: 1334 self.add(dbmext) 1335 else: 1336 self.missing.append('_dbm') 1337 1338 # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm: 1339 if ('gdbm' in dbm_order and 1340 self.compiler.find_library_file(self.lib_dirs, 'gdbm')): 1341 self.add(Extension('_gdbm', ['_gdbmmodule.c'], 1342 libraries=['gdbm'])) 1343 else: 1344 self.missing.append('_gdbm') 1345 1346 def detect_sqlite(self): 1347 # The sqlite interface 1348 sqlite_setup_debug = False # verbose debug prints from this script? 1349 1350 # We hunt for #define SQLITE_VERSION "n.n.n" 1351 # We need to find >= sqlite version 3.3.9, for sqlite3_prepare_v2 1352 sqlite_incdir = sqlite_libdir = None 1353 sqlite_inc_paths = [ '/usr/include', 1354 '/usr/include/sqlite', 1355 '/usr/include/sqlite3', 1356 '/usr/local/include', 1357 '/usr/local/include/sqlite', 1358 '/usr/local/include/sqlite3', 1359 ] 1360 if CROSS_COMPILING: 1361 sqlite_inc_paths = [] 1362 MIN_SQLITE_VERSION_NUMBER = (3, 7, 2) 1363 MIN_SQLITE_VERSION = ".".join([str(x) 1364 for x in MIN_SQLITE_VERSION_NUMBER]) 1365 1366 # Scan the default include directories before the SQLite specific 1367 # ones. This allows one to override the copy of sqlite on OSX, 1368 # where /usr/include contains an old version of sqlite. 1369 if MACOS: 1370 sysroot = macosx_sdk_root() 1371 1372 for d_ in self.inc_dirs + sqlite_inc_paths: 1373 d = d_ 1374 if MACOS and is_macosx_sdk_path(d): 1375 d = os.path.join(sysroot, d[1:]) 1376 1377 f = os.path.join(d, "sqlite3.h") 1378 if os.path.exists(f): 1379 if sqlite_setup_debug: print("sqlite: found %s"%f) 1380 with open(f) as file: 1381 incf = file.read() 1382 m = re.search( 1383 r'\s*.*#\s*.*define\s.*SQLITE_VERSION\W*"([\d\.]*)"', incf) 1384 if m: 1385 sqlite_version = m.group(1) 1386 sqlite_version_tuple = tuple([int(x) 1387 for x in sqlite_version.split(".")]) 1388 if sqlite_version_tuple >= MIN_SQLITE_VERSION_NUMBER: 1389 # we win! 1390 if sqlite_setup_debug: 1391 print("%s/sqlite3.h: version %s"%(d, sqlite_version)) 1392 sqlite_incdir = d 1393 break 1394 else: 1395 if sqlite_setup_debug: 1396 print("%s: version %s is too old, need >= %s"%(d, 1397 sqlite_version, MIN_SQLITE_VERSION)) 1398 elif sqlite_setup_debug: 1399 print("sqlite: %s had no SQLITE_VERSION"%(f,)) 1400 1401 if sqlite_incdir: 1402 sqlite_dirs_to_check = [ 1403 os.path.join(sqlite_incdir, '..', 'lib64'), 1404 os.path.join(sqlite_incdir, '..', 'lib'), 1405 os.path.join(sqlite_incdir, '..', '..', 'lib64'), 1406 os.path.join(sqlite_incdir, '..', '..', 'lib'), 1407 ] 1408 sqlite_libfile = self.compiler.find_library_file( 1409 sqlite_dirs_to_check + self.lib_dirs, 'sqlite3') 1410 if sqlite_libfile: 1411 sqlite_libdir = [os.path.abspath(os.path.dirname(sqlite_libfile))] 1412 1413 if sqlite_incdir and sqlite_libdir: 1414 sqlite_srcs = ['_sqlite/cache.c', 1415 '_sqlite/connection.c', 1416 '_sqlite/cursor.c', 1417 '_sqlite/microprotocols.c', 1418 '_sqlite/module.c', 1419 '_sqlite/prepare_protocol.c', 1420 '_sqlite/row.c', 1421 '_sqlite/statement.c', 1422 '_sqlite/util.c', ] 1423 1424 sqlite_defines = [] 1425 if not MS_WINDOWS: 1426 sqlite_defines.append(('MODULE_NAME', '"sqlite3"')) 1427 else: 1428 sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"')) 1429 1430 # Enable support for loadable extensions in the sqlite3 module 1431 # if --enable-loadable-sqlite-extensions configure option is used. 1432 if '--enable-loadable-sqlite-extensions' not in sysconfig.get_config_var("CONFIG_ARGS"): 1433 sqlite_defines.append(("SQLITE_OMIT_LOAD_EXTENSION", "1")) 1434 1435 if MACOS: 1436 # In every directory on the search path search for a dynamic 1437 # library and then a static library, instead of first looking 1438 # for dynamic libraries on the entire path. 1439 # This way a statically linked custom sqlite gets picked up 1440 # before the dynamic library in /usr/lib. 1441 sqlite_extra_link_args = ('-Wl,-search_paths_first',) 1442 else: 1443 sqlite_extra_link_args = () 1444 1445 include_dirs = ["Modules/_sqlite"] 1446 # Only include the directory where sqlite was found if it does 1447 # not already exist in set include directories, otherwise you 1448 # can end up with a bad search path order. 1449 if sqlite_incdir not in self.compiler.include_dirs: 1450 include_dirs.append(sqlite_incdir) 1451 # avoid a runtime library path for a system library dir 1452 if sqlite_libdir and sqlite_libdir[0] in self.lib_dirs: 1453 sqlite_libdir = None 1454 self.add(Extension('_sqlite3', sqlite_srcs, 1455 define_macros=sqlite_defines, 1456 include_dirs=include_dirs, 1457 library_dirs=sqlite_libdir, 1458 extra_link_args=sqlite_extra_link_args, 1459 libraries=["sqlite3",])) 1460 else: 1461 self.missing.append('_sqlite3') 1462 1463 def detect_platform_specific_exts(self): 1464 # Unix-only modules 1465 if not MS_WINDOWS: 1466 if not VXWORKS: 1467 # Steen Lumholt's termios module 1468 self.add(Extension('termios', ['termios.c'])) 1469 # Jeremy Hylton's rlimit interface 1470 self.add(Extension('resource', ['resource.c'])) 1471 else: 1472 self.missing.extend(['resource', 'termios']) 1473 1474 # Platform-specific libraries 1475 if HOST_PLATFORM.startswith(('linux', 'freebsd', 'gnukfreebsd')): 1476 self.add(Extension('ossaudiodev', ['ossaudiodev.c'])) 1477 elif not AIX: 1478 self.missing.append('ossaudiodev') 1479 1480 if MACOS: 1481 self.add(Extension('_scproxy', ['_scproxy.c'], 1482 extra_link_args=[ 1483 '-framework', 'SystemConfiguration', 1484 '-framework', 'CoreFoundation'])) 1485 1486 def detect_compress_exts(self): 1487 # Andrew Kuchling's zlib module. Note that some versions of zlib 1488 # 1.1.3 have security problems. See CERT Advisory CA-2002-07: 1489 # http://www.cert.org/advisories/CA-2002-07.html 1490 # 1491 # zlib 1.1.4 is fixed, but at least one vendor (RedHat) has decided to 1492 # patch its zlib 1.1.3 package instead of upgrading to 1.1.4. For 1493 # now, we still accept 1.1.3, because we think it's difficult to 1494 # exploit this in Python, and we'd rather make it RedHat's problem 1495 # than our problem <wink>. 1496 # 1497 # You can upgrade zlib to version 1.1.4 yourself by going to 1498 # http://www.gzip.org/zlib/ 1499 zlib_inc = find_file('zlib.h', [], self.inc_dirs) 1500 have_zlib = False 1501 if zlib_inc is not None: 1502 zlib_h = zlib_inc[0] + '/zlib.h' 1503 version = '"0.0.0"' 1504 version_req = '"1.1.3"' 1505 if MACOS and is_macosx_sdk_path(zlib_h): 1506 zlib_h = os.path.join(macosx_sdk_root(), zlib_h[1:]) 1507 with open(zlib_h) as fp: 1508 while 1: 1509 line = fp.readline() 1510 if not line: 1511 break 1512 if line.startswith('#define ZLIB_VERSION'): 1513 version = line.split()[2] 1514 break 1515 if version >= version_req: 1516 if (self.compiler.find_library_file(self.lib_dirs, 'z')): 1517 if MACOS: 1518 zlib_extra_link_args = ('-Wl,-search_paths_first',) 1519 else: 1520 zlib_extra_link_args = () 1521 self.add(Extension('zlib', ['zlibmodule.c'], 1522 libraries=['z'], 1523 extra_link_args=zlib_extra_link_args)) 1524 have_zlib = True 1525 else: 1526 self.missing.append('zlib') 1527 else: 1528 self.missing.append('zlib') 1529 else: 1530 self.missing.append('zlib') 1531 1532 # Helper module for various ascii-encoders. Uses zlib for an optimized 1533 # crc32 if we have it. Otherwise binascii uses its own. 1534 if have_zlib: 1535 extra_compile_args = ['-DUSE_ZLIB_CRC32'] 1536 libraries = ['z'] 1537 extra_link_args = zlib_extra_link_args 1538 else: 1539 extra_compile_args = [] 1540 libraries = [] 1541 extra_link_args = [] 1542 self.add(Extension('binascii', ['binascii.c'], 1543 extra_compile_args=extra_compile_args, 1544 libraries=libraries, 1545 extra_link_args=extra_link_args)) 1546 1547 # Gustavo Niemeyer's bz2 module. 1548 if (self.compiler.find_library_file(self.lib_dirs, 'bz2')): 1549 if MACOS: 1550 bz2_extra_link_args = ('-Wl,-search_paths_first',) 1551 else: 1552 bz2_extra_link_args = () 1553 self.add(Extension('_bz2', ['_bz2module.c'], 1554 libraries=['bz2'], 1555 extra_link_args=bz2_extra_link_args)) 1556 else: 1557 self.missing.append('_bz2') 1558 1559 # LZMA compression support. 1560 if self.compiler.find_library_file(self.lib_dirs, 'lzma'): 1561 self.add(Extension('_lzma', ['_lzmamodule.c'], 1562 libraries=['lzma'])) 1563 else: 1564 self.missing.append('_lzma') 1565 1566 def detect_expat_elementtree(self): 1567 # Interface to the Expat XML parser 1568 # 1569 # Expat was written by James Clark and is now maintained by a group of 1570 # developers on SourceForge; see www.libexpat.org for more information. 1571 # The pyexpat module was written by Paul Prescod after a prototype by 1572 # Jack Jansen. The Expat source is included in Modules/expat/. Usage 1573 # of a system shared libexpat.so is possible with --with-system-expat 1574 # configure option. 1575 # 1576 # More information on Expat can be found at www.libexpat.org. 1577 # 1578 if '--with-system-expat' in sysconfig.get_config_var("CONFIG_ARGS"): 1579 expat_inc = [] 1580 define_macros = [] 1581 extra_compile_args = [] 1582 expat_lib = ['expat'] 1583 expat_sources = [] 1584 expat_depends = [] 1585 else: 1586 expat_inc = [os.path.join(self.srcdir, 'Modules', 'expat')] 1587 define_macros = [ 1588 ('HAVE_EXPAT_CONFIG_H', '1'), 1589 # bpo-30947: Python uses best available entropy sources to 1590 # call XML_SetHashSalt(), expat entropy sources are not needed 1591 ('XML_POOR_ENTROPY', '1'), 1592 ] 1593 extra_compile_args = [] 1594 expat_lib = [] 1595 expat_sources = ['expat/xmlparse.c', 1596 'expat/xmlrole.c', 1597 'expat/xmltok.c'] 1598 expat_depends = ['expat/ascii.h', 1599 'expat/asciitab.h', 1600 'expat/expat.h', 1601 'expat/expat_config.h', 1602 'expat/expat_external.h', 1603 'expat/internal.h', 1604 'expat/latin1tab.h', 1605 'expat/utf8tab.h', 1606 'expat/xmlrole.h', 1607 'expat/xmltok.h', 1608 'expat/xmltok_impl.h' 1609 ] 1610 1611 cc = sysconfig.get_config_var('CC').split()[0] 1612 ret = os.system( 1613 '"%s" -Werror -Wno-unreachable-code -E -xc /dev/null >/dev/null 2>&1' % cc) 1614 if ret >> 8 == 0: 1615 extra_compile_args.append('-Wno-unreachable-code') 1616 1617 self.add(Extension('pyexpat', 1618 define_macros=define_macros, 1619 extra_compile_args=extra_compile_args, 1620 include_dirs=expat_inc, 1621 libraries=expat_lib, 1622 sources=['pyexpat.c'] + expat_sources, 1623 depends=expat_depends)) 1624 1625 # Fredrik Lundh's cElementTree module. Note that this also 1626 # uses expat (via the CAPI hook in pyexpat). 1627 1628 if os.path.isfile(os.path.join(self.srcdir, 'Modules', '_elementtree.c')): 1629 define_macros.append(('USE_PYEXPAT_CAPI', None)) 1630 self.add(Extension('_elementtree', 1631 define_macros=define_macros, 1632 include_dirs=expat_inc, 1633 libraries=expat_lib, 1634 sources=['_elementtree.c'], 1635 depends=['pyexpat.c', *expat_sources, 1636 *expat_depends])) 1637 else: 1638 self.missing.append('_elementtree') 1639 1640 def detect_multibytecodecs(self): 1641 # Hye-Shik Chang's CJKCodecs modules. 1642 self.add(Extension('_multibytecodec', 1643 ['cjkcodecs/multibytecodec.c'])) 1644 for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'): 1645 self.add(Extension('_codecs_%s' % loc, 1646 ['cjkcodecs/_codecs_%s.c' % loc])) 1647 1648 def detect_multiprocessing(self): 1649 # Richard Oudkerk's multiprocessing module 1650 if MS_WINDOWS: 1651 multiprocessing_srcs = ['_multiprocessing/multiprocessing.c', 1652 '_multiprocessing/semaphore.c'] 1653 1654 else: 1655 multiprocessing_srcs = ['_multiprocessing/multiprocessing.c'] 1656 if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not 1657 sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')): 1658 multiprocessing_srcs.append('_multiprocessing/semaphore.c') 1659 if (sysconfig.get_config_var('HAVE_SHM_OPEN') and 1660 sysconfig.get_config_var('HAVE_SHM_UNLINK')): 1661 posixshmem_srcs = ['_multiprocessing/posixshmem.c'] 1662 libs = [] 1663 if sysconfig.get_config_var('SHM_NEEDS_LIBRT'): 1664 # need to link with librt to get shm_open() 1665 libs.append('rt') 1666 self.add(Extension('_posixshmem', posixshmem_srcs, 1667 define_macros={}, 1668 libraries=libs, 1669 include_dirs=["Modules/_multiprocessing"])) 1670 1671 self.add(Extension('_multiprocessing', multiprocessing_srcs, 1672 include_dirs=["Modules/_multiprocessing"])) 1673 1674 def detect_uuid(self): 1675 # Build the _uuid module if possible 1676 uuid_incs = find_file("uuid.h", self.inc_dirs, ["/usr/include/uuid"]) 1677 if uuid_incs is not None: 1678 if self.compiler.find_library_file(self.lib_dirs, 'uuid'): 1679 uuid_libs = ['uuid'] 1680 else: 1681 uuid_libs = [] 1682 self.add(Extension('_uuid', ['_uuidmodule.c'], 1683 libraries=uuid_libs, 1684 include_dirs=uuid_incs)) 1685 else: 1686 self.missing.append('_uuid') 1687 1688 def detect_modules(self): 1689 self.configure_compiler() 1690 self.init_inc_lib_dirs() 1691 1692 self.detect_simple_extensions() 1693 if TEST_EXTENSIONS: 1694 self.detect_test_extensions() 1695 self.detect_readline_curses() 1696 self.detect_crypt() 1697 self.detect_socket() 1698 self.detect_openssl_hashlib() 1699 self.detect_hash_builtins() 1700 self.detect_dbm_gdbm() 1701 self.detect_sqlite() 1702 self.detect_platform_specific_exts() 1703 self.detect_nis() 1704 self.detect_compress_exts() 1705 self.detect_expat_elementtree() 1706 self.detect_multibytecodecs() 1707 self.detect_decimal() 1708 self.detect_ctypes() 1709 self.detect_multiprocessing() 1710 if not self.detect_tkinter(): 1711 self.missing.append('_tkinter') 1712 self.detect_uuid() 1713 1714## # Uncomment these lines if you want to play with xxmodule.c 1715## self.add(Extension('xx', ['xxmodule.c'])) 1716 1717 if 'd' not in sysconfig.get_config_var('ABIFLAGS'): 1718 self.add(Extension('xxlimited', ['xxlimited.c'], 1719 define_macros=[('Py_LIMITED_API', '0x03050000')])) 1720 1721 def detect_tkinter_explicitly(self): 1722 # Build _tkinter using explicit locations for Tcl/Tk. 1723 # 1724 # This is enabled when both arguments are given to ./configure: 1725 # 1726 # --with-tcltk-includes="-I/path/to/tclincludes \ 1727 # -I/path/to/tkincludes" 1728 # --with-tcltk-libs="-L/path/to/tcllibs -ltclm.n \ 1729 # -L/path/to/tklibs -ltkm.n" 1730 # 1731 # These values can also be specified or overridden via make: 1732 # make TCLTK_INCLUDES="..." TCLTK_LIBS="..." 1733 # 1734 # This can be useful for building and testing tkinter with multiple 1735 # versions of Tcl/Tk. Note that a build of Tk depends on a particular 1736 # build of Tcl so you need to specify both arguments and use care when 1737 # overriding. 1738 1739 # The _TCLTK variables are created in the Makefile sharedmods target. 1740 tcltk_includes = os.environ.get('_TCLTK_INCLUDES') 1741 tcltk_libs = os.environ.get('_TCLTK_LIBS') 1742 if not (tcltk_includes and tcltk_libs): 1743 # Resume default configuration search. 1744 return False 1745 1746 extra_compile_args = tcltk_includes.split() 1747 extra_link_args = tcltk_libs.split() 1748 self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], 1749 define_macros=[('WITH_APPINIT', 1)], 1750 extra_compile_args = extra_compile_args, 1751 extra_link_args = extra_link_args)) 1752 return True 1753 1754 def detect_tkinter_darwin(self): 1755 # The _tkinter module, using frameworks. Since frameworks are quite 1756 # different the UNIX search logic is not sharable. 1757 from os.path import join, exists 1758 framework_dirs = [ 1759 '/Library/Frameworks', 1760 '/System/Library/Frameworks/', 1761 join(os.getenv('HOME'), '/Library/Frameworks') 1762 ] 1763 1764 sysroot = macosx_sdk_root() 1765 1766 # Find the directory that contains the Tcl.framework and Tk.framework 1767 # bundles. 1768 # XXX distutils should support -F! 1769 for F in framework_dirs: 1770 # both Tcl.framework and Tk.framework should be present 1771 1772 1773 for fw in 'Tcl', 'Tk': 1774 if is_macosx_sdk_path(F): 1775 if not exists(join(sysroot, F[1:], fw + '.framework')): 1776 break 1777 else: 1778 if not exists(join(F, fw + '.framework')): 1779 break 1780 else: 1781 # ok, F is now directory with both frameworks. Continure 1782 # building 1783 break 1784 else: 1785 # Tk and Tcl frameworks not found. Normal "unix" tkinter search 1786 # will now resume. 1787 return False 1788 1789 # For 8.4a2, we must add -I options that point inside the Tcl and Tk 1790 # frameworks. In later release we should hopefully be able to pass 1791 # the -F option to gcc, which specifies a framework lookup path. 1792 # 1793 include_dirs = [ 1794 join(F, fw + '.framework', H) 1795 for fw in ('Tcl', 'Tk') 1796 for H in ('Headers', 'Versions/Current/PrivateHeaders') 1797 ] 1798 1799 # For 8.4a2, the X11 headers are not included. Rather than include a 1800 # complicated search, this is a hard-coded path. It could bail out 1801 # if X11 libs are not found... 1802 include_dirs.append('/usr/X11R6/include') 1803 frameworks = ['-framework', 'Tcl', '-framework', 'Tk'] 1804 1805 # All existing framework builds of Tcl/Tk don't support 64-bit 1806 # architectures. 1807 cflags = sysconfig.get_config_vars('CFLAGS')[0] 1808 archs = re.findall(r'-arch\s+(\w+)', cflags) 1809 1810 tmpfile = os.path.join(self.build_temp, 'tk.arch') 1811 if not os.path.exists(self.build_temp): 1812 os.makedirs(self.build_temp) 1813 1814 # Note: cannot use os.popen or subprocess here, that 1815 # requires extensions that are not available here. 1816 if is_macosx_sdk_path(F): 1817 os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile)) 1818 else: 1819 os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) 1820 1821 with open(tmpfile) as fp: 1822 detected_archs = [] 1823 for ln in fp: 1824 a = ln.split()[-1] 1825 if a in archs: 1826 detected_archs.append(ln.split()[-1]) 1827 os.unlink(tmpfile) 1828 1829 for a in detected_archs: 1830 frameworks.append('-arch') 1831 frameworks.append(a) 1832 1833 self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], 1834 define_macros=[('WITH_APPINIT', 1)], 1835 include_dirs=include_dirs, 1836 libraries=[], 1837 extra_compile_args=frameworks[2:], 1838 extra_link_args=frameworks)) 1839 return True 1840 1841 def detect_tkinter(self): 1842 # The _tkinter module. 1843 1844 # Check whether --with-tcltk-includes and --with-tcltk-libs were 1845 # configured or passed into the make target. If so, use these values 1846 # to build tkinter and bypass the searches for Tcl and TK in standard 1847 # locations. 1848 if self.detect_tkinter_explicitly(): 1849 return True 1850 1851 # Rather than complicate the code below, detecting and building 1852 # AquaTk is a separate method. Only one Tkinter will be built on 1853 # Darwin - either AquaTk, if it is found, or X11 based Tk. 1854 if (MACOS and self.detect_tkinter_darwin()): 1855 return True 1856 1857 # Assume we haven't found any of the libraries or include files 1858 # The versions with dots are used on Unix, and the versions without 1859 # dots on Windows, for detection by cygwin. 1860 tcllib = tklib = tcl_includes = tk_includes = None 1861 for version in ['8.6', '86', '8.5', '85', '8.4', '84', '8.3', '83', 1862 '8.2', '82', '8.1', '81', '8.0', '80']: 1863 tklib = self.compiler.find_library_file(self.lib_dirs, 1864 'tk' + version) 1865 tcllib = self.compiler.find_library_file(self.lib_dirs, 1866 'tcl' + version) 1867 if tklib and tcllib: 1868 # Exit the loop when we've found the Tcl/Tk libraries 1869 break 1870 1871 # Now check for the header files 1872 if tklib and tcllib: 1873 # Check for the include files on Debian and {Free,Open}BSD, where 1874 # they're put in /usr/include/{tcl,tk}X.Y 1875 dotversion = version 1876 if '.' not in dotversion and "bsd" in HOST_PLATFORM.lower(): 1877 # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a, 1878 # but the include subdirs are named like .../include/tcl8.3. 1879 dotversion = dotversion[:-1] + '.' + dotversion[-1] 1880 tcl_include_sub = [] 1881 tk_include_sub = [] 1882 for dir in self.inc_dirs: 1883 tcl_include_sub += [dir + os.sep + "tcl" + dotversion] 1884 tk_include_sub += [dir + os.sep + "tk" + dotversion] 1885 tk_include_sub += tcl_include_sub 1886 tcl_includes = find_file('tcl.h', self.inc_dirs, tcl_include_sub) 1887 tk_includes = find_file('tk.h', self.inc_dirs, tk_include_sub) 1888 1889 if (tcllib is None or tklib is None or 1890 tcl_includes is None or tk_includes is None): 1891 self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2) 1892 return False 1893 1894 # OK... everything seems to be present for Tcl/Tk. 1895 1896 include_dirs = [] 1897 libs = [] 1898 defs = [] 1899 added_lib_dirs = [] 1900 for dir in tcl_includes + tk_includes: 1901 if dir not in include_dirs: 1902 include_dirs.append(dir) 1903 1904 # Check for various platform-specific directories 1905 if HOST_PLATFORM == 'sunos5': 1906 include_dirs.append('/usr/openwin/include') 1907 added_lib_dirs.append('/usr/openwin/lib') 1908 elif os.path.exists('/usr/X11R6/include'): 1909 include_dirs.append('/usr/X11R6/include') 1910 added_lib_dirs.append('/usr/X11R6/lib64') 1911 added_lib_dirs.append('/usr/X11R6/lib') 1912 elif os.path.exists('/usr/X11R5/include'): 1913 include_dirs.append('/usr/X11R5/include') 1914 added_lib_dirs.append('/usr/X11R5/lib') 1915 else: 1916 # Assume default location for X11 1917 include_dirs.append('/usr/X11/include') 1918 added_lib_dirs.append('/usr/X11/lib') 1919 1920 # If Cygwin, then verify that X is installed before proceeding 1921 if CYGWIN: 1922 x11_inc = find_file('X11/Xlib.h', [], include_dirs) 1923 if x11_inc is None: 1924 return False 1925 1926 # Check for BLT extension 1927 if self.compiler.find_library_file(self.lib_dirs + added_lib_dirs, 1928 'BLT8.0'): 1929 defs.append( ('WITH_BLT', 1) ) 1930 libs.append('BLT8.0') 1931 elif self.compiler.find_library_file(self.lib_dirs + added_lib_dirs, 1932 'BLT'): 1933 defs.append( ('WITH_BLT', 1) ) 1934 libs.append('BLT') 1935 1936 # Add the Tcl/Tk libraries 1937 libs.append('tk'+ version) 1938 libs.append('tcl'+ version) 1939 1940 # Finally, link with the X11 libraries (not appropriate on cygwin) 1941 if not CYGWIN: 1942 libs.append('X11') 1943 1944 # XXX handle these, but how to detect? 1945 # *** Uncomment and edit for PIL (TkImaging) extension only: 1946 # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ 1947 # *** Uncomment and edit for TOGL extension only: 1948 # -DWITH_TOGL togl.c \ 1949 # *** Uncomment these for TOGL extension only: 1950 # -lGL -lGLU -lXext -lXmu \ 1951 1952 self.add(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], 1953 define_macros=[('WITH_APPINIT', 1)] + defs, 1954 include_dirs=include_dirs, 1955 libraries=libs, 1956 library_dirs=added_lib_dirs)) 1957 return True 1958 1959 def configure_ctypes_darwin(self, ext): 1960 # Darwin (OS X) uses preconfigured files, in 1961 # the Modules/_ctypes/libffi_osx directory. 1962 ffi_srcdir = os.path.abspath(os.path.join(self.srcdir, 'Modules', 1963 '_ctypes', 'libffi_osx')) 1964 sources = [os.path.join(ffi_srcdir, p) 1965 for p in ['ffi.c', 1966 'x86/darwin64.S', 1967 'x86/x86-darwin.S', 1968 'x86/x86-ffi_darwin.c', 1969 'x86/x86-ffi64.c', 1970 'powerpc/ppc-darwin.S', 1971 'powerpc/ppc-darwin_closure.S', 1972 'powerpc/ppc-ffi_darwin.c', 1973 'powerpc/ppc64-darwin_closure.S', 1974 ]] 1975 1976 # Add .S (preprocessed assembly) to C compiler source extensions. 1977 self.compiler.src_extensions.append('.S') 1978 1979 include_dirs = [os.path.join(ffi_srcdir, 'include'), 1980 os.path.join(ffi_srcdir, 'powerpc')] 1981 ext.include_dirs.extend(include_dirs) 1982 ext.sources.extend(sources) 1983 return True 1984 1985 def configure_ctypes(self, ext): 1986 if not self.use_system_libffi: 1987 if MACOS: 1988 return self.configure_ctypes_darwin(ext) 1989 print('INFO: Could not locate ffi libs and/or headers') 1990 return False 1991 return True 1992 1993 def detect_ctypes(self): 1994 # Thomas Heller's _ctypes module 1995 self.use_system_libffi = False 1996 include_dirs = [] 1997 extra_compile_args = [] 1998 extra_link_args = [] 1999 sources = ['_ctypes/_ctypes.c', 2000 '_ctypes/callbacks.c', 2001 '_ctypes/callproc.c', 2002 '_ctypes/stgdict.c', 2003 '_ctypes/cfield.c'] 2004 depends = ['_ctypes/ctypes.h'] 2005 2006 if MACOS: 2007 sources.append('_ctypes/malloc_closure.c') 2008 sources.append('_ctypes/darwin/dlfcn_simple.c') 2009 extra_compile_args.append('-DMACOSX') 2010 include_dirs.append('_ctypes/darwin') 2011 # XXX Is this still needed? 2012 # extra_link_args.extend(['-read_only_relocs', 'warning']) 2013 2014 elif HOST_PLATFORM == 'sunos5': 2015 # XXX This shouldn't be necessary; it appears that some 2016 # of the assembler code is non-PIC (i.e. it has relocations 2017 # when it shouldn't. The proper fix would be to rewrite 2018 # the assembler code to be PIC. 2019 # This only works with GCC; the Sun compiler likely refuses 2020 # this option. If you want to compile ctypes with the Sun 2021 # compiler, please research a proper solution, instead of 2022 # finding some -z option for the Sun compiler. 2023 extra_link_args.append('-mimpure-text') 2024 2025 elif HOST_PLATFORM.startswith('hp-ux'): 2026 extra_link_args.append('-fPIC') 2027 2028 ext = Extension('_ctypes', 2029 include_dirs=include_dirs, 2030 extra_compile_args=extra_compile_args, 2031 extra_link_args=extra_link_args, 2032 libraries=[], 2033 sources=sources, 2034 depends=depends) 2035 self.add(ext) 2036 if TEST_EXTENSIONS: 2037 # function my_sqrt() needs libm for sqrt() 2038 self.add(Extension('_ctypes_test', 2039 sources=['_ctypes/_ctypes_test.c'], 2040 libraries=['m'])) 2041 2042 ffi_inc_dirs = self.inc_dirs.copy() 2043 if MACOS: 2044 if '--with-system-ffi' not in sysconfig.get_config_var("CONFIG_ARGS"): 2045 return 2046 # OS X 10.5 comes with libffi.dylib; the include files are 2047 # in /usr/include/ffi 2048 ffi_inc_dirs.append('/usr/include/ffi') 2049 2050 ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")] 2051 if not ffi_inc or ffi_inc[0] == '': 2052 ffi_inc = find_file('ffi.h', [], ffi_inc_dirs) 2053 if ffi_inc is not None: 2054 ffi_h = ffi_inc[0] + '/ffi.h' 2055 if not os.path.exists(ffi_h): 2056 ffi_inc = None 2057 print('Header file {} does not exist'.format(ffi_h)) 2058 ffi_lib = None 2059 if ffi_inc is not None: 2060 for lib_name in ('ffi', 'ffi_pic'): 2061 if (self.compiler.find_library_file(self.lib_dirs, lib_name)): 2062 ffi_lib = lib_name 2063 break 2064 2065 if ffi_inc and ffi_lib: 2066 ext.include_dirs.extend(ffi_inc) 2067 ext.libraries.append(ffi_lib) 2068 self.use_system_libffi = True 2069 2070 if sysconfig.get_config_var('HAVE_LIBDL'): 2071 # for dlopen, see bpo-32647 2072 ext.libraries.append('dl') 2073 2074 def detect_decimal(self): 2075 # Stefan Krah's _decimal module 2076 extra_compile_args = [] 2077 undef_macros = [] 2078 if '--with-system-libmpdec' in sysconfig.get_config_var("CONFIG_ARGS"): 2079 include_dirs = [] 2080 libraries = [':libmpdec.so.2'] 2081 sources = ['_decimal/_decimal.c'] 2082 depends = ['_decimal/docstrings.h'] 2083 else: 2084 include_dirs = [os.path.abspath(os.path.join(self.srcdir, 2085 'Modules', 2086 '_decimal', 2087 'libmpdec'))] 2088 libraries = ['m'] 2089 sources = [ 2090 '_decimal/_decimal.c', 2091 '_decimal/libmpdec/basearith.c', 2092 '_decimal/libmpdec/constants.c', 2093 '_decimal/libmpdec/context.c', 2094 '_decimal/libmpdec/convolute.c', 2095 '_decimal/libmpdec/crt.c', 2096 '_decimal/libmpdec/difradix2.c', 2097 '_decimal/libmpdec/fnt.c', 2098 '_decimal/libmpdec/fourstep.c', 2099 '_decimal/libmpdec/io.c', 2100 '_decimal/libmpdec/memory.c', 2101 '_decimal/libmpdec/mpdecimal.c', 2102 '_decimal/libmpdec/numbertheory.c', 2103 '_decimal/libmpdec/sixstep.c', 2104 '_decimal/libmpdec/transpose.c', 2105 ] 2106 depends = [ 2107 '_decimal/docstrings.h', 2108 '_decimal/libmpdec/basearith.h', 2109 '_decimal/libmpdec/bits.h', 2110 '_decimal/libmpdec/constants.h', 2111 '_decimal/libmpdec/convolute.h', 2112 '_decimal/libmpdec/crt.h', 2113 '_decimal/libmpdec/difradix2.h', 2114 '_decimal/libmpdec/fnt.h', 2115 '_decimal/libmpdec/fourstep.h', 2116 '_decimal/libmpdec/io.h', 2117 '_decimal/libmpdec/mpalloc.h', 2118 '_decimal/libmpdec/mpdecimal.h', 2119 '_decimal/libmpdec/numbertheory.h', 2120 '_decimal/libmpdec/sixstep.h', 2121 '_decimal/libmpdec/transpose.h', 2122 '_decimal/libmpdec/typearith.h', 2123 '_decimal/libmpdec/umodarith.h', 2124 ] 2125 2126 config = { 2127 'x64': [('CONFIG_64','1'), ('ASM','1')], 2128 'uint128': [('CONFIG_64','1'), ('ANSI','1'), ('HAVE_UINT128_T','1')], 2129 'ansi64': [('CONFIG_64','1'), ('ANSI','1')], 2130 'ppro': [('CONFIG_32','1'), ('PPRO','1'), ('ASM','1')], 2131 'ansi32': [('CONFIG_32','1'), ('ANSI','1')], 2132 'ansi-legacy': [('CONFIG_32','1'), ('ANSI','1'), 2133 ('LEGACY_COMPILER','1')], 2134 'universal': [('UNIVERSAL','1')] 2135 } 2136 2137 cc = sysconfig.get_config_var('CC') 2138 sizeof_size_t = sysconfig.get_config_var('SIZEOF_SIZE_T') 2139 machine = os.environ.get('PYTHON_DECIMAL_WITH_MACHINE') 2140 2141 if machine: 2142 # Override automatic configuration to facilitate testing. 2143 define_macros = config[machine] 2144 elif MACOS: 2145 # Universal here means: build with the same options Python 2146 # was built with. 2147 define_macros = config['universal'] 2148 elif sizeof_size_t == 8: 2149 if sysconfig.get_config_var('HAVE_GCC_ASM_FOR_X64'): 2150 define_macros = config['x64'] 2151 elif sysconfig.get_config_var('HAVE_GCC_UINT128_T'): 2152 define_macros = config['uint128'] 2153 else: 2154 define_macros = config['ansi64'] 2155 elif sizeof_size_t == 4: 2156 ppro = sysconfig.get_config_var('HAVE_GCC_ASM_FOR_X87') 2157 if ppro and ('gcc' in cc or 'clang' in cc) and \ 2158 not 'sunos' in HOST_PLATFORM: 2159 # solaris: problems with register allocation. 2160 # icc >= 11.0 works as well. 2161 define_macros = config['ppro'] 2162 extra_compile_args.append('-Wno-unknown-pragmas') 2163 else: 2164 define_macros = config['ansi32'] 2165 else: 2166 raise DistutilsError("_decimal: unsupported architecture") 2167 2168 # Workarounds for toolchain bugs: 2169 if sysconfig.get_config_var('HAVE_IPA_PURE_CONST_BUG'): 2170 # Some versions of gcc miscompile inline asm: 2171 # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46491 2172 # http://gcc.gnu.org/ml/gcc/2010-11/msg00366.html 2173 extra_compile_args.append('-fno-ipa-pure-const') 2174 if sysconfig.get_config_var('HAVE_GLIBC_MEMMOVE_BUG'): 2175 # _FORTIFY_SOURCE wrappers for memmove and bcopy are incorrect: 2176 # http://sourceware.org/ml/libc-alpha/2010-12/msg00009.html 2177 undef_macros.append('_FORTIFY_SOURCE') 2178 2179 # Uncomment for extra functionality: 2180 #define_macros.append(('EXTRA_FUNCTIONALITY', 1)) 2181 self.add(Extension('_decimal', 2182 include_dirs=include_dirs, 2183 libraries=libraries, 2184 define_macros=define_macros, 2185 undef_macros=undef_macros, 2186 extra_compile_args=extra_compile_args, 2187 sources=sources, 2188 depends=depends)) 2189 2190 def detect_openssl_hashlib(self): 2191 # Detect SSL support for the socket module (via _ssl) 2192 config_vars = sysconfig.get_config_vars() 2193 2194 def split_var(name, sep): 2195 # poor man's shlex, the re module is not available yet. 2196 value = config_vars.get(name) 2197 if not value: 2198 return () 2199 # This trick works because ax_check_openssl uses --libs-only-L, 2200 # --libs-only-l, and --cflags-only-I. 2201 value = ' ' + value 2202 sep = ' ' + sep 2203 return [v.strip() for v in value.split(sep) if v.strip()] 2204 2205 openssl_includes = split_var('OPENSSL_INCLUDES', '-I') 2206 openssl_libdirs = split_var('OPENSSL_LDFLAGS', '-L') 2207 openssl_libs = split_var('OPENSSL_LIBS', '-l') 2208 if not openssl_libs: 2209 # libssl and libcrypto not found 2210 self.missing.extend(['_ssl', '_hashlib']) 2211 return None, None 2212 2213 # Find OpenSSL includes 2214 ssl_incs = find_file( 2215 'openssl/ssl.h', self.inc_dirs, openssl_includes 2216 ) 2217 if ssl_incs is None: 2218 self.missing.extend(['_ssl', '_hashlib']) 2219 return None, None 2220 2221 # OpenSSL 1.0.2 uses Kerberos for KRB5 ciphers 2222 krb5_h = find_file( 2223 'krb5.h', self.inc_dirs, 2224 ['/usr/kerberos/include'] 2225 ) 2226 if krb5_h: 2227 ssl_incs.extend(krb5_h) 2228 2229 if config_vars.get("HAVE_X509_VERIFY_PARAM_SET1_HOST"): 2230 self.add(Extension( 2231 '_ssl', ['_ssl.c'], 2232 include_dirs=openssl_includes, 2233 library_dirs=openssl_libdirs, 2234 libraries=openssl_libs, 2235 depends=['socketmodule.h', '_ssl/debughelpers.c']) 2236 ) 2237 else: 2238 self.missing.append('_ssl') 2239 2240 self.add(Extension('_hashlib', ['_hashopenssl.c'], 2241 depends=['hashlib.h'], 2242 include_dirs=openssl_includes, 2243 library_dirs=openssl_libdirs, 2244 libraries=openssl_libs)) 2245 2246 def detect_hash_builtins(self): 2247 # We always compile these even when OpenSSL is available (issue #14693). 2248 # It's harmless and the object code is tiny (40-50 KiB per module, 2249 # only loaded when actually used). 2250 self.add(Extension('_sha256', ['sha256module.c'], 2251 depends=['hashlib.h'])) 2252 self.add(Extension('_sha512', ['sha512module.c'], 2253 depends=['hashlib.h'])) 2254 self.add(Extension('_md5', ['md5module.c'], 2255 depends=['hashlib.h'])) 2256 self.add(Extension('_sha1', ['sha1module.c'], 2257 depends=['hashlib.h'])) 2258 2259 blake2_deps = glob(os.path.join(self.srcdir, 2260 'Modules/_blake2/impl/*')) 2261 blake2_deps.append('hashlib.h') 2262 2263 self.add(Extension('_blake2', 2264 ['_blake2/blake2module.c', 2265 '_blake2/blake2b_impl.c', 2266 '_blake2/blake2s_impl.c'], 2267 depends=blake2_deps)) 2268 2269 sha3_deps = glob(os.path.join(self.srcdir, 2270 'Modules/_sha3/kcp/*')) 2271 sha3_deps.append('hashlib.h') 2272 self.add(Extension('_sha3', 2273 ['_sha3/sha3module.c'], 2274 depends=sha3_deps)) 2275 2276 def detect_nis(self): 2277 if MS_WINDOWS or CYGWIN or HOST_PLATFORM == 'qnx6': 2278 self.missing.append('nis') 2279 return 2280 2281 libs = [] 2282 library_dirs = [] 2283 includes_dirs = [] 2284 2285 # bpo-32521: glibc has deprecated Sun RPC for some time. Fedora 28 2286 # moved headers and libraries to libtirpc and libnsl. The headers 2287 # are in tircp and nsl sub directories. 2288 rpcsvc_inc = find_file( 2289 'rpcsvc/yp_prot.h', self.inc_dirs, 2290 [os.path.join(inc_dir, 'nsl') for inc_dir in self.inc_dirs] 2291 ) 2292 rpc_inc = find_file( 2293 'rpc/rpc.h', self.inc_dirs, 2294 [os.path.join(inc_dir, 'tirpc') for inc_dir in self.inc_dirs] 2295 ) 2296 if rpcsvc_inc is None or rpc_inc is None: 2297 # not found 2298 self.missing.append('nis') 2299 return 2300 includes_dirs.extend(rpcsvc_inc) 2301 includes_dirs.extend(rpc_inc) 2302 2303 if self.compiler.find_library_file(self.lib_dirs, 'nsl'): 2304 libs.append('nsl') 2305 else: 2306 # libnsl-devel: check for libnsl in nsl/ subdirectory 2307 nsl_dirs = [os.path.join(lib_dir, 'nsl') for lib_dir in self.lib_dirs] 2308 libnsl = self.compiler.find_library_file(nsl_dirs, 'nsl') 2309 if libnsl is not None: 2310 library_dirs.append(os.path.dirname(libnsl)) 2311 libs.append('nsl') 2312 2313 if self.compiler.find_library_file(self.lib_dirs, 'tirpc'): 2314 libs.append('tirpc') 2315 2316 self.add(Extension('nis', ['nismodule.c'], 2317 libraries=libs, 2318 library_dirs=library_dirs, 2319 include_dirs=includes_dirs)) 2320 2321 2322class PyBuildInstall(install): 2323 # Suppress the warning about installation into the lib_dynload 2324 # directory, which is not in sys.path when running Python during 2325 # installation: 2326 def initialize_options (self): 2327 install.initialize_options(self) 2328 self.warn_dir=0 2329 2330 # Customize subcommands to not install an egg-info file for Python 2331 sub_commands = [('install_lib', install.has_lib), 2332 ('install_headers', install.has_headers), 2333 ('install_scripts', install.has_scripts), 2334 ('install_data', install.has_data)] 2335 2336 2337class PyBuildInstallLib(install_lib): 2338 # Do exactly what install_lib does but make sure correct access modes get 2339 # set on installed directories and files. All installed files with get 2340 # mode 644 unless they are a shared library in which case they will get 2341 # mode 755. All installed directories will get mode 755. 2342 2343 # this is works for EXT_SUFFIX too, which ends with SHLIB_SUFFIX 2344 shlib_suffix = sysconfig.get_config_var("SHLIB_SUFFIX") 2345 2346 def install(self): 2347 outfiles = install_lib.install(self) 2348 self.set_file_modes(outfiles, 0o644, 0o755) 2349 self.set_dir_modes(self.install_dir, 0o755) 2350 return outfiles 2351 2352 def set_file_modes(self, files, defaultMode, sharedLibMode): 2353 if not files: return 2354 2355 for filename in files: 2356 if os.path.islink(filename): continue 2357 mode = defaultMode 2358 if filename.endswith(self.shlib_suffix): mode = sharedLibMode 2359 log.info("changing mode of %s to %o", filename, mode) 2360 if not self.dry_run: os.chmod(filename, mode) 2361 2362 def set_dir_modes(self, dirname, mode): 2363 for dirpath, dirnames, fnames in os.walk(dirname): 2364 if os.path.islink(dirpath): 2365 continue 2366 log.info("changing mode of %s to %o", dirpath, mode) 2367 if not self.dry_run: os.chmod(dirpath, mode) 2368 2369 2370class PyBuildScripts(build_scripts): 2371 def copy_scripts(self): 2372 outfiles, updated_files = build_scripts.copy_scripts(self) 2373 fullversion = '-{0[0]}.{0[1]}'.format(sys.version_info) 2374 minoronly = '.{0[1]}'.format(sys.version_info) 2375 newoutfiles = [] 2376 newupdated_files = [] 2377 for filename in outfiles: 2378 if filename.endswith('2to3'): 2379 newfilename = filename + fullversion 2380 else: 2381 newfilename = filename + minoronly 2382 log.info('renaming %s to %s', filename, newfilename) 2383 os.rename(filename, newfilename) 2384 newoutfiles.append(newfilename) 2385 if filename in updated_files: 2386 newupdated_files.append(newfilename) 2387 return newoutfiles, newupdated_files 2388 2389 2390def main(): 2391 set_compiler_flags('CFLAGS', 'PY_CFLAGS_NODIST') 2392 set_compiler_flags('LDFLAGS', 'PY_LDFLAGS_NODIST') 2393 2394 class DummyProcess: 2395 """Hack for parallel build""" 2396 ProcessPoolExecutor = None 2397 2398 sys.modules['concurrent.futures.process'] = DummyProcess 2399 2400 # turn off warnings when deprecated modules are imported 2401 import warnings 2402 warnings.filterwarnings("ignore",category=DeprecationWarning) 2403 setup(# PyPI Metadata (PEP 301) 2404 name = "Python", 2405 version = sys.version.split()[0], 2406 url = "http://www.python.org/%d.%d" % sys.version_info[:2], 2407 maintainer = "Guido van Rossum and the Python community", 2408 maintainer_email = "python-dev@python.org", 2409 description = "A high-level object-oriented programming language", 2410 long_description = SUMMARY.strip(), 2411 license = "PSF license", 2412 classifiers = [x for x in CLASSIFIERS.split("\n") if x], 2413 platforms = ["Many"], 2414 2415 # Build info 2416 cmdclass = {'build_ext': PyBuildExt, 2417 'build_scripts': PyBuildScripts, 2418 'install': PyBuildInstall, 2419 'install_lib': PyBuildInstallLib}, 2420 # The struct module is defined here, because build_ext won't be 2421 # called unless there's at least one extension module defined. 2422 ext_modules=[Extension('_struct', ['_struct.c'])], 2423 2424 # If you change the scripts installed here, you also need to 2425 # check the PyBuildScripts command above, and change the links 2426 # created by the bininstall target in Makefile.pre.in 2427 scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3", 2428 "Tools/scripts/2to3"] 2429 ) 2430 2431# --install-platlib 2432if __name__ == '__main__': 2433 main() 2434