Attachment 'setup.py'

Download

   1 # Autodetecting setup.py script for building the Python extensions
   2 #
   3 
   4 __version__ = "$Revision: 60581 $"
   5 
   6 import sys, os, imp, re, optparse
   7 
   8 from distutils import log
   9 from distutils import sysconfig
  10 from distutils import text_file
  11 from distutils.errors import *
  12 from distutils.core import Extension, setup
  13 from distutils.command.build_ext import build_ext
  14 from distutils.command.install import install
  15 from distutils.command.install_lib import install_lib
  16 
  17 # This global variable is used to hold the list of modules to be disabled.
  18 disabled_module_list = []
  19 
  20 def add_dir_to_list(dirlist, dir):
  21     """Add the directory 'dir' to the list 'dirlist' (at the front) if
  22     1) 'dir' is not already in 'dirlist'
  23     2) 'dir' actually exists, and is a directory."""
  24     if dir is not None and os.path.isdir(dir) and dir not in dirlist:
  25         dirlist.insert(0, dir)
  26 
  27 def find_file(filename, std_dirs, paths):
  28     """Searches for the directory where a given file is located,
  29     and returns a possibly-empty list of additional directories, or None
  30     if the file couldn't be found at all.
  31 
  32     'filename' is the name of a file, such as readline.h or libcrypto.a.
  33     'std_dirs' is the list of standard system directories; if the
  34         file is found in one of them, no additional directives are needed.
  35     'paths' is a list of additional locations to check; if the file is
  36         found in one of them, the resulting list will contain the directory.
  37     """
  38 
  39     # Check the standard locations
  40     for dir in std_dirs:
  41         f = os.path.join(dir, filename)
  42         if os.path.exists(f): return []
  43 
  44     # Check the additional directories
  45     for dir in paths:
  46         f = os.path.join(dir, filename)
  47         if os.path.exists(f):
  48             return [dir]
  49 
  50     # Not found anywhere
  51     return None
  52 
  53 def find_library_file(compiler, libname, std_dirs, paths):
  54     result = compiler.find_library_file(std_dirs + paths, libname)
  55     if result is None:
  56         return None
  57 
  58     # Check whether the found file is in one of the standard directories
  59     dirname = os.path.dirname(result)
  60     for p in std_dirs:
  61         # Ensure path doesn't end with path separator
  62         p = p.rstrip(os.sep)
  63         if p == dirname:
  64             return [ ]
  65 
  66     # Otherwise, it must have been in one of the additional directories,
  67     # so we have to figure out which one.
  68     for p in paths:
  69         # Ensure path doesn't end with path separator
  70         p = p.rstrip(os.sep)
  71         if p == dirname:
  72             return [p]
  73     else:
  74         assert False, "Internal error: Path not found in std_dirs or paths"
  75 
  76 def module_enabled(extlist, modname):
  77     """Returns whether the module 'modname' is present in the list
  78     of extensions 'extlist'."""
  79     extlist = [ext for ext in extlist if ext.name == modname]
  80     return len(extlist)
  81 
  82 def find_module_file(module, dirlist):
  83     """Find a module in a set of possible folders. If it is not found
  84     return the unadorned filename"""
  85     list = find_file(module, [], dirlist)
  86     if not list:
  87         return module
  88     if len(list) > 1:
  89         log.info("WARNING: multiple copies of %s found"%module)
  90     return os.path.join(list[0], module)
  91 
  92 class PyBuildExt(build_ext):
  93 
  94     def build_extensions(self):
  95 
  96         # Detect which modules should be compiled
  97         self.detect_modules()
  98 
  99         # Remove modules that are present on the disabled list
 100         self.extensions = [ext for ext in self.extensions
 101                            if ext.name not in disabled_module_list]
 102 
 103         # Fix up the autodetected modules, prefixing all the source files
 104         # with Modules/ and adding Python's include directory to the path.
 105         (srcdir,) = sysconfig.get_config_vars('srcdir')
 106         if not srcdir:
 107             # Maybe running on Windows but not using CYGWIN?
 108             raise ValueError("No source directory; cannot proceed.")
 109 
 110         # Figure out the location of the source code for extension modules
 111         moddir = os.path.join(os.getcwd(), srcdir, 'Modules')
 112         moddir = os.path.normpath(moddir)
 113         srcdir, tail = os.path.split(moddir)
 114         srcdir = os.path.normpath(srcdir)
 115         moddir = os.path.normpath(moddir)
 116 
 117         moddirlist = [moddir]
 118         incdirlist = ['./Include']
 119 
 120         # Platform-dependent module source and include directories
 121         platform = self.get_platform()
 122         if platform in ('darwin', 'mac') and ("--disable-toolbox-glue" not in
 123             sysconfig.get_config_var("CONFIG_ARGS")):
 124             # Mac OS X also includes some mac-specific modules
 125             macmoddir = os.path.join(os.getcwd(), srcdir, 'Mac/Modules')
 126             moddirlist.append(macmoddir)
 127             incdirlist.append('./Mac/Include')
 128 
 129         alldirlist = moddirlist + incdirlist
 130 
 131         # Fix up the paths for scripts, too
 132         self.distribution.scripts = [os.path.join(srcdir, filename)
 133                                      for filename in self.distribution.scripts]
 134 
 135         for ext in self.extensions[:]:
 136             ext.sources = [ find_module_file(filename, moddirlist)
 137                             for filename in ext.sources ]
 138             if ext.depends is not None:
 139                 ext.depends = [find_module_file(filename, alldirlist)
 140                                for filename in ext.depends]
 141             ext.include_dirs.append( '.' ) # to get config.h
 142             for incdir in incdirlist:
 143                 ext.include_dirs.append( os.path.join(srcdir, incdir) )
 144 
 145             # If a module has already been built statically,
 146             # don't build it here
 147             if ext.name in sys.builtin_module_names:
 148                 self.extensions.remove(ext)
 149 
 150         if platform != 'mac':
 151             # Parse Modules/Setup and Modules/Setup.local to figure out which
 152             # modules are turned on in the file.
 153             remove_modules = []
 154             for filename in ('Modules/Setup', 'Modules/Setup.local'):
 155                 input = text_file.TextFile(filename, join_lines=1)
 156                 while 1:
 157                     line = input.readline()
 158                     if not line: break
 159                     line = line.split()
 160                     remove_modules.append(line[0])
 161                 input.close()
 162 
 163             for ext in self.extensions[:]:
 164                 if ext.name in remove_modules:
 165                     self.extensions.remove(ext)
 166 
 167         # When you run "make CC=altcc" or something similar, you really want
 168         # those environment variables passed into the setup.py phase.  Here's
 169         # a small set of useful ones.
 170         compiler = os.environ.get('CC')
 171         args = {}
 172         # unfortunately, distutils doesn't let us provide separate C and C++
 173         # compilers
 174         if compiler is not None:
 175             (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS')
 176             args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags
 177         self.compiler.set_executables(**args)
 178 
 179         build_ext.build_extensions(self)
 180 
 181     def build_extension(self, ext):
 182 
 183         if ext.name == '_ctypes':
 184             if not self.configure_ctypes(ext):
 185                 return
 186 
 187         try:
 188             build_ext.build_extension(self, ext)
 189             return
 190         except (CCompilerError, DistutilsError), why:
 191             self.announce('WARNING: building of extension "%s" failed: %s' %
 192                           (ext.name, sys.exc_info()[1]))
 193             return
 194         # Workaround for Mac OS X: The Carbon-based modules cannot be
 195         # reliably imported into a command-line Python
 196         if 'Carbon' in ext.extra_link_args:
 197             self.announce(
 198                 'WARNING: skipping import check for Carbon-based "%s"' %
 199                 ext.name)
 200             return
 201         # Workaround for Cygwin: Cygwin currently has fork issues when many
 202         # modules have been imported
 203         if self.get_platform() == 'cygwin':
 204             self.announce('WARNING: skipping import check for Cygwin-based "%s"'
 205                 % ext.name)
 206             return
 207         ext_filename = os.path.join(
 208             self.build_lib,
 209             self.get_ext_filename(self.get_ext_fullname(ext.name)))
 210         try:
 211             imp.load_dynamic(ext.name, ext_filename)
 212         except ImportError, why:
 213             self.announce('*** WARNING: renaming "%s" since importing it'
 214                           ' failed: %s' % (ext.name, why), level=3)
 215             assert not self.inplace
 216             basename, tail = os.path.splitext(ext_filename)
 217             newname = basename + "_failed" + tail
 218             if os.path.exists(newname):
 219                 os.remove(newname)
 220             os.rename(ext_filename, newname)
 221 
 222             # XXX -- This relies on a Vile HACK in
 223             # distutils.command.build_ext.build_extension().  The
 224             # _built_objects attribute is stored there strictly for
 225             # use here.
 226             # If there is a failure, _built_objects may not be there,
 227             # so catch the AttributeError and move on.
 228             try:
 229                 for filename in self._built_objects:
 230                     os.remove(filename)
 231             except AttributeError:
 232                 self.announce('unable to remove files (ignored)')
 233         except:
 234             exc_type, why, tb = sys.exc_info()
 235             self.announce('*** WARNING: importing extension "%s" '
 236                           'failed with %s: %s' % (ext.name, exc_type, why),
 237                           level=3)
 238 
 239     def get_platform(self):
 240         # Get value of sys.platform
 241         for platform in ['cygwin', 'beos', 'darwin', 'atheos', 'osf1']:
 242             if sys.platform.startswith(platform):
 243                 return platform
 244         return sys.platform
 245 
 246     def detect_modules(self):
 247         # Ensure that /usr/local is always used
 248         #add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
 249         #add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
 250 
 251         # Add paths specified in the environment variables LDFLAGS and
 252         # CPPFLAGS for header and library files.
 253         # We must get the values from the Makefile and not the environment
 254         # directly since an inconsistently reproducible issue comes up where
 255         # the environment variable is not set even though the value were passed
 256         # into configure and stored in the Makefile (issue found on OS X 10.3).
 257         for env_var, arg_name, dir_list in (
 258                 ('LDFLAGS', '-L', self.compiler.library_dirs),
 259                 ('CPPFLAGS', '-I', self.compiler.include_dirs)):
 260             env_val = sysconfig.get_config_var(env_var)
 261             if env_val:
 262                 # To prevent optparse from raising an exception about any
 263                 # options in env_val that is doesn't know about we strip out
 264                 # all double dashes and any dashes followed by a character
 265                 # that is not for the option we are dealing with.
 266                 #
 267                 # Please note that order of the regex is important!  We must
 268                 # strip out double-dashes first so that we don't end up with
 269                 # substituting "--Long" to "-Long" and thus lead to "ong" being
 270                 # used for a library directory.
 271                 env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1],
 272                                  ' ', env_val)
 273                 parser = optparse.OptionParser()
 274                 # Make sure that allowing args interspersed with options is
 275                 # allowed
 276                 parser.allow_interspersed_args = True
 277                 parser.error = lambda msg: None
 278                 parser.add_option(arg_name, dest="dirs", action="append")
 279                 options = parser.parse_args(env_val.split())[0]
 280                 if options.dirs:
 281                     for directory in reversed(options.dirs):
 282                         add_dir_to_list(dir_list, directory)
 283 
 284         if os.path.normpath(sys.prefix) != '/usr':
 285             add_dir_to_list(self.compiler.library_dirs,
 286                             sysconfig.get_config_var("LIBDIR"))
 287             add_dir_to_list(self.compiler.include_dirs,
 288                             sysconfig.get_config_var("INCLUDEDIR"))
 289 
 290         try:
 291             have_unicode = unicode
 292         except NameError:
 293             have_unicode = 0
 294 
 295         # lib_dirs and inc_dirs are used to search for files;
 296         # if a file is found in one of those directories, it can
 297         # be assumed that no additional -I,-L directives are needed.
 298         lib_dirs = self.compiler.library_dirs + [
 299             '/lib64', '/usr/lib64',
 300             '/lib', '/usr/lib',
 301             ]
 302         inc_dirs = self.compiler.include_dirs + ['/usr/include']
 303         exts = []
 304 
 305         config_h = sysconfig.get_config_h_filename()
 306         config_h_vars = sysconfig.parse_config_h(open(config_h))
 307 
 308         platform = self.get_platform()
 309         (srcdir,) = sysconfig.get_config_vars('srcdir')
 310 
 311         # Check for AtheOS which has libraries in non-standard locations
 312         if platform == 'atheos':
 313             lib_dirs += ['/system/libs', '/atheos/autolnk/lib']
 314             lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep)
 315             inc_dirs += ['/system/include', '/atheos/autolnk/include']
 316             inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep)
 317 
 318         # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb)
 319         if platform in ['osf1', 'unixware7', 'openunix8']:
 320             lib_dirs += ['/usr/ccs/lib']
 321 
 322         if platform == 'darwin':
 323             # This should work on any unixy platform ;-)
 324             # If the user has bothered specifying additional -I and -L flags
 325             # in OPT and LDFLAGS we might as well use them here.
 326             #   NOTE: using shlex.split would technically be more correct, but
 327             # also gives a bootstrap problem. Let's hope nobody uses directories
 328             # with whitespace in the name to store libraries.
 329             cflags, ldflags = sysconfig.get_config_vars(
 330                     'CFLAGS', 'LDFLAGS')
 331             for item in cflags.split():
 332                 if item.startswith('-I'):
 333                     inc_dirs.append(item[2:])
 334 
 335             for item in ldflags.split():
 336                 if item.startswith('-L'):
 337                     lib_dirs.append(item[2:])
 338 
 339         # Check for MacOS X, which doesn't need libm.a at all
 340         math_libs = ['m']
 341         if platform in ['darwin', 'beos', 'mac']:
 342             math_libs = []
 343 
 344         # XXX Omitted modules: gl, pure, dl, SGI-specific modules
 345 
 346         #
 347         # The following modules are all pretty straightforward, and compile
 348         # on pretty much any POSIXish platform.
 349         #
 350 
 351         # Some modules that are normally always on:
 352         exts.append( Extension('_weakref', ['_weakref.c']) )
 353 
 354         # array objects
 355         exts.append( Extension('array', ['arraymodule.c']) )
 356         # complex math library functions
 357         #exts.append( Extension('cmath', ['cmathmodule.c'],
 358          #                      libraries=math_libs) )
 359 
 360         # math library functions, e.g. sin()
 361         exts.append( Extension('math',  ['mathmodule.c'],
 362                                libraries=math_libs) )
 363         # fast string operations implemented in C
 364         exts.append( Extension('strop', ['stropmodule.c']) )
 365         # time operations and variables
 366         exts.append( Extension('time', ['timemodule.c'],
 367                                libraries=math_libs) )
 368         exts.append( Extension('datetime', ['datetimemodule.c', 'timemodule.c'],
 369                                libraries=math_libs) )
 370         # random number generator implemented in C
 371         exts.append( Extension("_random", ["_randommodule.c"]) )
 372         # fast iterator tools implemented in C
 373         exts.append( Extension("itertools", ["itertoolsmodule.c"]) )
 374         # high-performance collections
 375         exts.append( Extension("collections", ["collectionsmodule.c"]) )
 376         # bisect
 377         exts.append( Extension("_bisect", ["_bisectmodule.c"]) )
 378         # heapq
 379         exts.append( Extension("_heapq", ["_heapqmodule.c"]) )
 380         # operator.add() and similar goodies
 381         exts.append( Extension('operator', ['operator.c']) )
 382         # _functools
 383         exts.append( Extension("_functools", ["_functoolsmodule.c"]) )
 384         # Python C API test module
 385        # exts.append( Extension('_testcapi', ['_testcapimodule.c']) )
 386         # profilers (_lsprof is for cProfile.py)
 387         exts.append( Extension('_hotshot', ['_hotshot.c']) )
 388         exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) )
 389         # static Unicode character database
 390         if have_unicode:
 391             exts.append( Extension('unicodedata', ['unicodedata.c']) )
 392         # access to ISO C locale support
 393         data = open('pyconfig.h').read()
 394         m = re.search(r"#s*define\s+WITH_LIBINTL\s+1\s*", data)
 395         if m is not None:
 396             locale_libs = ['intl']
 397         else:
 398             locale_libs = []
 399         if platform == 'darwin':
 400             locale_extra_link_args = ['-framework', 'CoreFoundation']
 401         else:
 402             locale_extra_link_args = []
 403 
 404 
 405         exts.append( Extension('_locale', ['_localemodule.c'],
 406                                libraries=locale_libs,
 407                                extra_link_args=locale_extra_link_args) )
 408 
 409         # Modules with some UNIX dependencies -- on by default:
 410         # (If you have a really backward UNIX, select and socket may not be
 411         # supported...)
 412 
 413         # fcntl(2) and ioctl(2)
 414         exts.append( Extension('fcntl', ['fcntlmodule.c']) )
 415         #if platform not in ['mac']:
 416             # pwd(3)
 417           #  exts.append( Extension('pwd', ['pwdmodule.c']) )
 418             # grp(3)
 419            # exts.append( Extension('grp', ['grpmodule.c']) )
 420             # spwd, shadow passwords
 421            # if (config_h_vars.get('HAVE_GETSPNAM', False) or
 422              #       config_h_vars.get('HAVE_GETSPENT', False)):
 423             #    exts.append( Extension('spwd', ['spwdmodule.c']) )
 424         # select(2); not on ancient System V
 425         exts.append( Extension('select', ['selectmodule.c']) )
 426 
 427         # Helper module for various ascii-encoders
 428         exts.append( Extension('binascii', ['binascii.c']) )
 429 
 430         # Fred Drake's interface to the Python parser
 431         exts.append( Extension('parser', ['parsermodule.c']) )
 432 
 433         # cStringIO and cPickle
 434         exts.append( Extension('cStringIO', ['cStringIO.c']) )
 435         exts.append( Extension('cPickle', ['cPickle.c']) )
 436 
 437         # Memory-mapped files (also works on Win32).
 438         #if platform not in ['atheos', 'mac']:
 439            # exts.append( Extension('mmap', ['mmapmodule.c']) )
 440 
 441         # Lance Ellinghaus's syslog module
 442 #        if platform not in ['mac']:
 443 #            # syslog daemon interface
 444 #            exts.append( Extension('syslog', ['syslogmodule.c']) )
 445 #
 446 #        # George Neville-Neil's timing module:
 447 #        # Deprecated in PEP 4 http://www.python.org/peps/pep-0004.html
 448 #        # http://mail.python.org/pipermail/python-dev/2006-January/060023.html
 449 #        #exts.append( Extension('timing', ['timingmodule.c']) )
 450 #
 451 #        #
 452 #        # Here ends the simple stuff.  From here on, modules need certain
 453 #        # libraries, are platform-specific, or present other surprises.
 454 #        #
 455 #
 456 #        # Multimedia modules
 457 #        # These don't work for 64-bit platforms!!!
 458 #        # These represent audio samples or images as strings:
 459 #
 460 #        # Operations on audio samples
 461 #        # According to #993173, this one should actually work fine on
 462 #        # 64-bit platforms.
 463 #        #exts.append( Extension('audioop', ['audioop.c']) )
 464 #
 465 #        # Disabled on 64-bit platforms
 466 #        if sys.maxint != 9223372036854775807L:
 467 #            # Operations on images
 468 #         #   exts.append( Extension('imageop', ['imageop.c']) )
 469 #            # Read SGI RGB image files (but coded portably)
 470 #          #  exts.append( Extension('rgbimg', ['rgbimgmodule.c']) )
 471 #
 472 #        # readline
 473 #       # do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
 474 #        if platform == 'darwin':
 475 #            # MacOSX 10.4 has a broken readline. Don't try to build
 476 #            # the readline module unless the user has installed a fixed
 477 #            # readline package
 478 #            if find_file('readline/rlconf.h', inc_dirs, []) is None:
 479 #                do_readline = False
 480 #        if do_readline:
 481 #            if sys.platform == 'darwin':
 482 #                # In every directory on the search path search for a dynamic
 483 #                # library and then a static library, instead of first looking
 484 #                # for dynamic libraries on the entiry path.
 485 #                # This way a staticly linked custom readline gets picked up
 486 #                # before the (broken) dynamic library in /usr/lib.
 487 #                readline_extra_link_args = ('-Wl,-search_paths_first',)
 488 #            else:
 489 #                readline_extra_link_args = ()
 490 #
 491 #            readline_libs = ['readline']
 492 #            if self.compiler.find_library_file(lib_dirs,
 493 #                                                 'ncursesw'):
 494 #                readline_libs.append('ncursesw')
 495 #            elif self.compiler.find_library_file(lib_dirs,
 496 #                                                 'ncurses'):
 497 #                readline_libs.append('ncurses')
 498 #            elif self.compiler.find_library_file(lib_dirs, 'curses'):
 499 #                readline_libs.append('curses')
 500 #            elif self.compiler.find_library_file(lib_dirs +
 501 #                                               ['/usr/lib/termcap'],
 502 #                                               'termcap'):
 503 #                readline_libs.append('termcap')
 504 #            exts.append( Extension('readline', ['readline.c'],
 505 #                                   library_dirs=['/usr/lib/termcap'],
 506 #                                   extra_link_args=readline_extra_link_args,
 507 #                                   libraries=readline_libs) )
 508         if platform not in ['mac']:
 509             # crypt module.
 510 
 511             if self.compiler.find_library_file(lib_dirs, 'crypt'):
 512                 libs = ['crypt']
 513             else:
 514                 libs = []
 515             exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
 516 
 517         # CSV files
 518         exts.append( Extension('_csv', ['_csv.c']) )
 519 
 520         # socket(2)
 521         exts.append( Extension('_socket', ['socketmodule.c'],
 522                                depends = ['socketmodule.h']) )
 523 #        # Detect SSL support for the socket module (via _ssl)
 524 #        search_for_ssl_incs_in = [
 525 #                              '/usr/local/ssl/include',
 526 #                              '/usr/contrib/ssl/include/'
 527 #                             ]
 528 #       # ssl_incs = find_file('openssl/ssl.h', inc_dirs,
 529 #        #                     search_for_ssl_incs_in
 530 #        #                     )
 531 #        if ssl_incs is not None:
 532 #            krb5_h = find_file('krb5.h', inc_dirs,
 533 #                               ['/usr/kerberos/include'])
 534 #            if krb5_h:
 535 #                ssl_incs += krb5_h
 536 #        ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
 537 #                                     ['/usr/local/ssl/lib',
 538 #                                      '/usr/contrib/ssl/lib/'
 539 #                                     ] )
 540 #
 541 #        if (ssl_incs is not None and
 542 #            ssl_libs is not None):
 543 #            exts.append( Extension('_ssl', ['_ssl.c'],
 544 #                                   include_dirs = ssl_incs,
 545 #                                   library_dirs = ssl_libs,
 546 #                                   libraries = ['ssl', 'crypto'],
 547 #                                   depends = ['socketmodule.h']), )
 548 #
 549 #        # find out which version of OpenSSL we have
 550 #        openssl_ver = 0
 551 #       # openssl_ver_re = re.compile(
 552 #        #    '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
 553 #        for ssl_inc_dir in inc_dirs + search_for_ssl_incs_in:
 554 #            name = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h')
 555 #            if os.path.isfile(name):
 556 #                try:
 557 #                    incfile = open(name, 'r')
 558 #                    for line in incfile:
 559 #                        m = openssl_ver_re.match(line)
 560 #                        if m:
 561 #                            openssl_ver = eval(m.group(1))
 562 #                            break
 563 #                except IOError:
 564 #                    pass
 565 #
 566 #            # first version found is what we'll use (as the compiler should)
 567 #            if openssl_ver:
 568 #                break
 569 #
 570 #        #print 'openssl_ver = 0x%08x' % openssl_ver
 571 #
 572 #        if (ssl_incs is not None and
 573 #            ssl_libs is not None and
 574 #            openssl_ver >= 0x00907000):
 575 #            # The _hashlib module wraps optimized implementations
 576 #            # of hash functions from the OpenSSL library.
 577 #            exts.append( Extension('_hashlib', ['_hashopenssl.c'],
 578 #                                   include_dirs = ssl_incs,
 579 #                                   library_dirs = ssl_libs,
 580 #                                   libraries = ['ssl', 'crypto']) )
 581 #        else:
 582 #            # The _sha module implements the SHA1 hash algorithm.
 583 #            exts.append( Extension('_sha', ['shamodule.c']) )
 584 #            # The _md5 module implements the RSA Data Security, Inc. MD5
 585 #            # Message-Digest Algorithm, described in RFC 1321.  The
 586 #            # necessary files md5.c and md5.h are included here.
 587 #            exts.append( Extension('_md5',
 588 #                            sources = ['md5module.c', 'md5.c'],
 589 #                            depends = ['md5.h']) )
 590 #
 591 #        if (openssl_ver < 0x00908000):
 592 #            # OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash
 593 #            exts.append( Extension('_sha256', ['sha256module.c']) )
 594 #            exts.append( Extension('_sha512', ['sha512module.c']) )
 595 #
 596 
 597         # Modules that provide persistent dictionary-like semantics.  You will
 598         # probably want to arrange for at least one of them to be available on
 599         # your machine, though none are defined by default because of library
 600         # dependencies.  The Python module anydbm.py provides an
 601         # implementation independent wrapper for these; dumbdbm.py provides
 602         # similar functionality (but slower of course) implemented in Python.
 603 
 604         # Sleepycat^WOracle Berkeley DB interface.
 605         #  http://www.oracle.com/database/berkeley-db/db/index.html
 606         #
 607         # This requires the Sleepycat^WOracle DB code. The supported versions
 608         # are set below.  Visit the URL above to download
 609         # a release.  Most open source OSes come with one or more
 610         # versions of BerkeleyDB already installed.
 611 
 612 #        max_db_ver = (4, 5)
 613 #        # NOTE: while the _bsddb.c code links against BerkeleyDB 4.6.x
 614 #        # we leave that version disabled by default as it has proven to be
 615 #        # quite a buggy library release on many platforms.
 616 #        min_db_ver = (3, 3)
 617 #        db_setup_debug = False   # verbose debug prints from this script?
 618 #
 619 #        # construct a list of paths to look for the header file in on
 620 #        # top of the normal inc_dirs.
 621 #        db_inc_paths = [
 622 #            '/usr/include/db4',
 623 #            '/usr/local/include/db4',
 624 #            '/opt/sfw/include/db4',
 625 #            '/sw/include/db4',
 626 #            '/usr/include/db3',
 627 #            '/usr/local/include/db3',
 628 #            '/opt/sfw/include/db3',
 629 #            '/sw/include/db3',
 630 #        ]
 631 #        # 4.x minor number specific paths
 632 #        for x in range(max_db_ver[1]+1):
 633 #            db_inc_paths.append('/usr/include/db4%d' % x)
 634 #            db_inc_paths.append('/usr/include/db4.%d' % x)
 635 #            db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x)
 636 #            db_inc_paths.append('/usr/local/include/db4%d' % x)
 637 #            db_inc_paths.append('/pkg/db-4.%d/include' % x)
 638 #            db_inc_paths.append('/opt/db-4.%d/include' % x)
 639 #        # 3.x minor number specific paths
 640 #        for x in (3,):
 641 #            db_inc_paths.append('/usr/include/db3%d' % x)
 642 #            db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x)
 643 #            db_inc_paths.append('/usr/local/include/db3%d' % x)
 644 #            db_inc_paths.append('/pkg/db-3.%d/include' % x)
 645 #            db_inc_paths.append('/opt/db-3.%d/include' % x)
 646 #
 647 #        # Add some common subdirectories for Sleepycat DB to the list,
 648 #        # based on the standard include directories. This way DB3/4 gets
 649 #        # picked up when it is installed in a non-standard prefix and
 650 #        # the user has added that prefix into inc_dirs.
 651 #        std_variants = []
 652 #        for dn in inc_dirs:
 653 #            std_variants.append(os.path.join(dn, 'db3'))
 654 #            std_variants.append(os.path.join(dn, 'db4'))
 655 #            for x in range(max_db_ver[1]+1):
 656 #                std_variants.append(os.path.join(dn, "db4%d"%x))
 657 #                std_variants.append(os.path.join(dn, "db4.%d"%x))
 658 #            for x in (2,3):
 659 #                std_variants.append(os.path.join(dn, "db3%d"%x))
 660 #                std_variants.append(os.path.join(dn, "db3.%d"%x))
 661 #
 662 #        db_inc_paths = std_variants + db_inc_paths
 663 #
 664 #
 665 #        db_ver_inc_map = {}
 666 #
 667 #        class db_found(Exception): pass
 668 #        try:
 669 #            # See whether there is a Sleepycat header in the standard
 670 #            # search path.
 671 #            for d in inc_dirs + db_inc_paths:
 672 #                f = os.path.join(d, "db.h")
 673 #                if db_setup_debug: print "db: looking for db.h in", f
 674 #                if os.path.exists(f):
 675 #                    f = open(f).read()
 676 #                    m = re.search(r"#define\WDB_VERSION_MAJOR\W(\d+)", f)
 677 #                    if m:
 678 #                        db_major = int(m.group(1))
 679 #                        m = re.search(r"#define\WDB_VERSION_MINOR\W(\d+)", f)
 680 #                        db_minor = int(m.group(1))
 681 #                        db_ver = (db_major, db_minor)
 682 #
 683 #                        # Avoid 4.6 prior to 4.6.21 due to a BerkeleyDB bug
 684 #                        if db_ver == (4, 6):
 685 #                            m = re.search(r"#define\WDB_VERSION_PATCH\W(\d+)", f)
 686 #                            db_patch = int(m.group(1))
 687 #                            if db_patch < 21:
 688 #                                print "db.h:", db_ver, "patch", db_patch,
 689 #                                print "being ignored (4.6.x must be >= 4.6.21)"
 690 #                                continue
 691 #
 692 #                        if ( (not db_ver_inc_map.has_key(db_ver)) and
 693 #                           (db_ver <= max_db_ver and db_ver >= min_db_ver) ):
 694 #                            # save the include directory with the db.h version
 695 #                            # (first occurrance only)
 696 #                            db_ver_inc_map[db_ver] = d
 697 #                            print "db.h: found", db_ver, "in", d
 698 #                        else:
 699 #                            # we already found a header for this library version
 700 #                            if db_setup_debug: print "db.h: ignoring", d
 701 #                    else:
 702 #                        # ignore this header, it didn't contain a version number
 703 #                        if db_setup_debug: print "db.h: unsupported version", db_ver, "in", d
 704 #
 705 #            db_found_vers = db_ver_inc_map.keys()
 706 #            db_found_vers.sort()
 707 #
 708 #            while db_found_vers:
 709 #                db_ver = db_found_vers.pop()
 710 #                db_incdir = db_ver_inc_map[db_ver]
 711 #
 712 #                # check lib directories parallel to the location of the header
 713 #                db_dirs_to_check = [
 714 #                    os.path.join(db_incdir, '..', 'lib64'),
 715 #                    os.path.join(db_incdir, '..', 'lib'),
 716 #                    os.path.join(db_incdir, '..', '..', 'lib64'),
 717 #                    os.path.join(db_incdir, '..', '..', 'lib'),
 718 #                ]
 719 #                db_dirs_to_check = filter(os.path.isdir, db_dirs_to_check)
 720 #
 721 #                # Look for a version specific db-X.Y before an ambiguoius dbX
 722 #                # XXX should we -ever- look for a dbX name?  Do any
 723 #                # systems really not name their library by version and
 724 #                # symlink to more general names?
 725 #                for dblib in (('db-%d.%d' % db_ver),
 726 #                              ('db%d%d' % db_ver),
 727 #                              ('db%d' % db_ver[0])):
 728 #                    dblib_file = self.compiler.find_library_file(
 729 #                                    db_dirs_to_check + lib_dirs, dblib )
 730 #                    if dblib_file:
 731 #                        dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ]
 732 #                        raise db_found
 733 #                    else:
 734 #                        if db_setup_debug: print "db lib: ", dblib, "not found"
 735 #
 736 #        except db_found:
 737 #            print "db lib: using", db_ver, dblib
 738 #            if db_setup_debug: print "db: lib dir", dblib_dir, "inc dir", db_incdir
 739 #            db_incs = [db_incdir]
 740 #            dblibs = [dblib]
 741 #            # We add the runtime_library_dirs argument because the
 742 #            # BerkeleyDB lib we're linking against often isn't in the
 743 #            # system dynamic library search path.  This is usually
 744 #            # correct and most trouble free, but may cause problems in
 745 #            # some unusual system configurations (e.g. the directory
 746 #            # is on an NFS server that goes away).
 747 #            exts.append(Extension('_bsddb', ['_bsddb.c'],
 748 #                                  library_dirs=dblib_dir,
 749 #                                  runtime_library_dirs=dblib_dir,
 750 #                                  include_dirs=db_incs,
 751 #                                  libraries=dblibs))
 752 #        else:
 753 #            if db_setup_debug: print "db: no appropriate library found"
 754 #            db_incs = None
 755 #            dblibs = []
 756 #            dblib_dir = None
 757 #
 758         # The sqlite interface
 759         sqlite_setup_debug = False # verbose debug prints from this script?
 760 
 761         # We hunt for #define SQLITE_VERSION "n.n.n"
 762         # We need to find >= sqlite version 3.0.8
 763         sqlite_incdir = sqlite_libdir = None
 764         sqlite_inc_paths = [ '/usr/include',
 765                              '/usr/include/sqlite',
 766                              '/usr/include/sqlite3',
 767                              '/usr/local/include',
 768                              '/usr/local/include/sqlite',
 769                              '/usr/local/include/sqlite3',
 770                            ]
 771         MIN_SQLITE_VERSION_NUMBER = (3, 0, 8)
 772         MIN_SQLITE_VERSION = ".".join([str(x)
 773                                     for x in MIN_SQLITE_VERSION_NUMBER])
 774 
 775         # Scan the default include directories before the SQLite specific
 776         # ones. This allows one to override the copy of sqlite on OSX,
 777         # where /usr/include contains an old version of sqlite.
 778         for d in inc_dirs + sqlite_inc_paths:
 779             f = os.path.join(d, "sqlite3.h")
 780             if os.path.exists(f):
 781                 if sqlite_setup_debug: print "sqlite: found %s"%f
 782                 incf = open(f).read()
 783                 m = re.search(
 784                     r'\s*.*#\s*.*define\s.*SQLITE_VERSION\W*"(.*)"', incf)
 785                 if m:
 786                     sqlite_version = m.group(1)
 787                     sqlite_version_tuple = tuple([int(x)
 788                                         for x in sqlite_version.split(".")])
 789                     if sqlite_version_tuple >= MIN_SQLITE_VERSION_NUMBER:
 790                         # we win!
 791                         print "%s/sqlite3.h: version %s"%(d, sqlite_version)
 792                         sqlite_incdir = d
 793                         break
 794                     else:
 795                         if sqlite_setup_debug:
 796                             print "%s: version %d is too old, need >= %s"%(d,
 797                                         sqlite_version, MIN_SQLITE_VERSION)
 798                 elif sqlite_setup_debug:
 799                     print "sqlite: %s had no SQLITE_VERSION"%(f,)
 800 
 801         if sqlite_incdir:
 802             sqlite_dirs_to_check = [
 803                 os.path.join(sqlite_incdir, '..', 'lib64'),
 804                 os.path.join(sqlite_incdir, '..', 'lib'),
 805                 os.path.join(sqlite_incdir, '..', '..', 'lib64'),
 806                 os.path.join(sqlite_incdir, '..', '..', 'lib'),
 807             ]
 808             sqlite_libfile = self.compiler.find_library_file(
 809                                 sqlite_dirs_to_check + lib_dirs, 'sqlite3')
 810             sqlite_libdir = [os.path.abspath(os.path.dirname(sqlite_libfile))]
 811 
 812         if sqlite_incdir and sqlite_libdir:
 813             sqlite_srcs = ['_sqlite/cache.c',
 814                 '_sqlite/connection.c',
 815                 '_sqlite/cursor.c',
 816                 '_sqlite/microprotocols.c',
 817                 '_sqlite/module.c',
 818                 '_sqlite/prepare_protocol.c',
 819                 '_sqlite/row.c',
 820                 '_sqlite/statement.c',
 821                 '_sqlite/util.c', ]
 822 
 823             sqlite_defines = []
 824             if sys.platform != "win32":
 825                 sqlite_defines.append(('MODULE_NAME', '"sqlite3"'))
 826             else:
 827                 sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"'))
 828 
 829 
 830             if sys.platform == 'darwin':
 831                 # In every directory on the search path search for a dynamic
 832                 # library and then a static library, instead of first looking
 833                 # for dynamic libraries on the entiry path.
 834                 # This way a staticly linked custom sqlite gets picked up
 835                 # before the dynamic library in /usr/lib.
 836                 sqlite_extra_link_args = ('-Wl,-search_paths_first',)
 837             else:
 838                 sqlite_extra_link_args = ()
 839 
 840             exts.append(Extension('_sqlite3', sqlite_srcs,
 841                                   define_macros=sqlite_defines,
 842                                   include_dirs=["Modules/_sqlite",
 843                                                 sqlite_incdir],
 844                                   library_dirs=sqlite_libdir,
 845                                   runtime_library_dirs=sqlite_libdir,
 846                                   extra_link_args=sqlite_extra_link_args,
 847                                   libraries=["sqlite3",]))
 848 
 849         # Look for Berkeley db 1.85.   Note that it is built as a different
 850         # module name so it can be included even when later versions are
 851         # available.  A very restrictive search is performed to avoid
 852         # accidentally building this module with a later version of the
 853         # underlying db library.  May BSD-ish Unixes incorporate db 1.85
 854         # symbols into libc and place the include file in /usr/include.
 855         #
 856         # If the better bsddb library can be built (db_incs is defined)
 857         # we do not build this one.  Otherwise this build will pick up
 858         # the more recent berkeleydb's db.h file first in the include path
 859         # when attempting to compile and it will fail.
 860 #        f = "/usr/include/db.h"
 861 #        if os.path.exists(f) and not db_incs:
 862 #            data = open(f).read()
 863 #            m = re.search(r"#s*define\s+HASHVERSION\s+2\s*", data)
 864 #            if m is not None:
 865 #                # bingo - old version used hash file format version 2
 866 #                ### XXX this should be fixed to not be platform-dependent
 867 #                ### but I don't have direct access to an osf1 platform and
 868 #                ### seemed to be muffing the search somehow
 869 #                libraries = platform == "osf1" and ['db'] or None
 870 #                if libraries is not None:
 871 #                    exts.append(Extension('bsddb185', ['bsddbmodule.c'],
 872 #                                          libraries=libraries))
 873 #                else:
 874 #                    exts.append(Extension('bsddb185', ['bsddbmodule.c']))
 875 #
 876 #        # The standard Unix dbm module:
 877 #        if platform not in ['cygwin']:
 878 #            if find_file("ndbm.h", inc_dirs, []) is not None:
 879 #                # Some systems have -lndbm, others don't
 880 #                if self.compiler.find_library_file(lib_dirs, 'ndbm'):
 881 #                    ndbm_libs = ['ndbm']
 882 #                else:
 883 #                    ndbm_libs = []
 884 #                exts.append( Extension('dbm', ['dbmmodule.c'],
 885 #                                       define_macros=[('HAVE_NDBM_H',None)],
 886 #                                       libraries = ndbm_libs ) )
 887 #            elif (self.compiler.find_library_file(lib_dirs, 'gdbm')
 888 #                  and find_file("gdbm/ndbm.h", inc_dirs, []) is not None):
 889 #                exts.append( Extension('dbm', ['dbmmodule.c'],
 890 #                                       define_macros=[('HAVE_GDBM_NDBM_H',None)],
 891 #                                       libraries = ['gdbm'] ) )
 892 #            elif db_incs is not None:
 893 #                exts.append( Extension('dbm', ['dbmmodule.c'],
 894 #                                       library_dirs=dblib_dir,
 895 #                                       runtime_library_dirs=dblib_dir,
 896 #                                       include_dirs=db_incs,
 897 #                                       define_macros=[('HAVE_BERKDB_H',None),
 898 #                                                      ('DB_DBM_HSEARCH',None)],
 899 #                                       libraries=dblibs))
 900 #
 901 #        # Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
 902 #        if (self.compiler.find_library_file(lib_dirs, 'gdbm')):
 903 #            exts.append( Extension('gdbm', ['gdbmmodule.c'],
 904 #                                   libraries = ['gdbm'] ) )
 905 #
 906 #        # Unix-only modules
 907 #        if platform not in ['mac', 'win32']:
 908 #            # Steen Lumholt's termios module
 909 #            exts.append( Extension('termios', ['termios.c']) )
 910 #            # Jeremy Hylton's rlimit interface
 911 #            if platform not in ['atheos']:
 912 #                exts.append( Extension('resource', ['resource.c']) )
 913 #
 914 #            # Sun yellow pages. Some systems have the functions in libc.
 915 #            if platform not in ['cygwin', 'atheos']:
 916 #                if (self.compiler.find_library_file(lib_dirs, 'nsl')):
 917 #                    libs = ['nsl']
 918 #                else:
 919 #                    libs = []
 920 #                exts.append( Extension('nis', ['nismodule.c'],
 921 #                                       libraries = libs) )
 922 #
 923 #        # Curses support, requiring the System V version of curses, often
 924 #        # provided by the ncurses library.
 925 #        panel_library = 'panel'
 926 #        if (self.compiler.find_library_file(lib_dirs, 'ncursesw')):
 927 #            curses_libs = ['ncursesw']
 928 #            # Bug 1464056: If _curses.so links with ncursesw,
 929 #            # _curses_panel.so must link with panelw.
 930 #            panel_library = 'panelw'
 931 #            exts.append( Extension('_curses', ['_cursesmodule.c'],
 932 #                                   libraries = curses_libs) )
 933 #        elif (self.compiler.find_library_file(lib_dirs, 'ncurses')):
 934 #            curses_libs = ['ncurses']
 935 #            exts.append( Extension('_curses', ['_cursesmodule.c'],
 936 #                                   libraries = curses_libs) )
 937 #        elif (self.compiler.find_library_file(lib_dirs, 'curses')
 938 #              and platform != 'darwin'):
 939 #                # OSX has an old Berkeley curses, not good enough for
 940 #                # the _curses module.
 941 #            if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
 942 #                curses_libs = ['curses', 'terminfo']
 943 #            elif (self.compiler.find_library_file(lib_dirs, 'termcap')):
 944 #                curses_libs = ['curses', 'termcap']
 945 #            else:
 946 #                curses_libs = ['curses']
 947 #
 948 #            exts.append( Extension('_curses', ['_cursesmodule.c'],
 949 #                                   libraries = curses_libs) )
 950 #
 951 #        # If the curses module is enabled, check for the panel module
 952 #        if (module_enabled(exts, '_curses') and
 953 #            self.compiler.find_library_file(lib_dirs, panel_library)):
 954 #            exts.append( Extension('_curses_panel', ['_curses_panel.c'],
 955 #                                   libraries = [panel_library] + curses_libs) )
 956 #
 957 #
 958         # Andrew Kuchling's zlib module.  Note that some versions of zlib
 959         # 1.1.3 have security problems.  See CERT Advisory CA-2002-07:
 960         # http://www.cert.org/advisories/CA-2002-07.html
 961         #
 962         # zlib 1.1.4 is fixed, but at least one vendor (RedHat) has decided to
 963         # patch its zlib 1.1.3 package instead of upgrading to 1.1.4.  For
 964         # now, we still accept 1.1.3, because we think it's difficult to
 965         # exploit this in Python, and we'd rather make it RedHat's problem
 966         # than our problem <wink>.
 967         #
 968         # You can upgrade zlib to version 1.1.4 yourself by going to
 969         # http://www.gzip.org/zlib/
 970         zlib_inc = find_file('zlib.h', [], inc_dirs)
 971         if zlib_inc is not None:
 972             zlib_h = zlib_inc[0] + '/zlib.h'
 973             version = '"0.0.0"'
 974             version_req = '"1.1.3"'
 975             fp = open(zlib_h)
 976             while 1:
 977                 line = fp.readline()
 978                 if not line:
 979                     break
 980                 if line.startswith('#define ZLIB_VERSION'):
 981                     version = line.split()[2]
 982                     break
 983             if version >= version_req:
 984                 if (self.compiler.find_library_file(lib_dirs, 'z')):
 985                     if sys.platform == "darwin":
 986                         zlib_extra_link_args = ('-Wl,-search_paths_first',)
 987                     else:
 988                         zlib_extra_link_args = ()
 989                     exts.append( Extension('zlib', ['zlibmodule.c'],
 990                                            libraries = ['z'],
 991                                            extra_link_args = zlib_extra_link_args))
 992 
 993         # Gustavo Niemeyer's bz2 module.
 994 #        if (self.compiler.find_library_file(lib_dirs, 'bz2')):
 995 #            if sys.platform == "darwin":
 996 #                bz2_extra_link_args = ('-Wl,-search_paths_first',)
 997 #            else:
 998 #                bz2_extra_link_args = ()
 999 #            exts.append( Extension('bz2', ['bz2module.c'],
