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