src/newcore/setup.py
changeset 0 ca70ae20a155
equal deleted inserted replaced
-1:000000000000 0:ca70ae20a155
       
     1 # Autodetecting setup.py script for building the Python extensions
       
     2 #
       
     3 
       
     4 __version__ = "$Revision: 66914 $"
       
     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         except (CCompilerError, DistutilsError), why:
       
   190             self.announce('WARNING: building of extension "%s" failed: %s' %
       
   191                           (ext.name, sys.exc_info()[1]))
       
   192             return
       
   193         # Workaround for Mac OS X: The Carbon-based modules cannot be
       
   194         # reliably imported into a command-line Python
       
   195         if 'Carbon' in ext.extra_link_args:
       
   196             self.announce(
       
   197                 'WARNING: skipping import check for Carbon-based "%s"' %
       
   198                 ext.name)
       
   199             return
       
   200         # Workaround for Cygwin: Cygwin currently has fork issues when many
       
   201         # modules have been imported
       
   202         if self.get_platform() == 'cygwin':
       
   203             self.announce('WARNING: skipping import check for Cygwin-based "%s"'
       
   204                 % ext.name)
       
   205             return
       
   206         ext_filename = os.path.join(
       
   207             self.build_lib,
       
   208             self.get_ext_filename(self.get_ext_fullname(ext.name)))
       
   209         try:
       
   210             imp.load_dynamic(ext.name, ext_filename)
       
   211         except ImportError, why:
       
   212             self.announce('*** WARNING: renaming "%s" since importing it'
       
   213                           ' failed: %s' % (ext.name, why), level=3)
       
   214             assert not self.inplace
       
   215             basename, tail = os.path.splitext(ext_filename)
       
   216             newname = basename + "_failed" + tail
       
   217             if os.path.exists(newname):
       
   218                 os.remove(newname)
       
   219             os.rename(ext_filename, newname)
       
   220 
       
   221             # XXX -- This relies on a Vile HACK in
       
   222             # distutils.command.build_ext.build_extension().  The
       
   223             # _built_objects attribute is stored there strictly for
       
   224             # use here.
       
   225             # If there is a failure, _built_objects may not be there,
       
   226             # so catch the AttributeError and move on.
       
   227             try:
       
   228                 for filename in self._built_objects:
       
   229                     os.remove(filename)
       
   230             except AttributeError:
       
   231                 self.announce('unable to remove files (ignored)')
       
   232         except:
       
   233             exc_type, why, tb = sys.exc_info()
       
   234             self.announce('*** WARNING: importing extension "%s" '
       
   235                           'failed with %s: %s' % (ext.name, exc_type, why),
       
   236                           level=3)
       
   237 
       
   238     def get_platform(self):
       
   239         # Get value of sys.platform
       
   240         for platform in ['cygwin', 'beos', 'darwin', 'atheos', 'osf1']:
       
   241             if sys.platform.startswith(platform):
       
   242                 return platform
       
   243         return sys.platform
       
   244 
       
   245     def detect_modules(self):
       
   246         # Ensure that /usr/local is always used
       
   247         add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
       
   248         add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
       
   249 
       
   250         # Add paths specified in the environment variables LDFLAGS and
       
   251         # CPPFLAGS for header and library files.
       
   252         # We must get the values from the Makefile and not the environment
       
   253         # directly since an inconsistently reproducible issue comes up where
       
   254         # the environment variable is not set even though the value were passed
       
   255         # into configure and stored in the Makefile (issue found on OS X 10.3).
       
   256         for env_var, arg_name, dir_list in (
       
   257                 ('LDFLAGS', '-R', self.compiler.runtime_library_dirs),
       
   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 %r is too old, need >= %r"%(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 = "python-dev@python.org",
       
  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         )
       
  1542 
       
  1543 # --install-platlib
       
  1544 if __name__ == '__main__':
       
  1545     main()