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