This commit was manufactured by cvs2svn to create tag 'r23b1-mac'.
[python/dscho.git] / setup.py
blobb45f623f919f180af16a9f4e2f19621450a3de60
1 # Autodetecting setup.py script for building the Python extensions
4 __version__ = "$Revision$"
6 import sys, os, getopt, imp, re
8 from distutils import log
9 from distutils import sysconfig
10 from distutils import text_file
11 from distutils.errors import *
12 from distutils.core import Extension, setup
13 from distutils.command.build_ext import build_ext
14 from distutils.command.install import install
15 from distutils.command.install_lib import install_lib
17 # This global variable is used to hold the list of modules to be disabled.
18 disabled_module_list = []
20 def add_dir_to_list(dirlist, dir):
21 """Add the directory 'dir' to the list 'dirlist' (at the front) if
22 1) 'dir' is not already in 'dirlist'
23 2) 'dir' actually exists, and is a directory."""
24 if dir is not None and os.path.isdir(dir) and dir not in dirlist:
25 dirlist.insert(0, dir)
27 def find_file(filename, std_dirs, paths):
28 """Searches for the directory where a given file is located,
29 and returns a possibly-empty list of additional directories, or None
30 if the file couldn't be found at all.
32 'filename' is the name of a file, such as readline.h or libcrypto.a.
33 'std_dirs' is the list of standard system directories; if the
34 file is found in one of them, no additional directives are needed.
35 'paths' is a list of additional locations to check; if the file is
36 found in one of them, the resulting list will contain the directory.
37 """
39 # Check the standard locations
40 for dir in std_dirs:
41 f = os.path.join(dir, filename)
42 if os.path.exists(f): return []
44 # Check the additional directories
45 for dir in paths:
46 f = os.path.join(dir, filename)
47 if os.path.exists(f):
48 return [dir]
50 # Not found anywhere
51 return None
53 def find_library_file(compiler, libname, std_dirs, paths):
54 result = compiler.find_library_file(std_dirs + paths, libname)
55 if result is None:
56 return None
58 # Check whether the found file is in one of the standard directories
59 dirname = os.path.dirname(result)
60 for p in std_dirs:
61 # Ensure path doesn't end with path separator
62 if p.endswith(os.sep):
63 p = p.strip(os.sep)
64 if p == dirname:
65 return [ ]
67 # Otherwise, it must have been in one of the additional directories,
68 # so we have to figure out which one.
69 for p in paths:
70 # Ensure path doesn't end with path separator
71 if p.endswith(os.sep):
72 p = p.strip(os.sep)
73 if p == dirname:
74 return [p]
75 else:
76 assert False, "Internal error: Path not found in std_dirs or paths"
78 def module_enabled(extlist, modname):
79 """Returns whether the module 'modname' is present in the list
80 of extensions 'extlist'."""
81 extlist = [ext for ext in extlist if ext.name == modname]
82 return len(extlist)
84 def find_module_file(module, dirlist):
85 """Find a module in a set of possible folders. If it is not found
86 return the unadorned filename"""
87 list = find_file(module, [], dirlist)
88 if not list:
89 return module
90 if len(list) > 1:
91 log.info("WARNING: multiple copies of %s found"%module)
92 return os.path.join(list[0], module)
94 class PyBuildExt(build_ext):
96 def build_extensions(self):
98 # Detect which modules should be compiled
99 self.detect_modules()
101 # Remove modules that are present on the disabled list
102 self.extensions = [ext for ext in self.extensions
103 if ext.name not in disabled_module_list]
105 # Fix up the autodetected modules, prefixing all the source files
106 # with Modules/ and adding Python's include directory to the path.
107 (srcdir,) = sysconfig.get_config_vars('srcdir')
108 if not srcdir:
109 # Maybe running on Windows but not using CYGWIN?
110 raise ValueError("No source directory; cannot proceed.")
112 # Figure out the location of the source code for extension modules
113 moddir = os.path.join(os.getcwd(), srcdir, 'Modules')
114 moddir = os.path.normpath(moddir)
115 srcdir, tail = os.path.split(moddir)
116 srcdir = os.path.normpath(srcdir)
117 moddir = os.path.normpath(moddir)
119 moddirlist = [moddir]
120 incdirlist = ['./Include']
122 # Platform-dependent module source and include directories
123 platform = self.get_platform()
124 if platform in ('darwin', 'mac'):
125 # Mac OS X also includes some mac-specific modules
126 macmoddir = os.path.join(os.getcwd(), srcdir, 'Mac/Modules')
127 moddirlist.append(macmoddir)
128 incdirlist.append('./Mac/Include')
130 alldirlist = moddirlist + incdirlist
132 # Fix up the paths for scripts, too
133 self.distribution.scripts = [os.path.join(srcdir, filename)
134 for filename in self.distribution.scripts]
136 for ext in self.extensions[:]:
137 ext.sources = [ find_module_file(filename, moddirlist)
138 for filename in ext.sources ]
139 if ext.depends is not None:
140 ext.depends = [find_module_file(filename, alldirlist)
141 for filename in ext.depends]
142 ext.include_dirs.append( '.' ) # to get config.h
143 for incdir in incdirlist:
144 ext.include_dirs.append( os.path.join(srcdir, incdir) )
146 # If a module has already been built statically,
147 # don't build it here
148 if ext.name in sys.builtin_module_names:
149 self.extensions.remove(ext)
151 if platform != 'mac':
152 # Parse Modules/Setup to figure out which modules are turned
153 # on in the file.
154 input = text_file.TextFile('Modules/Setup', join_lines=1)
155 remove_modules = []
156 while 1:
157 line = input.readline()
158 if not line: break
159 line = line.split()
160 remove_modules.append( line[0] )
161 input.close()
163 for ext in self.extensions[:]:
164 if ext.name in remove_modules:
165 self.extensions.remove(ext)
167 # When you run "make CC=altcc" or something similar, you really want
168 # those environment variables passed into the setup.py phase. Here's
169 # a small set of useful ones.
170 compiler = os.environ.get('CC')
171 linker_so = os.environ.get('LDSHARED')
172 args = {}
173 # unfortunately, distutils doesn't let us provide separate C and C++
174 # compilers
175 if compiler is not None:
176 (ccshared,opt,base) = sysconfig.get_config_vars('CCSHARED','OPT','BASECFLAGS')
177 args['compiler_so'] = compiler + ' ' + opt + ' ' + ccshared + ' ' + base
178 if linker_so is not None:
179 args['linker_so'] = linker_so
180 self.compiler.set_executables(**args)
182 build_ext.build_extensions(self)
184 def build_extension(self, ext):
186 try:
187 build_ext.build_extension(self, ext)
188 except (CCompilerError, DistutilsError), why:
189 self.announce('WARNING: building of extension "%s" failed: %s' %
190 (ext.name, sys.exc_info()[1]))
191 return
192 # Workaround for Mac OS X: The Carbon-based modules cannot be
193 # reliably imported into a command-line Python
194 if 'Carbon' in ext.extra_link_args:
195 self.announce(
196 'WARNING: skipping import check for Carbon-based "%s"' %
197 ext.name)
198 return
199 # Workaround for Cygwin: Cygwin currently has fork issues when many
200 # modules have been imported
201 if self.get_platform() == 'cygwin':
202 self.announce('WARNING: skipping import check for Cygwin-based "%s"'
203 % ext.name)
204 return
205 ext_filename = os.path.join(
206 self.build_lib,
207 self.get_ext_filename(self.get_ext_fullname(ext.name)))
208 try:
209 imp.load_dynamic(ext.name, ext_filename)
210 except ImportError, why:
211 self.announce('*** WARNING: renaming "%s" since importing it'
212 ' failed: %s' % (ext.name, why), level=3)
213 assert not self.inplace
214 basename, tail = os.path.splitext(ext_filename)
215 newname = basename + "_failed" + tail
216 if os.path.exists(newname):
217 os.remove(newname)
218 os.rename(ext_filename, newname)
220 # XXX -- This relies on a Vile HACK in
221 # distutils.command.build_ext.build_extension(). The
222 # _built_objects attribute is stored there strictly for
223 # use here.
224 # If there is a failure, _built_objects may not be there,
225 # so catch the AttributeError and move on.
226 try:
227 for filename in self._built_objects:
228 os.remove(filename)
229 except AttributeError:
230 self.announce('unable to remove files (ignored)')
231 except:
232 exc_type, why, tb = sys.exc_info()
233 self.announce('*** WARNING: importing extension "%s" '
234 'failed with %s: %s' % (ext.name, exc_type, why),
235 level=3)
237 def get_platform (self):
238 # Get value of sys.platform
239 platform = sys.platform
240 if platform[:6] =='cygwin':
241 platform = 'cygwin'
242 elif platform[:4] =='beos':
243 platform = 'beos'
244 elif platform[:6] == 'darwin':
245 platform = 'darwin'
246 elif platform[:6] == 'atheos':
247 platform = 'atheos'
249 return platform
251 def detect_modules(self):
252 # Ensure that /usr/local is always used
253 add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
254 add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
256 # fink installs lots of goodies in /sw/... - make sure we
257 # check there
258 if sys.platform == "darwin":
259 add_dir_to_list(self.compiler.library_dirs, '/sw/lib')
260 add_dir_to_list(self.compiler.include_dirs, '/sw/include')
262 if os.path.normpath(sys.prefix) != '/usr':
263 add_dir_to_list(self.compiler.library_dirs,
264 sysconfig.get_config_var("LIBDIR"))
265 add_dir_to_list(self.compiler.include_dirs,
266 sysconfig.get_config_var("INCLUDEDIR"))
268 try:
269 have_unicode = unicode
270 except NameError:
271 have_unicode = 0
273 # lib_dirs and inc_dirs are used to search for files;
274 # if a file is found in one of those directories, it can
275 # be assumed that no additional -I,-L directives are needed.
276 lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib']
277 inc_dirs = self.compiler.include_dirs + ['/usr/include']
278 exts = []
280 platform = self.get_platform()
281 (srcdir,) = sysconfig.get_config_vars('srcdir')
283 # Check for AtheOS which has libraries in non-standard locations
284 if platform == 'atheos':
285 lib_dirs += ['/system/libs', '/atheos/autolnk/lib']
286 lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep)
287 inc_dirs += ['/system/include', '/atheos/autolnk/include']
288 inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep)
290 # Check for MacOS X, which doesn't need libm.a at all
291 math_libs = ['m']
292 if platform in ['darwin', 'beos', 'mac']:
293 math_libs = []
295 # XXX Omitted modules: gl, pure, dl, SGI-specific modules
298 # The following modules are all pretty straightforward, and compile
299 # on pretty much any POSIXish platform.
302 # Some modules that are normally always on:
303 exts.append( Extension('regex', ['regexmodule.c', 'regexpr.c']) )
304 exts.append( Extension('pcre', ['pcremodule.c', 'pypcre.c']) )
306 exts.append( Extension('_hotshot', ['_hotshot.c']) )
307 exts.append( Extension('_weakref', ['_weakref.c']) )
308 exts.append( Extension('xreadlines', ['xreadlinesmodule.c']) )
310 # array objects
311 exts.append( Extension('array', ['arraymodule.c']) )
312 # complex math library functions
313 exts.append( Extension('cmath', ['cmathmodule.c'],
314 libraries=math_libs) )
316 # math library functions, e.g. sin()
317 exts.append( Extension('math', ['mathmodule.c'],
318 libraries=math_libs) )
319 # fast string operations implemented in C
320 exts.append( Extension('strop', ['stropmodule.c']) )
321 # time operations and variables
322 exts.append( Extension('time', ['timemodule.c'],
323 libraries=math_libs) )
324 exts.append( Extension('datetime', ['datetimemodule.c'],
325 libraries=math_libs) )
326 # random number generator implemented in C
327 exts.append( Extension("_random", ["_randommodule.c"]) )
328 # fast iterator tools implemented in C
329 exts.append( Extension("itertools", ["itertoolsmodule.c"]) )
330 # operator.add() and similar goodies
331 exts.append( Extension('operator', ['operator.c']) )
332 # Python C API test module
333 exts.append( Extension('_testcapi', ['_testcapimodule.c']) )
334 # static Unicode character database
335 if have_unicode:
336 exts.append( Extension('unicodedata', ['unicodedata.c']) )
337 # access to ISO C locale support
338 if platform in ['cygwin', 'aix4']:
339 locale_libs = ['intl']
340 else:
341 locale_libs = []
342 exts.append( Extension('_locale', ['_localemodule.c'],
343 libraries=locale_libs ) )
345 # Modules with some UNIX dependencies -- on by default:
346 # (If you have a really backward UNIX, select and socket may not be
347 # supported...)
349 # fcntl(2) and ioctl(2)
350 exts.append( Extension('fcntl', ['fcntlmodule.c']) )
351 if platform not in ['mac']:
352 # pwd(3)
353 exts.append( Extension('pwd', ['pwdmodule.c']) )
354 # grp(3)
355 exts.append( Extension('grp', ['grpmodule.c']) )
356 # select(2); not on ancient System V
357 exts.append( Extension('select', ['selectmodule.c']) )
359 # The md5 module implements the RSA Data Security, Inc. MD5
360 # Message-Digest Algorithm, described in RFC 1321. The
361 # necessary files md5c.c and md5.h are included here.
362 exts.append( Extension('md5', ['md5module.c', 'md5c.c']) )
364 # The sha module implements the SHA checksum algorithm.
365 # (NIST's Secure Hash Algorithm.)
366 exts.append( Extension('sha', ['shamodule.c']) )
368 # Helper module for various ascii-encoders
369 exts.append( Extension('binascii', ['binascii.c']) )
371 # Fred Drake's interface to the Python parser
372 exts.append( Extension('parser', ['parsermodule.c']) )
374 # cStringIO and cPickle
375 exts.append( Extension('cStringIO', ['cStringIO.c']) )
376 exts.append( Extension('cPickle', ['cPickle.c']) )
378 # Memory-mapped files (also works on Win32).
379 if platform not in ['atheos', 'mac']:
380 exts.append( Extension('mmap', ['mmapmodule.c']) )
382 # Lance Ellinghaus's modules:
383 # enigma-inspired encryption
384 exts.append( Extension('rotor', ['rotormodule.c']) )
385 if platform not in ['mac']:
386 # syslog daemon interface
387 exts.append( Extension('syslog', ['syslogmodule.c']) )
389 # George Neville-Neil's timing module:
390 exts.append( Extension('timing', ['timingmodule.c']) )
393 # Here ends the simple stuff. From here on, modules need certain
394 # libraries, are platform-specific, or present other surprises.
397 # Multimedia modules
398 # These don't work for 64-bit platforms!!!
399 # These represent audio samples or images as strings:
401 # Disabled on 64-bit platforms
402 if sys.maxint != 9223372036854775807L:
403 # Operations on audio samples
404 exts.append( Extension('audioop', ['audioop.c']) )
405 # Operations on images
406 exts.append( Extension('imageop', ['imageop.c']) )
407 # Read SGI RGB image files (but coded portably)
408 exts.append( Extension('rgbimg', ['rgbimgmodule.c']) )
410 # readline
411 if self.compiler.find_library_file(lib_dirs, 'readline'):
412 readline_libs = ['readline']
413 if self.compiler.find_library_file(lib_dirs,
414 'ncurses'):
415 readline_libs.append('ncurses')
416 elif self.compiler.find_library_file(lib_dirs, 'curses'):
417 readline_libs.append('curses')
418 elif self.compiler.find_library_file(lib_dirs +
419 ['/usr/lib/termcap'],
420 'termcap'):
421 readline_libs.append('termcap')
422 exts.append( Extension('readline', ['readline.c'],
423 library_dirs=['/usr/lib/termcap'],
424 libraries=readline_libs) )
425 if platform not in ['mac']:
426 # crypt module.
428 if self.compiler.find_library_file(lib_dirs, 'crypt'):
429 libs = ['crypt']
430 else:
431 libs = []
432 exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
434 # CSV files
435 exts.append( Extension('_csv', ['_csv.c']) )
437 # socket(2)
438 exts.append( Extension('_socket', ['socketmodule.c'],
439 depends = ['socketmodule.h']) )
440 # Detect SSL support for the socket module (via _ssl)
441 ssl_incs = find_file('openssl/ssl.h', inc_dirs,
442 ['/usr/local/ssl/include',
443 '/usr/contrib/ssl/include/'
446 krb5_h = find_file('krb5.h', inc_dirs,
447 ['/usr/kerberos/include'])
448 if krb5_h:
449 ssl_incs += krb5_h
450 ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
451 ['/usr/local/ssl/lib',
452 '/usr/contrib/ssl/lib/'
455 if (ssl_incs is not None and
456 ssl_libs is not None):
457 exts.append( Extension('_ssl', ['_ssl.c'],
458 include_dirs = ssl_incs,
459 library_dirs = ssl_libs,
460 libraries = ['ssl', 'crypto'],
461 depends = ['socketmodule.h']), )
463 # Modules that provide persistent dictionary-like semantics. You will
464 # probably want to arrange for at least one of them to be available on
465 # your machine, though none are defined by default because of library
466 # dependencies. The Python module anydbm.py provides an
467 # implementation independent wrapper for these; dumbdbm.py provides
468 # similar functionality (but slower of course) implemented in Python.
470 # Sleepycat Berkeley DB interface. http://www.sleepycat.com
472 # This requires the Sleepycat DB code. The earliest supported version
473 # of that library is 3.0, the latest supported version is 4.1. A list
474 # of available releases can be found at
476 # http://www.sleepycat.com/update/index.html
478 # when sorted in reverse order, keys for this dict must appear in the
479 # order you wish to search - e.g., search for db4 before db3
480 db_try_this = {
481 'db4': {'libs': ('db-4.1', 'db-4.0',),
482 'libdirs': ('/usr/local/BerkeleyDB.4.1/lib',
483 '/usr/local/BerkeleyDB.4.0/lib',
484 '/usr/local/lib',
485 '/opt/sfw',
486 '/sw/lib',
488 'incdirs': ('/usr/local/BerkeleyDB.4.1/include',
489 '/usr/local/BerkeleyDB.4.0/include',
490 '/usr/local/include/db4',
491 '/opt/sfw/include/db4',
492 '/sw/include/db4',
493 '/usr/include/db4',
495 'db3': {'libs': ('db-3.3', 'db-3.2', 'db-3.1'),
496 'libdirs': ('/usr/local/BerkeleyDB.3.3/lib',
497 '/usr/local/BerkeleyDB.3.2/lib',
498 '/usr/local/BerkeleyDB.3.1/lib',
499 '/usr/local/lib',
500 '/opt/sfw/lib',
501 '/sw/lib',
503 'incdirs': ('/usr/local/BerkeleyDB.3.3/include',
504 '/usr/local/BerkeleyDB.3.2/include',
505 '/usr/local/BerkeleyDB.3.1/include',
506 '/usr/local/include/db3',
507 '/opt/sfw/include/db3',
508 '/sw/include/db3',
509 '/usr/include/db3',
513 db_search_order = db_try_this.keys()
514 db_search_order.sort()
515 db_search_order.reverse()
517 class found(Exception): pass
518 try:
519 # See whether there is a Sleepycat header in the standard
520 # search path.
521 std_dbinc = None
522 for d in inc_dirs:
523 f = os.path.join(d, "db.h")
524 if os.path.exists(f):
525 f = open(f).read()
526 m = re.search(r"#define\WDB_VERSION_MAJOR\W([1-9]+)", f)
527 if m:
528 std_dbinc = 'db' + m.group(1)
529 for dbkey in db_search_order:
530 dbd = db_try_this[dbkey]
531 for dblib in dbd['libs']:
532 # Prefer version-specific includes over standard
533 # include locations.
534 db_incs = find_file('db.h', [], dbd['incdirs'])
535 dblib_dir = find_library_file(self.compiler,
536 dblib,
537 lib_dirs,
538 list(dbd['libdirs']))
539 if (db_incs or dbkey == std_dbinc) and \
540 dblib_dir is not None:
541 dblibs = [dblib]
542 raise found
543 except found:
544 dblibs = [dblib]
545 # A default source build puts Berkeley DB in something like
546 # /usr/local/Berkeley.3.3 and the lib dir under that isn't
547 # normally on ld.so's search path, unless the sysadmin has hacked
548 # /etc/ld.so.conf. We add the directory to runtime_library_dirs
549 # so the proper -R/--rpath flags get passed to the linker. This
550 # is usually correct and most trouble free, but may cause problems
551 # in some unusual system configurations (e.g. the directory is on
552 # an NFS server that goes away).
553 exts.append(Extension('_bsddb', ['_bsddb.c'],
554 library_dirs=dblib_dir,
555 runtime_library_dirs=dblib_dir,
556 include_dirs=db_incs,
557 libraries=dblibs))
558 else:
559 db_incs = None
560 dblibs = []
561 dblib_dir = None
563 # The standard Unix dbm module:
564 if platform not in ['cygwin']:
565 if find_file("ndbm.h", inc_dirs, []) is not None:
566 # Some systems have -lndbm, others don't
567 if self.compiler.find_library_file(lib_dirs, 'ndbm'):
568 ndbm_libs = ['ndbm']
569 else:
570 ndbm_libs = []
571 exts.append( Extension('dbm', ['dbmmodule.c'],
572 define_macros=[('HAVE_NDBM_H',None)],
573 libraries = ndbm_libs ) )
574 elif (self.compiler.find_library_file(lib_dirs, 'gdbm')
575 and find_file("gdbm/ndbm.h", inc_dirs, []) is not None):
576 exts.append( Extension('dbm', ['dbmmodule.c'],
577 define_macros=[('HAVE_GDBM_NDBM_H',None)],
578 libraries = ['gdbm'] ) )
579 elif db_incs is not None:
580 exts.append( Extension('dbm', ['dbmmodule.c'],
581 library_dirs=dblib_dir,
582 runtime_library_dirs=dblib_dir,
583 include_dirs=db_incs,
584 define_macros=[('HAVE_BERKDB_H',None),
585 ('DB_DBM_HSEARCH',None)],
586 libraries=dblibs))
588 # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
589 if (self.compiler.find_library_file(lib_dirs, 'gdbm')):
590 exts.append( Extension('gdbm', ['gdbmmodule.c'],
591 libraries = ['gdbm'] ) )
593 # The mpz module interfaces to the GNU Multiple Precision library.
594 # You need to ftp the GNU MP library.
595 # This was originally written and tested against GMP 1.2 and 1.3.2.
596 # It has been modified by Rob Hooft to work with 2.0.2 as well, but I
597 # haven't tested it recently, and it definitely doesn't work with
598 # GMP 4.0. For more complete modules, refer to
599 # http://gmpy.sourceforge.net and
600 # http://www.egenix.com/files/python/mxNumber.html
602 # A compatible MP library unencumbered by the GPL also exists. It was
603 # posted to comp.sources.misc in volume 40 and is widely available from
604 # FTP archive sites. One URL for it is:
605 # ftp://gatekeeper.dec.com/.b/usenet/comp.sources.misc/volume40/fgmp/part01.Z
607 if (self.compiler.find_library_file(lib_dirs, 'gmp')):
608 exts.append( Extension('mpz', ['mpzmodule.c'],
609 libraries = ['gmp'] ) )
612 # Unix-only modules
613 if platform not in ['mac', 'win32']:
614 # Steen Lumholt's termios module
615 exts.append( Extension('termios', ['termios.c']) )
616 # Jeremy Hylton's rlimit interface
617 if platform not in ['atheos']:
618 exts.append( Extension('resource', ['resource.c']) )
620 # Sun yellow pages. Some systems have the functions in libc.
621 if platform not in ['cygwin', 'atheos']:
622 if (self.compiler.find_library_file(lib_dirs, 'nsl')):
623 libs = ['nsl']
624 else:
625 libs = []
626 exts.append( Extension('nis', ['nismodule.c'],
627 libraries = libs) )
629 # Curses support, requring the System V version of curses, often
630 # provided by the ncurses library.
631 if platform == 'sunos4':
632 inc_dirs += ['/usr/5include']
633 lib_dirs += ['/usr/5lib']
635 if (self.compiler.find_library_file(lib_dirs, 'ncurses')):
636 curses_libs = ['ncurses']
637 exts.append( Extension('_curses', ['_cursesmodule.c'],
638 libraries = curses_libs) )
639 elif (self.compiler.find_library_file(lib_dirs, 'curses')
640 and platform != 'darwin'):
641 # OSX has an old Berkeley curses, not good enough for
642 # the _curses module.
643 if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
644 curses_libs = ['curses', 'terminfo']
645 elif (self.compiler.find_library_file(lib_dirs, 'termcap')):
646 curses_libs = ['curses', 'termcap']
647 else:
648 curses_libs = ['curses']
650 exts.append( Extension('_curses', ['_cursesmodule.c'],
651 libraries = curses_libs) )
653 # If the curses module is enabled, check for the panel module
654 if (module_enabled(exts, '_curses') and
655 self.compiler.find_library_file(lib_dirs, 'panel')):
656 exts.append( Extension('_curses_panel', ['_curses_panel.c'],
657 libraries = ['panel'] + curses_libs) )
660 # Andrew Kuchling's zlib module. Note that some versions of zlib
661 # 1.1.3 have security problems. See CERT Advisory CA-2002-07:
662 # http://www.cert.org/advisories/CA-2002-07.html
664 # zlib 1.1.4 is fixed, but at least one vendor (RedHat) has decided to
665 # patch its zlib 1.1.3 package instead of upgrading to 1.1.4. For
666 # now, we still accept 1.1.3, because we think it's difficult to
667 # exploit this in Python, and we'd rather make it RedHat's problem
668 # than our problem <wink>.
670 # You can upgrade zlib to version 1.1.4 yourself by going to
671 # http://www.gzip.org/zlib/
672 zlib_inc = find_file('zlib.h', [], inc_dirs)
673 if zlib_inc is not None:
674 zlib_h = zlib_inc[0] + '/zlib.h'
675 version = '"0.0.0"'
676 version_req = '"1.1.3"'
677 fp = open(zlib_h)
678 while 1:
679 line = fp.readline()
680 if not line:
681 break
682 if line.startswith('#define ZLIB_VERSION'):
683 version = line.split()[2]
684 break
685 if version >= version_req:
686 if (self.compiler.find_library_file(lib_dirs, 'z')):
687 exts.append( Extension('zlib', ['zlibmodule.c'],
688 libraries = ['z']) )
690 # Gustavo Niemeyer's bz2 module.
691 if (self.compiler.find_library_file(lib_dirs, 'bz2')):
692 exts.append( Extension('bz2', ['bz2module.c'],
693 libraries = ['bz2']) )
695 # Interface to the Expat XML parser
697 # Expat was written by James Clark and is now maintained by a
698 # group of developers on SourceForge; see www.libexpat.org for
699 # more information. The pyexpat module was written by Paul
700 # Prescod after a prototype by Jack Jansen. Source of Expat
701 # 1.95.2 is included in Modules/expat/. Usage of a system
702 # shared libexpat.so/expat.dll is not advised.
704 # More information on Expat can be found at www.libexpat.org.
706 if sys.byteorder == "little":
707 xmlbo = "1234"
708 else:
709 xmlbo = "4321"
710 expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')
711 exts.append(Extension('pyexpat',
712 sources = [
713 'pyexpat.c',
714 'expat/xmlparse.c',
715 'expat/xmlrole.c',
716 'expat/xmltok.c',
718 define_macros = [
719 ('XML_NS', '1'),
720 ('XML_DTD', '1'),
721 ('BYTEORDER', xmlbo),
722 ('XML_CONTEXT_BYTES','1024'),
724 include_dirs = [expatinc]
727 # Dynamic loading module
728 if sys.maxint == 0x7fffffff:
729 # This requires sizeof(int) == sizeof(long) == sizeof(char*)
730 dl_inc = find_file('dlfcn.h', [], inc_dirs)
731 if (dl_inc is not None) and (platform not in ['atheos', 'darwin']):
732 exts.append( Extension('dl', ['dlmodule.c']) )
734 # Platform-specific libraries
735 if platform == 'linux2':
736 # Linux-specific modules
737 exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
739 if platform in ('linux2', 'freebsd4'):
740 exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
742 if platform == 'sunos5':
743 # SunOS specific modules
744 exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
746 if platform == 'darwin':
747 # Mac OS X specific modules.
748 exts.append( Extension('_CF', ['cf/_CFmodule.c', 'cf/pycfbridge.c'],
749 extra_link_args=['-framework', 'CoreFoundation']) )
751 exts.append( Extension('gestalt', ['gestaltmodule.c'],
752 extra_link_args=['-framework', 'Carbon']) )
753 exts.append( Extension('MacOS', ['macosmodule.c'],
754 extra_link_args=['-framework', 'Carbon']) )
755 exts.append( Extension('OSATerminology', ['OSATerminology.c'],
756 extra_link_args=['-framework', 'Carbon']) )
757 exts.append( Extension('icglue', ['icgluemodule.c'],
758 extra_link_args=['-framework', 'Carbon']) )
759 exts.append( Extension('_Res', ['res/_Resmodule.c'],
760 extra_link_args=['-framework', 'Carbon']) )
761 exts.append( Extension('_Snd', ['snd/_Sndmodule.c'],
762 extra_link_args=['-framework', 'Carbon']) )
763 exts.append( Extension('Nav', ['Nav.c'],
764 extra_link_args=['-framework', 'Carbon']) )
765 exts.append( Extension('_AE', ['ae/_AEmodule.c'],
766 extra_link_args=['-framework', 'Carbon']) )
767 exts.append( Extension('_AH', ['ah/_AHmodule.c'],
768 extra_link_args=['-framework', 'Carbon']) )
769 exts.append( Extension('_App', ['app/_Appmodule.c'],
770 extra_link_args=['-framework', 'Carbon']) )
771 exts.append( Extension('_CarbonEvt', ['carbonevt/_CarbonEvtmodule.c'],
772 extra_link_args=['-framework', 'Carbon']) )
773 exts.append( Extension('_CG', ['cg/_CGmodule.c'],
774 extra_link_args=['-framework', 'ApplicationServices']) )
775 exts.append( Extension('_Cm', ['cm/_Cmmodule.c'],
776 extra_link_args=['-framework', 'Carbon']) )
777 exts.append( Extension('_Ctl', ['ctl/_Ctlmodule.c'],
778 extra_link_args=['-framework', 'Carbon']) )
779 exts.append( Extension('_Dlg', ['dlg/_Dlgmodule.c'],
780 extra_link_args=['-framework', 'Carbon']) )
781 exts.append( Extension('_Drag', ['drag/_Dragmodule.c'],
782 extra_link_args=['-framework', 'Carbon']) )
783 exts.append( Extension('_Evt', ['evt/_Evtmodule.c'],
784 extra_link_args=['-framework', 'Carbon']) )
785 exts.append( Extension('_File', ['file/_Filemodule.c'],
786 extra_link_args=['-framework', 'Carbon']) )
787 exts.append( Extension('_Folder', ['folder/_Foldermodule.c'],
788 extra_link_args=['-framework', 'Carbon']) )
789 exts.append( Extension('_Fm', ['fm/_Fmmodule.c'],
790 extra_link_args=['-framework', 'Carbon']) )
791 exts.append( Extension('_Help', ['help/_Helpmodule.c'],
792 extra_link_args=['-framework', 'Carbon']) )
793 exts.append( Extension('_Icn', ['icn/_Icnmodule.c'],
794 extra_link_args=['-framework', 'Carbon']) )
795 exts.append( Extension('_IBCarbon', ['ibcarbon/_IBCarbon.c'],
796 extra_link_args=['-framework', 'Carbon']) )
797 exts.append( Extension('_List', ['list/_Listmodule.c'],
798 extra_link_args=['-framework', 'Carbon']) )
799 exts.append( Extension('_Menu', ['menu/_Menumodule.c'],
800 extra_link_args=['-framework', 'Carbon']) )
801 exts.append( Extension('_Mlte', ['mlte/_Mltemodule.c'],
802 extra_link_args=['-framework', 'Carbon']) )
803 exts.append( Extension('_Qd', ['qd/_Qdmodule.c'],
804 extra_link_args=['-framework', 'Carbon']) )
805 exts.append( Extension('_Qdoffs', ['qdoffs/_Qdoffsmodule.c'],
806 extra_link_args=['-framework', 'Carbon']) )
807 exts.append( Extension('_Qt', ['qt/_Qtmodule.c'],
808 extra_link_args=['-framework', 'QuickTime',
809 '-framework', 'Carbon']) )
810 exts.append( Extension('_Scrap', ['scrap/_Scrapmodule.c'],
811 extra_link_args=['-framework', 'Carbon']) )
812 exts.append( Extension('_TE', ['te/_TEmodule.c'],
813 extra_link_args=['-framework', 'Carbon']) )
814 # As there is no standardized place (yet) to put
815 # user-installed Mac libraries on OSX, we search for "waste"
816 # in parent directories of the Python source tree. You
817 # should put a symlink to your Waste installation in the
818 # same folder as your python source tree. Or modify the
819 # next few lines:-)
820 waste_incs = find_file("WASTE.h", [],
821 ['../'*n + 'waste/C_C++ Headers' for n in (0,1,2,3,4)])
822 waste_libs = find_library_file(self.compiler, "WASTE", [],
823 ["../"*n + "waste/Static Libraries" for n in (0,1,2,3,4)])
824 if waste_incs != None and waste_libs != None:
825 (srcdir,) = sysconfig.get_config_vars('srcdir')
826 exts.append( Extension('waste',
827 ['waste/wastemodule.c'] + [
828 os.path.join(srcdir, d) for d in
829 'Mac/Wastemods/WEObjectHandlers.c',
830 'Mac/Wastemods/WETabHooks.c',
831 'Mac/Wastemods/WETabs.c'
833 include_dirs = waste_incs + [os.path.join(srcdir, 'Mac/Wastemods')],
834 library_dirs = waste_libs,
835 libraries = ['WASTE'],
836 extra_link_args = ['-framework', 'Carbon'],
838 exts.append( Extension('_Win', ['win/_Winmodule.c'],
839 extra_link_args=['-framework', 'Carbon']) )
841 self.extensions.extend(exts)
843 # Call the method for detecting whether _tkinter can be compiled
844 self.detect_tkinter(inc_dirs, lib_dirs)
846 def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
847 # The _tkinter module, using frameworks. Since frameworks are quite
848 # different the UNIX search logic is not sharable.
849 from os.path import join, exists
850 framework_dirs = [
851 '/System/Library/Frameworks/',
852 '/Library/Frameworks',
853 join(os.getenv('HOME'), '/Library/Frameworks')
856 # Find the directory that contains the Tcl.framwork and Tk.framework
857 # bundles.
858 # XXX distutils should support -F!
859 for F in framework_dirs:
860 # both Tcl.framework and Tk.framework should be present
861 for fw in 'Tcl', 'Tk':
862 if not exists(join(F, fw + '.framework')):
863 break
864 else:
865 # ok, F is now directory with both frameworks. Continure
866 # building
867 break
868 else:
869 # Tk and Tcl frameworks not found. Normal "unix" tkinter search
870 # will now resume.
871 return 0
873 # For 8.4a2, we must add -I options that point inside the Tcl and Tk
874 # frameworks. In later release we should hopefully be able to pass
875 # the -F option to gcc, which specifies a framework lookup path.
877 include_dirs = [
878 join(F, fw + '.framework', H)
879 for fw in 'Tcl', 'Tk'
880 for H in 'Headers', 'Versions/Current/PrivateHeaders'
883 # For 8.4a2, the X11 headers are not included. Rather than include a
884 # complicated search, this is a hard-coded path. It could bail out
885 # if X11 libs are not found...
886 include_dirs.append('/usr/X11R6/include')
887 frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
889 ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
890 define_macros=[('WITH_APPINIT', 1)],
891 include_dirs = include_dirs,
892 libraries = [],
893 extra_compile_args = frameworks,
894 extra_link_args = frameworks,
896 self.extensions.append(ext)
897 return 1
900 def detect_tkinter(self, inc_dirs, lib_dirs):
901 # The _tkinter module.
903 # Rather than complicate the code below, detecting and building
904 # AquaTk is a separate method. Only one Tkinter will be built on
905 # Darwin - either AquaTk, if it is found, or X11 based Tk.
906 platform = self.get_platform()
907 if platform == 'darwin' and \
908 self.detect_tkinter_darwin(inc_dirs, lib_dirs):
909 return
911 # Assume we haven't found any of the libraries or include files
912 # The versions with dots are used on Unix, and the versions without
913 # dots on Windows, for detection by cygwin.
914 tcllib = tklib = tcl_includes = tk_includes = None
915 for version in ['8.4', '84', '8.3', '83', '8.2',
916 '82', '8.1', '81', '8.0', '80']:
917 tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version)
918 tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version)
919 if tklib and tcllib:
920 # Exit the loop when we've found the Tcl/Tk libraries
921 break
923 # Now check for the header files
924 if tklib and tcllib:
925 # Check for the include files on Debian, where
926 # they're put in /usr/include/{tcl,tk}X.Y
927 debian_tcl_include = [ '/usr/include/tcl' + version ]
928 debian_tk_include = [ '/usr/include/tk' + version ] + \
929 debian_tcl_include
930 tcl_includes = find_file('tcl.h', inc_dirs, debian_tcl_include)
931 tk_includes = find_file('tk.h', inc_dirs, debian_tk_include)
933 if (tcllib is None or tklib is None and
934 tcl_includes is None or tk_includes is None):
935 # Something's missing, so give up
936 return
938 # OK... everything seems to be present for Tcl/Tk.
940 include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
941 for dir in tcl_includes + tk_includes:
942 if dir not in include_dirs:
943 include_dirs.append(dir)
945 # Check for various platform-specific directories
946 if platform == 'sunos5':
947 include_dirs.append('/usr/openwin/include')
948 added_lib_dirs.append('/usr/openwin/lib')
949 elif os.path.exists('/usr/X11R6/include'):
950 include_dirs.append('/usr/X11R6/include')
951 added_lib_dirs.append('/usr/X11R6/lib')
952 elif os.path.exists('/usr/X11R5/include'):
953 include_dirs.append('/usr/X11R5/include')
954 added_lib_dirs.append('/usr/X11R5/lib')
955 else:
956 # Assume default location for X11
957 include_dirs.append('/usr/X11/include')
958 added_lib_dirs.append('/usr/X11/lib')
960 # If Cygwin, then verify that X is installed before proceeding
961 if platform == 'cygwin':
962 x11_inc = find_file('X11/Xlib.h', [], include_dirs)
963 if x11_inc is None:
964 return
966 # Check for BLT extension
967 if self.compiler.find_library_file(lib_dirs + added_lib_dirs,
968 'BLT8.0'):
969 defs.append( ('WITH_BLT', 1) )
970 libs.append('BLT8.0')
971 elif self.compiler.find_library_file(lib_dirs + added_lib_dirs,
972 'BLT'):
973 defs.append( ('WITH_BLT', 1) )
974 libs.append('BLT')
976 # Add the Tcl/Tk libraries
977 libs.append('tk'+ version)
978 libs.append('tcl'+ version)
980 if platform in ['aix3', 'aix4']:
981 libs.append('ld')
983 # Finally, link with the X11 libraries (not appropriate on cygwin)
984 if platform != "cygwin":
985 libs.append('X11')
987 ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
988 define_macros=[('WITH_APPINIT', 1)] + defs,
989 include_dirs = include_dirs,
990 libraries = libs,
991 library_dirs = added_lib_dirs,
993 self.extensions.append(ext)
995 ## # Uncomment these lines if you want to play with xxmodule.c
996 ## ext = Extension('xx', ['xxmodule.c'])
997 ## self.extensions.append(ext)
999 # XXX handle these, but how to detect?
1000 # *** Uncomment and edit for PIL (TkImaging) extension only:
1001 # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
1002 # *** Uncomment and edit for TOGL extension only:
1003 # -DWITH_TOGL togl.c \
1004 # *** Uncomment these for TOGL extension only:
1005 # -lGL -lGLU -lXext -lXmu \
1007 class PyBuildInstall(install):
1008 # Suppress the warning about installation into the lib_dynload
1009 # directory, which is not in sys.path when running Python during
1010 # installation:
1011 def initialize_options (self):
1012 install.initialize_options(self)
1013 self.warn_dir=0
1015 class PyBuildInstallLib(install_lib):
1016 # Do exactly what install_lib does but make sure correct access modes get
1017 # set on installed directories and files. All installed files with get
1018 # mode 644 unless they are a shared library in which case they will get
1019 # mode 755. All installed directories will get mode 755.
1021 so_ext = sysconfig.get_config_var("SO")
1023 def install(self):
1024 outfiles = install_lib.install(self)
1025 self.set_file_modes(outfiles, 0644, 0755)
1026 self.set_dir_modes(self.install_dir, 0755)
1027 return outfiles
1029 def set_file_modes(self, files, defaultMode, sharedLibMode):
1030 if not self.is_chmod_supported(): return
1031 if not files: return
1033 for filename in files:
1034 if os.path.islink(filename): continue
1035 mode = defaultMode
1036 if filename.endswith(self.so_ext): mode = sharedLibMode
1037 log.info("changing mode of %s to %o", filename, mode)
1038 if not self.dry_run: os.chmod(filename, mode)
1040 def set_dir_modes(self, dirname, mode):
1041 if not self.is_chmod_supported(): return
1042 os.path.walk(dirname, self.set_dir_modes_visitor, mode)
1044 def set_dir_modes_visitor(self, mode, dirname, names):
1045 if os.path.islink(dirname): return
1046 log.info("changing mode of %s to %o", dirname, mode)
1047 if not self.dry_run: os.chmod(dirname, mode)
1049 def is_chmod_supported(self):
1050 return hasattr(os, 'chmod')
1052 SUMMARY = """
1053 Python is an interpreted, interactive, object-oriented programming
1054 language. It is often compared to Tcl, Perl, Scheme or Java.
1056 Python combines remarkable power with very clear syntax. It has
1057 modules, classes, exceptions, very high level dynamic data types, and
1058 dynamic typing. There are interfaces to many system calls and
1059 libraries, as well as to various windowing systems (X11, Motif, Tk,
1060 Mac, MFC). New built-in modules are easily written in C or C++. Python
1061 is also usable as an extension language for applications that need a
1062 programmable interface.
1064 The Python implementation is portable: it runs on many brands of UNIX,
1065 on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't
1066 listed here, it may still be supported, if there's a C compiler for
1067 it. Ask around on comp.lang.python -- or just try compiling Python
1068 yourself.
1071 CLASSIFIERS = """
1072 Development Status :: 3 - Alpha
1073 Development Status :: 6 - Mature
1074 License :: OSI Approved :: Python Software Foundation License
1075 Natural Language :: English
1076 Programming Language :: C
1077 Programming Language :: Python
1078 Topic :: Software Development
1081 def main():
1082 # turn off warnings when deprecated modules are imported
1083 import warnings
1084 warnings.filterwarnings("ignore",category=DeprecationWarning)
1085 setup(# PyPI Metadata (PEP 301)
1086 name = "Python",
1087 version = sys.version.split()[0],
1088 url = "http://www.python.org/%s" % sys.version[:3],
1089 maintainer = "Guido van Rossum and the Python community",
1090 maintainer_email = "python-dev@python.org",
1091 description = "A high-level object-oriented programming language",
1092 long_description = SUMMARY.strip(),
1093 license = "PSF license",
1094 classifiers = filter(None, CLASSIFIERS.split("\n")),
1095 platforms = ["Many"],
1097 # Build info
1098 cmdclass = {'build_ext':PyBuildExt, 'install':PyBuildInstall,
1099 'install_lib':PyBuildInstallLib},
1100 # The struct module is defined here, because build_ext won't be
1101 # called unless there's at least one extension module defined.
1102 ext_modules=[Extension('struct', ['structmodule.c'])],
1104 # Scripts to install
1105 scripts = ['Tools/scripts/pydoc']
1108 # --install-platlib
1109 if __name__ == '__main__':
1110 main()