1000 #                                   libraries = ['bz2'],
1001 #                                   extra_link_args = bz2_extra_link_args) )
1002 #
1003         # Interface to the Expat XML parser
1004         #
1005         # Expat was written by James Clark and is now maintained by a
1006         # group of developers on SourceForge; see www.libexpat.org for
1007         # more information.  The pyexpat module was written by Paul
1008         # Prescod after a prototype by Jack Jansen.  The Expat source
1009         # is included in Modules/expat/.  Usage of a system
1010         # shared libexpat.so/expat.dll is not advised.
1011         #
1012         # More information on Expat can be found at www.libexpat.org.
1013         #
1014         expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')
1015         define_macros = [
1016             ('HAVE_EXPAT_CONFIG_H', '1'),
1017         ]
1018 
1019         exts.append(Extension('pyexpat',
1020                               define_macros = define_macros,
1021                               include_dirs = [expatinc],
1022                               sources = ['pyexpat.c',
1023                                          'expat/xmlparse.c',
1024                                          'expat/xmlrole.c',
1025                                          'expat/xmltok.c',
1026                                          ],
1027                               ))
1028 
1029         # Fredrik Lundh's cElementTree module.  Note that this also
1030         # uses expat (via the CAPI hook in pyexpat).
1031 
1032         if os.path.isfile(os.path.join(srcdir, 'Modules', '_elementtree.c')):
1033             define_macros.append(('USE_PYEXPAT_CAPI', None))
1034             exts.append(Extension('_elementtree',
1035                                   define_macros = define_macros,
1036                                   include_dirs = [expatinc],
1037                                   sources = ['_elementtree.c'],
1038                                   ))
1039 
1040         # Hye-Shik Chang's CJKCodecs modules.
1041         if have_unicode:
1042             exts.append(Extension('_multibytecodec',
1043                                   ['cjkcodecs/multibytecodec.c']))
1044             for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
1045                 exts.append(Extension('_codecs_' + loc,
1046                                       ['cjkcodecs/_codecs_%s.c' % loc]))
1047 
1048         # Dynamic loading module
1049         if sys.maxint == 0x7fffffff:
1050             # This requires sizeof(int) == sizeof(long) == sizeof(char*)
1051             dl_inc = find_file('dlfcn.h', [], inc_dirs)
1052             if (dl_inc is not None) and (platform not in ['atheos']):
1053                 exts.append( Extension('dl', ['dlmodule.c']) )
1054 
1055         # Thomas Heller's _ctypes module
1056         self.detect_ctypes(inc_dirs, lib_dirs)
1057 
1058         # Platform-specific libraries
1059         if platform == 'linux2':
1060             # Linux-specific modules
1061             exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
1062 
1063         if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
1064                         'freebsd7'):
1065             exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
1066 
1067         if platform == 'sunos5':
1068             # SunOS specific modules
1069             exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
1070 
1071         if platform == 'darwin' and ("--disable-toolbox-glue" not in
1072                 sysconfig.get_config_var("CONFIG_ARGS")):
1073 
1074             if os.uname()[2] > '8.':
1075                 # We're on Mac OS X 10.4 or later, the compiler should
1076                 # support '-Wno-deprecated-declarations'. This will
1077                 # surpress deprecation warnings for the Carbon extensions,
1078                 # these extensions wrap the Carbon APIs and even those
1079                 # parts that are deprecated.
1080                 carbon_extra_compile_args = ['-Wno-deprecated-declarations']
1081             else:
1082                 carbon_extra_compile_args = []
1083 
1084             # Mac OS X specific modules.
1085             def macSrcExists(name1, name2=''):
1086                 if not name1:
1087                     return None
1088                 names = (name1,)
1089                 if name2:
1090                     names = (name1, name2)
1091                 path = os.path.join(srcdir, 'Mac', 'Modules', *names)
1092                 return os.path.exists(path)
1093 
1094             def addMacExtension(name, kwds, extra_srcs=[]):
1095                 dirname = ''
1096                 if name[0] == '_':
1097                     dirname = name[1:].lower()
1098                 cname = name + '.c'
1099                 cmodulename = name + 'module.c'
1100                 # Check for NNN.c, NNNmodule.c, _nnn/NNN.c, _nnn/NNNmodule.c
1101                 if macSrcExists(cname):
1102                     srcs = [cname]
1103                 elif macSrcExists(cmodulename):
1104                     srcs = [cmodulename]
1105                 elif macSrcExists(dirname, cname):
1106                     # XXX(nnorwitz): If all the names ended with module, we
1107                     # wouldn't need this condition.  ibcarbon is the only one.
1108                     srcs = [os.path.join(dirname, cname)]
1109                 elif macSrcExists(dirname, cmodulename):
1110                     srcs = [os.path.join(dirname, cmodulename)]
1111                 else:
1112                     raise RuntimeError("%s not found" % name)
1113 
1114                 # Here's the whole point:  add the extension with sources
1115                 exts.append(Extension(name, srcs + extra_srcs, **kwds))
1116 
1117             # Core Foundation
1118             core_kwds = {'extra_compile_args': carbon_extra_compile_args,
1119                          'extra_link_args': ['-framework', 'CoreFoundation'],
1120                         }
1121             addMacExtension('_CF', core_kwds, ['cf/pycfbridge.c'])
1122             addMacExtension('autoGIL', core_kwds)
1123 
1124             # Carbon
1125             carbon_kwds = {'extra_compile_args': carbon_extra_compile_args,
1126                            'extra_link_args': ['-framework', 'Carbon'],
1127                           }
1128             CARBON_EXTS = ['ColorPicker', 'gestalt', 'MacOS', 'Nav',
1129                            'OSATerminology', 'icglue',
1130                            # All these are in subdirs
1131                            '_AE', '_AH', '_App', '_CarbonEvt', '_Cm', '_Ctl',
1132                            '_Dlg', '_Drag', '_Evt', '_File', '_Folder', '_Fm',
1133                            '_Help', '_Icn', '_IBCarbon', '_List',
1134                            '_Menu', '_Mlte', '_OSA', '_Res', '_Qd', '_Qdoffs',
1135                            '_Scrap', '_Snd', '_TE', '_Win',
1136                           ]
1137             for name in CARBON_EXTS:
1138                 addMacExtension(name, carbon_kwds)
1139 
1140             # Application Services & QuickTime
1141             app_kwds = {'extra_compile_args': carbon_extra_compile_args,
1142                         'extra_link_args': ['-framework','ApplicationServices'],
1143                        }
1144             addMacExtension('_Launch', app_kwds)
1145             addMacExtension('_CG', app_kwds)
1146 
1147             exts.append( Extension('_Qt', ['qt/_Qtmodule.c'],
1148                         extra_compile_args=carbon_extra_compile_args,
1149                         extra_link_args=['-framework', 'QuickTime',
1150                                      '-framework', 'Carbon']) )
1151 
1152 
1153         self.extensions.extend(exts)
1154 
1155         # Call the method for detecting whether _tkinter can be compiled
1156         self.detect_tkinter(inc_dirs, lib_dirs)
1157 
1158     def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
1159         # The _tkinter module, using frameworks. Since frameworks are quite
1160         # different the UNIX search logic is not sharable.
1161         from os.path import join, exists
1162         framework_dirs = [
1163             '/System/Library/Frameworks/',
1164             '/Library/Frameworks',
1165             join(os.getenv('HOME'), '/Library/Frameworks')
1166         ]
1167 
1168         # Find the directory that contains the Tcl.framework and Tk.framework
1169         # bundles.
1170         # XXX distutils should support -F!
1171         for F in framework_dirs:
1172             # both Tcl.framework and Tk.framework should be present
1173             for fw in 'Tcl', 'Tk':
1174                 if not exists(join(F, fw + '.framework')):
1175                     break
1176             else:
1177                 # ok, F is now directory with both frameworks. Continure
1178                 # building
1179                 break
1180         else:
1181             # Tk and Tcl frameworks not found. Normal "unix" tkinter search
1182             # will now resume.
1183             return 0
1184 
1185         # For 8.4a2, we must add -I options that point inside the Tcl and Tk
1186         # frameworks. In later release we should hopefully be able to pass
1187         # the -F option to gcc, which specifies a framework lookup path.
1188         #
1189         include_dirs = [
1190             join(F, fw + '.framework', H)
1191             for fw in 'Tcl', 'Tk'
1192             for H in 'Headers', 'Versions/Current/PrivateHeaders'
1193         ]
1194 
1195         # For 8.4a2, the X11 headers are not included. Rather than include a
1196         # complicated search, this is a hard-coded path. It could bail out
1197         # if X11 libs are not found...
1198         include_dirs.append('/usr/X11R6/include')
1199         frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
1200 
1201         ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
1202                         define_macros=[('WITH_APPINIT', 1)],
1203                         include_dirs = include_dirs,
1204                         libraries = [],
1205                         extra_compile_args = frameworks,
1206                         extra_link_args = frameworks,
1207                         )
1208         self.extensions.append(ext)
1209         return 1
1210 
1211 
1212     def detect_tkinter(self, inc_dirs, lib_dirs):
1213         # The _tkinter module.
1214 
1215         # Rather than complicate the code below, detecting and building
1216         # AquaTk is a separate method. Only one Tkinter will be built on
1217         # Darwin - either AquaTk, if it is found, or X11 based Tk.
1218         platform = self.get_platform()
1219         if (platform == 'darwin' and
1220             self.detect_tkinter_darwin(inc_dirs, lib_dirs)):
1221             return
1222 
1223         # Assume we haven't found any of the libraries or include files
1224         # The versions with dots are used on Unix, and the versions without
1225         # dots on Windows, for detection by cygwin.
1226         tcllib = tklib = tcl_includes = tk_includes = None
1227         for version in ['8.5', '85', '8.4', '84', '8.3', '83', '8.2',
1228                         '82', '8.1', '81', '8.0', '80']:
1229             tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version)
1230             tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version)
1231             if tklib and tcllib:
1232                 # Exit the loop when we've found the Tcl/Tk libraries
1233                 break
1234 
1235         # Now check for the header files
1236         if tklib and tcllib:
1237             # Check for the include files on Debian and {Free,Open}BSD, where
1238             # they're put in /usr/include/{tcl,tk}X.Y
1239             dotversion = version
1240             if '.' not in dotversion and "bsd" in sys.platform.lower():
1241                 # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a,
1242                 # but the include subdirs are named like .../include/tcl8.3.
1243                 dotversion = dotversion[:-1] + '.' + dotversion[-1]
1244             tcl_include_sub = []
1245             tk_include_sub = []
1246             for dir in inc_dirs:
1247                 tcl_include_sub += [dir + os.sep + "tcl" + dotversion]
1248                 tk_include_sub += [dir + os.sep + "tk" + dotversion]
1249             tk_include_sub += tcl_include_sub
1250             tcl_includes = find_file('tcl.h', inc_dirs, tcl_include_sub)
1251             tk_includes = find_file('tk.h', inc_dirs, tk_include_sub)
1252 
1253         if (tcllib is None or tklib is None or
1254             tcl_includes is None or tk_includes is None):
1255             self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2)
1256             return
1257 
1258         # OK... everything seems to be present for Tcl/Tk.
1259 
1260         include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
1261         for dir in tcl_includes + tk_includes:
1262             if dir not in include_dirs:
1263                 include_dirs.append(dir)
1264 
1265         # Check for various platform-specific directories
1266         if platform == 'sunos5':
1267             include_dirs.append('/usr/openwin/include')
1268             added_lib_dirs.append('/usr/openwin/lib')
1269         elif os.path.exists('/usr/X11R6/include'):
1270             include_dirs.append('/usr/X11R6/include')
1271             added_lib_dirs.append('/usr/X11R6/lib64')
1272             added_lib_dirs.append('/usr/X11R6/lib')
1273         elif os.path.exists('/usr/X11R5/include'):
1274             include_dirs.append('/usr/X11R5/include')
1275             added_lib_dirs.append('/usr/X11R5/lib')
1276         else:
1277             # Assume default location for X11
1278             include_dirs.append('/usr/X11/include')
1279             added_lib_dirs.append('/usr/X11/lib')
1280 
1281         # If Cygwin, then verify that X is installed before proceeding
1282         if platform == 'cygwin':
1283             x11_inc = find_file('X11/Xlib.h', [], include_dirs)
1284             if x11_inc is None:
1285                 return
1286 
1287         # Check for BLT extension
1288         if self.compiler.find_library_file(lib_dirs + added_lib_dirs,
1289                                            'BLT8.0'):
1290             defs.append( ('WITH_BLT', 1) )
1291             libs.append('BLT8.0')
1292         elif self.compiler.find_library_file(lib_dirs + added_lib_dirs,
1293                                            'BLT'):
1294             defs.append( ('WITH_BLT', 1) )
1295             libs.append('BLT')
1296 
1297         # Add the Tcl/Tk libraries
1298         libs.append('tk'+ version)
1299         libs.append('tcl'+ version)
1300 
1301         if platform in ['aix3', 'aix4']:
1302             libs.append('ld')
1303 
1304         # Finally, link with the X11 libraries (not appropriate on cygwin)
1305         if platform != "cygwin":
1306             libs.append('X11')
1307 
1308         ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
1309                         define_macros=[('WITH_APPINIT', 1)] + defs,
1310                         include_dirs = include_dirs,
1311                         libraries = libs,
1312                         library_dirs = added_lib_dirs,
1313                         )
1314         self.extensions.append(ext)
1315 
1316 ##         # Uncomment these lines if you want to play with xxmodule.c
1317 ##         ext = Extension('xx', ['xxmodule.c'])
1318 ##         self.extensions.append(ext)
1319 
1320         # XXX handle these, but how to detect?
1321         # *** Uncomment and edit for PIL (TkImaging) extension only:
1322         #       -DWITH_PIL -I../Extensions/Imaging/libImaging  tkImaging.c \
1323         # *** Uncomment and edit for TOGL extension only:
1324         #       -DWITH_TOGL togl.c \
1325         # *** Uncomment these for TOGL extension only:
1326         #       -lGL -lGLU -lXext -lXmu \
1327 
1328     def configure_ctypes(self, ext):
1329         if not self.use_system_libffi:
1330             (srcdir,) = sysconfig.get_config_vars('srcdir')
1331             ffi_builddir = os.path.join(self.build_temp, 'libffi')
1332             ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
1333                                          '_ctypes', 'libffi'))
1334             ffi_configfile = os.path.join(ffi_builddir, 'fficonfig.py')
1335 
1336             from distutils.dep_util import newer_group
1337 
1338             config_sources = [os.path.join(ffi_srcdir, fname)
1339                               for fname in os.listdir(ffi_srcdir)
1340                               if os.path.isfile(os.path.join(ffi_srcdir, fname))]
1341             if self.force or newer_group(config_sources,
1342                                          ffi_configfile):
1343                 from distutils.dir_util import mkpath
1344                 mkpath(ffi_builddir)
1345                 config_args = []
1346 
1347                 # Pass empty CFLAGS because we'll just append the resulting
1348                 # CFLAGS to Python's; -g or -O2 is to be avoided.
1349                 cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \
1350                       % (ffi_builddir, ffi_srcdir, " ".join(config_args))
1351 
1352                 res = os.system(cmd)
1353                 if res or not os.path.exists(ffi_configfile):
1354                     print "Failed to configure _ctypes module"
1355                     return False
1356 
1357             fficonfig = {}
1358             execfile(ffi_configfile, globals(), fficonfig)
1359             ffi_srcdir = os.path.join(fficonfig['ffi_srcdir'], 'src')
1360 
1361             # Add .S (preprocessed assembly) to C compiler source extensions.
1362             self.compiler.src_extensions.append('.S')
1363 
1364             include_dirs = [os.path.join(ffi_builddir, 'include'),
1365                             ffi_builddir, ffi_srcdir]
1366             extra_compile_args = fficonfig['ffi_cflags'].split()
1367 
1368             ext.sources.extend(fficonfig['ffi_sources'])
1369             ext.include_dirs.extend(include_dirs)
1370             ext.extra_compile_args.extend(extra_compile_args)
1371         return True
1372 
1373     def detect_ctypes(self, inc_dirs, lib_dirs):
1374         self.use_system_libffi = False
1375         include_dirs = []
1376         extra_compile_args = []
1377         extra_link_args = []
1378         sources = ['_ctypes/_ctypes.c',
1379                    '_ctypes/callbacks.c',
1380                    '_ctypes/callproc.c',
1381                    '_ctypes/stgdict.c',
1382                    '_ctypes/cfield.c',
1383                    '_ctypes/malloc_closure.c']
1384         depends = ['_ctypes/ctypes.h']
1385 
1386         if sys.platform == 'darwin':
1387             sources.append('_ctypes/darwin/dlfcn_simple.c')
1388             include_dirs.append('_ctypes/darwin')
1389 # XXX Is this still needed?
1390 ##            extra_link_args.extend(['-read_only_relocs', 'warning'])
1391 
1392         elif sys.platform == 'sunos5':
1393             # XXX This shouldn't be necessary; it appears that some
1394             # of the assembler code is non-PIC (i.e. it has relocations
1395             # when it shouldn't. The proper fix would be to rewrite
1396             # the assembler code to be PIC.
1397             # This only works with GCC; the Sun compiler likely refuses
1398             # this option. If you want to compile ctypes with the Sun
1399             # compiler, please research a proper solution, instead of
1400             # finding some -z option for the Sun compiler.
1401             extra_link_args.append('-mimpure-text')
1402 
1403         ext = Extension('_ctypes',
1404                         include_dirs=include_dirs,
1405                         extra_compile_args=extra_compile_args,
1406                         extra_link_args=extra_link_args,
1407                         libraries=[],
1408                         sources=sources,
1409                         depends=depends)
1410         ext_test = Extension('_ctypes_test',
1411                              sources=['_ctypes/_ctypes_test.c'])
1412         self.extensions.extend([ext, ext_test])
1413 
1414         if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"):
1415             return
1416 
1417         ffi_inc = find_file('ffi.h', [], inc_dirs)
1418         if ffi_inc is not None:
1419             ffi_h = ffi_inc[0] + '/ffi.h'
1420             fp = open(ffi_h)
1421             while 1:
1422                 line = fp.readline()
1423                 if not line:
1424                     ffi_inc = None
1425                     break
1426                 if line.startswith('#define LIBFFI_H'):
1427                     break
1428         ffi_lib = None
1429         if ffi_inc is not None:
1430             for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
1431                 if (self.compiler.find_library_file(lib_dirs, lib_name)):
1432                     ffi_lib = lib_name
1433                     break
1434 
1435         if ffi_inc and ffi_lib:
1436             ext.include_dirs.extend(ffi_inc)
1437             ext.libraries.append(ffi_lib)
1438             self.use_system_libffi = True
1439 
1440 
1441 class PyBuildInstall(install):
1442     # Suppress the warning about installation into the lib_dynload
1443     # directory, which is not in sys.path when running Python during
1444     # installation:
1445     def initialize_options (self):
1446         install.initialize_options(self)
1447         self.warn_dir=0
1448 
1449 class PyBuildInstallLib(install_lib):
1450     # Do exactly what install_lib does but make sure correct access modes get
1451     # set on installed directories and files. All installed files with get
1452     # mode 644 unless they are a shared library in which case they will get
1453     # mode 755. All installed directories will get mode 755.
1454 
1455     so_ext = sysconfig.get_config_var("SO")
1456 
1457     def install(self):
1458         outfiles = install_lib.install(self)
1459         self.set_file_modes(outfiles, 0644, 0755)
1460         self.set_dir_modes(self.install_dir, 0755)
1461         return outfiles
1462 
1463     def set_file_modes(self, files, defaultMode, sharedLibMode):
1464         if not self.is_chmod_supported(): return
1465         if not files: return
1466 
1467         for filename in files:
1468             if os.path.islink(filename): continue
1469             mode = defaultMode
1470             if filename.endswith(self.so_ext): mode = sharedLibMode
1471             log.info("changing mode of %s to %o", filename, mode)
1472             if not self.dry_run: os.chmod(filename, mode)
1473 
1474     def set_dir_modes(self, dirname, mode):
1475         if not self.is_chmod_supported(): return
1476         os.path.walk(dirname, self.set_dir_modes_visitor, mode)
1477 
1478     def set_dir_modes_visitor(self, mode, dirname, names):
1479         if os.path.islink(dirname): return
1480         log.info("changing mode of %s to %o", dirname, mode)
1481         if not self.dry_run: os.chmod(dirname, mode)
1482 
1483     def is_chmod_supported(self):
1484         return hasattr(os, 'chmod')
1485 
1486 SUMMARY = """
1487 Python is an interpreted, interactive, object-oriented programming
1488 language. It is often compared to Tcl, Perl, Scheme or Java.
1489 
1490 Python combines remarkable power with very clear syntax. It has
1491 modules, classes, exceptions, very high level dynamic data types, and
1492 dynamic typing. There are interfaces to many system calls and
1493 libraries, as well as to various windowing systems (X11, Motif, Tk,
1494 Mac, MFC). New built-in modules are easily written in C or C++. Python
1495 is also usable as an extension language for applications that need a
1496 programmable interface.
1497 
1498 The Python implementation is portable: it runs on many brands of UNIX,
1499 on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't
1500 listed here, it may still be supported, if there's a C compiler for
1501 it. Ask around on comp.lang.python -- or just try compiling Python
1502 yourself.
1503 """
1504 
1505 CLASSIFIERS = """
1506 Development Status :: 3 - Alpha
1507 Development Status :: 6 - Mature
1508 License :: OSI Approved :: Python Software Foundation License
1509 Natural Language :: English
1510 Programming Language :: C
1511 Programming Language :: Python
1512 Topic :: Software Development
1513 """
1514 
1515 def main():
1516     # turn off warnings when deprecated modules are imported
1517     import warnings
1518     warnings.filterwarnings("ignore",category=DeprecationWarning)
1519     setup(# PyPI Metadata (PEP 301)
1520           name = "Python",
1521           version = sys.version.split()[0],
1522           url = "http://www.python.org/%s" % sys.version[:3],
1523           maintainer = "Guido van Rossum and the Python community",
1524           maintainer_email = "[email protected]",
1525           description = "A high-level object-oriented programming language",
1526           long_description = SUMMARY.strip(),
1527           license = "PSF license",
1528           classifiers = filter(None, CLASSIFIERS.split("\n")),
1529           platforms = ["Many"],
1530 
1531           # Build info
1532           cmdclass = {'build_ext':PyBuildExt, 'install':PyBuildInstall,
1533                       'install_lib':PyBuildInstallLib},
1534           # The struct module is defined here, because build_ext won't be
1535           # called unless there's at least one extension module defined.
1536           ext_modules=[Extension('_struct', ['_struct.c'])],
1537 
1538           # Scripts to install
1539     #      scripts = ['Tools/scripts/pydoc', 'Tools/scripts/idle',
1540      #                'Lib/smtpd.py']
1541           scripts = []
1542         )
1543 
1544 # --install-platlib
1545 if __name__ == '__main__':
1546     main()

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2021-05-11 08:51:52, 37.9 KB) [[attachment:Makefile]]
  • [get | view] (2021-05-11 08:51:52, 67.9 KB) [[attachment:setup.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.