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