setup.py revision 96f7d875b7092ec92a24647702757c76cdf9b6a5
1# Autodetecting setup.py script for building the Python extensions 2# 3 4__version__ = "$Revision$" 5 6import sys, os, getopt, imp, re 7 8from distutils import log 9from distutils import sysconfig 10from distutils import text_file 11from distutils.errors import * 12from distutils.core import Extension, setup 13from distutils.command.build_ext import build_ext 14from distutils.command.install import install 15from distutils.command.install_lib import install_lib 16 17# This global variable is used to hold the list of modules to be disabled. 18disabled_module_list = [] 19 20def add_dir_to_list(dirlist, dir): 21 """Add the directory 'dir' to the list 'dirlist' (at the front) if 22 1) 'dir' is not already in 'dirlist' 23 2) 'dir' actually exists, and is a directory.""" 24 if dir is not None and os.path.isdir(dir) and dir not in dirlist: 25 dirlist.insert(0, dir) 26 27def find_file(filename, std_dirs, paths): 28 """Searches for the directory where a given file is located, 29 and returns a possibly-empty list of additional directories, or None 30 if the file couldn't be found at all. 31 32 'filename' is the name of a file, such as readline.h or libcrypto.a. 33 'std_dirs' is the list of standard system directories; if the 34 file is found in one of them, no additional directives are needed. 35 'paths' is a list of additional locations to check; if the file is 36 found in one of them, the resulting list will contain the directory. 37 """ 38 39 # Check the standard locations 40 for dir in std_dirs: 41 f = os.path.join(dir, filename) 42 if os.path.exists(f): return [] 43 44 # Check the additional directories 45 for dir in paths: 46 f = os.path.join(dir, filename) 47 if os.path.exists(f): 48 return [dir] 49 50 # Not found anywhere 51 return None 52 53def find_library_file(compiler, libname, std_dirs, paths): 54 result = compiler.find_library_file(std_dirs + paths, libname) 55 if result is None: 56 return None 57 58 # Check whether the found file is in one of the standard directories 59 dirname = os.path.dirname(result) 60 for p in std_dirs: 61 # Ensure path doesn't end with path separator 62 if p.endswith(os.sep): 63 p = p.strip(os.sep) 64 if p == dirname: 65 return [ ] 66 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" 77 78def module_enabled(extlist, modname): 79 """Returns whether the module 'modname' is present in the list 80 of extensions 'extlist'.""" 81 extlist = [ext for ext in extlist if ext.name == modname] 82 return len(extlist) 83 84def find_module_file(module, dirlist): 85 """Find a module in a set of possible folders. If it is not found 86 return the unadorned filename""" 87 list = find_file(module, [], dirlist) 88 if not list: 89 return module 90 if len(list) > 1: 91 log.info("WARNING: multiple copies of %s found"%module) 92 return os.path.join(list[0], module) 93 94class PyBuildExt(build_ext): 95 96 def build_extensions(self): 97 98 # Detect which modules should be compiled 99 self.detect_modules() 100 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] 104 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.") 111 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) 118 119 moddirlist = [moddir] 120 incdirlist = ['./Include'] 121 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') 129 130 alldirlist = moddirlist + incdirlist 131 132 # Fix up the paths for scripts, too 133 self.distribution.scripts = [os.path.join(srcdir, filename) 134 for filename in self.distribution.scripts] 135 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) ) 145 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) 150 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() 162 163 for ext in self.extensions[:]: 164 if ext.name in remove_modules: 165 self.extensions.remove(ext) 166 167 # When you run "make CC=altcc" or something similar, you really want 168 # those environment variables passed into the setup.py phase. Here's 169 # a small set of useful ones. 170 compiler = os.environ.get('CC') 171 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) 181 182 build_ext.build_extensions(self) 183 184 def build_extension(self, ext): 185 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) 219 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) 236 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' 248 249 return platform 250 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') 255 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') 261 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")) 267 268 try: 269 have_unicode = unicode 270 except NameError: 271 have_unicode = 0 272 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 = [] 279 280 platform = self.get_platform() 281 (srcdir,) = sysconfig.get_config_vars('srcdir') 282 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) 289 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 = [] 294 295 # XXX Omitted modules: gl, pure, dl, SGI-specific modules 296 297 # 298 # The following modules are all pretty straightforward, and compile 299 # on pretty much any POSIXish platform. 300 # 301 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']) ) 305 306 exts.append( Extension('_hotshot', ['_hotshot.c']) ) 307 exts.append( Extension('_weakref', ['_weakref.c']) ) 308 exts.append( Extension('xreadlines', ['xreadlinesmodule.c']) ) 309 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) ) 315 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 ) ) 344 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...) 348 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']) ) 358 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']) ) 363 364 # The sha module implements the SHA checksum algorithm. 365 # (NIST's Secure Hash Algorithm.) 366 exts.append( Extension('sha', ['shamodule.c']) ) 367 368 # Helper module for various ascii-encoders 369 exts.append( Extension('binascii', ['binascii.c']) ) 370 371 # Fred Drake's interface to the Python parser 372 exts.append( Extension('parser', ['parsermodule.c']) ) 373 374 # cStringIO and cPickle 375 exts.append( Extension('cStringIO', ['cStringIO.c']) ) 376 exts.append( Extension('cPickle', ['cPickle.c']) ) 377 378 # Memory-mapped files (also works on Win32). 379 if platform not in ['atheos', 'mac']: 380 exts.append( Extension('mmap', ['mmapmodule.c']) ) 381 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']) ) 388 389 # George Neville-Neil's timing module: 390 exts.append( Extension('timing', ['timingmodule.c']) ) 391 392 # 393 # Here ends the simple stuff. From here on, modules need certain 394 # libraries, are platform-specific, or present other surprises. 395 # 396 397 # Multimedia modules 398 # These don't work for 64-bit platforms!!! 399 # These represent audio samples or images as strings: 400 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']) ) 409 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. 427 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) ) 433 434 # CSV files 435 exts.append( Extension('_csv', ['_csv.c']) ) 436 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/' 444 ] 445 ) 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/' 453 ] ) 454 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']), ) 462 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. 469 470 # Sleepycat Berkeley DB interface. http://www.sleepycat.com 471 # 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 475 # 476 # http://www.sleepycat.com/update/index.html 477 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', 487 ), 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', 494 )}, 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', 502 ), 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', 510 )}, 511 } 512 513 db_search_order = db_try_this.keys() 514 db_search_order.sort() 515 db_search_order.reverse() 516 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 562 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)) 587 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'] ) ) 592 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 601 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 606 607 if (self.compiler.find_library_file(lib_dirs, 'gmp')): 608 exts.append( Extension('mpz', ['mpzmodule.c'], 609 libraries = ['gmp'] ) ) 610 611 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']) ) 619 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) ) 628 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'] 634 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'] 649 650 exts.append( Extension('_curses', ['_cursesmodule.c'], 651 libraries = curses_libs) ) 652 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) ) 658 659 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 663 # 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>. 669 # 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']) ) 689 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']) ) 694 695 # Interface to the Expat XML parser 696 # 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. 703 # 704 # More information on Expat can be found at www.libexpat.org. 705 # 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', 717 ], 718 define_macros = [ 719 ('XML_NS', '1'), 720 ('XML_DTD', '1'), 721 ('BYTEORDER', xmlbo), 722 ('XML_CONTEXT_BYTES','1024'), 723 ], 724 include_dirs = [expatinc] 725 )) 726 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']) ) 733 734 # Platform-specific libraries 735 if platform == 'linux2': 736 # Linux-specific modules 737 exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) ) 738 739 if platform in ('linux2', 'freebsd4'): 740 exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) ) 741 742 if platform == 'sunos5': 743 # SunOS specific modules 744 exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) ) 745 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']) ) 750 751 exts.append( Extension('autoGIL', ['autoGIL.c'], 752 extra_link_args=['-framework', 'CoreFoundation']) ) 753 exts.append( Extension('gestalt', ['gestaltmodule.c'], 754 extra_link_args=['-framework', 'Carbon']) ) 755 exts.append( Extension('MacOS', ['macosmodule.c'], 756 extra_link_args=['-framework', 'Carbon']) ) 757 exts.append( Extension('OSATerminology', ['OSATerminology.c'], 758 extra_link_args=['-framework', 'Carbon']) ) 759 exts.append( Extension('icglue', ['icgluemodule.c'], 760 extra_link_args=['-framework', 'Carbon']) ) 761 exts.append( Extension('_Res', ['res/_Resmodule.c'], 762 extra_link_args=['-framework', 'Carbon']) ) 763 exts.append( Extension('_Snd', ['snd/_Sndmodule.c'], 764 extra_link_args=['-framework', 'Carbon']) ) 765 exts.append( Extension('Nav', ['Nav.c'], 766 extra_link_args=['-framework', 'Carbon']) ) 767 exts.append( Extension('_AE', ['ae/_AEmodule.c'], 768 extra_link_args=['-framework', 'Carbon']) ) 769 exts.append( Extension('_AH', ['ah/_AHmodule.c'], 770 extra_link_args=['-framework', 'Carbon']) ) 771 exts.append( Extension('_App', ['app/_Appmodule.c'], 772 extra_link_args=['-framework', 'Carbon']) ) 773 exts.append( Extension('_CarbonEvt', ['carbonevt/_CarbonEvtmodule.c'], 774 extra_link_args=['-framework', 'Carbon']) ) 775 exts.append( Extension('_CG', ['cg/_CGmodule.c'], 776 extra_link_args=['-framework', 'ApplicationServices']) ) 777 exts.append( Extension('_Cm', ['cm/_Cmmodule.c'], 778 extra_link_args=['-framework', 'Carbon']) ) 779 exts.append( Extension('_Ctl', ['ctl/_Ctlmodule.c'], 780 extra_link_args=['-framework', 'Carbon']) ) 781 exts.append( Extension('_Dlg', ['dlg/_Dlgmodule.c'], 782 extra_link_args=['-framework', 'Carbon']) ) 783 exts.append( Extension('_Drag', ['drag/_Dragmodule.c'], 784 extra_link_args=['-framework', 'Carbon']) ) 785 exts.append( Extension('_Evt', ['evt/_Evtmodule.c'], 786 extra_link_args=['-framework', 'Carbon']) ) 787 exts.append( Extension('_File', ['file/_Filemodule.c'], 788 extra_link_args=['-framework', 'Carbon']) ) 789 exts.append( Extension('_Folder', ['folder/_Foldermodule.c'], 790 extra_link_args=['-framework', 'Carbon']) ) 791 exts.append( Extension('_Fm', ['fm/_Fmmodule.c'], 792 extra_link_args=['-framework', 'Carbon']) ) 793 exts.append( Extension('_Help', ['help/_Helpmodule.c'], 794 extra_link_args=['-framework', 'Carbon']) ) 795 exts.append( Extension('_Icn', ['icn/_Icnmodule.c'], 796 extra_link_args=['-framework', 'Carbon']) ) 797 exts.append( Extension('_IBCarbon', ['ibcarbon/_IBCarbon.c'], 798 extra_link_args=['-framework', 'Carbon']) ) 799 exts.append( Extension('_List', ['list/_Listmodule.c'], 800 extra_link_args=['-framework', 'Carbon']) ) 801 exts.append( Extension('_Menu', ['menu/_Menumodule.c'], 802 extra_link_args=['-framework', 'Carbon']) ) 803 exts.append( Extension('_Mlte', ['mlte/_Mltemodule.c'], 804 extra_link_args=['-framework', 'Carbon']) ) 805 exts.append( Extension('_Qd', ['qd/_Qdmodule.c'], 806 extra_link_args=['-framework', 'Carbon']) ) 807 exts.append( Extension('_Qdoffs', ['qdoffs/_Qdoffsmodule.c'], 808 extra_link_args=['-framework', 'Carbon']) ) 809 exts.append( Extension('_Qt', ['qt/_Qtmodule.c'], 810 extra_link_args=['-framework', 'QuickTime', 811 '-framework', 'Carbon']) ) 812 exts.append( Extension('_Scrap', ['scrap/_Scrapmodule.c'], 813 extra_link_args=['-framework', 'Carbon']) ) 814 exts.append( Extension('_TE', ['te/_TEmodule.c'], 815 extra_link_args=['-framework', 'Carbon']) ) 816 # As there is no standardized place (yet) to put 817 # user-installed Mac libraries on OSX, we search for "waste" 818 # in parent directories of the Python source tree. You 819 # should put a symlink to your Waste installation in the 820 # same folder as your python source tree. Or modify the 821 # next few lines:-) 822 waste_incs = find_file("WASTE.h", [], 823 ['../'*n + 'waste/C_C++ Headers' for n in (0,1,2,3,4)]) 824 waste_libs = find_library_file(self.compiler, "WASTE", [], 825 ["../"*n + "waste/Static Libraries" for n in (0,1,2,3,4)]) 826 if waste_incs != None and waste_libs != None: 827 (srcdir,) = sysconfig.get_config_vars('srcdir') 828 exts.append( Extension('waste', 829 ['waste/wastemodule.c'] + [ 830 os.path.join(srcdir, d) for d in 831 'Mac/Wastemods/WEObjectHandlers.c', 832 'Mac/Wastemods/WETabHooks.c', 833 'Mac/Wastemods/WETabs.c' 834 ], 835 include_dirs = waste_incs + [os.path.join(srcdir, 'Mac/Wastemods')], 836 library_dirs = waste_libs, 837 libraries = ['WASTE'], 838 extra_link_args = ['-framework', 'Carbon'], 839 ) ) 840 exts.append( Extension('_Win', ['win/_Winmodule.c'], 841 extra_link_args=['-framework', 'Carbon']) ) 842 843 self.extensions.extend(exts) 844 845 # Call the method for detecting whether _tkinter can be compiled 846 self.detect_tkinter(inc_dirs, lib_dirs) 847 848 def detect_tkinter_darwin(self, inc_dirs, lib_dirs): 849 # The _tkinter module, using frameworks. Since frameworks are quite 850 # different the UNIX search logic is not sharable. 851 from os.path import join, exists 852 framework_dirs = [ 853 '/System/Library/Frameworks/', 854 '/Library/Frameworks', 855 join(os.getenv('HOME'), '/Library/Frameworks') 856 ] 857 858 # Find the directory that contains the Tcl.framwork and Tk.framework 859 # bundles. 860 # XXX distutils should support -F! 861 for F in framework_dirs: 862 # both Tcl.framework and Tk.framework should be present 863 for fw in 'Tcl', 'Tk': 864 if not exists(join(F, fw + '.framework')): 865 break 866 else: 867 # ok, F is now directory with both frameworks. Continure 868 # building 869 break 870 else: 871 # Tk and Tcl frameworks not found. Normal "unix" tkinter search 872 # will now resume. 873 return 0 874 875 # For 8.4a2, we must add -I options that point inside the Tcl and Tk 876 # frameworks. In later release we should hopefully be able to pass 877 # the -F option to gcc, which specifies a framework lookup path. 878 # 879 include_dirs = [ 880 join(F, fw + '.framework', H) 881 for fw in 'Tcl', 'Tk' 882 for H in 'Headers', 'Versions/Current/PrivateHeaders' 883 ] 884 885 # For 8.4a2, the X11 headers are not included. Rather than include a 886 # complicated search, this is a hard-coded path. It could bail out 887 # if X11 libs are not found... 888 include_dirs.append('/usr/X11R6/include') 889 frameworks = ['-framework', 'Tcl', '-framework', 'Tk'] 890 891 ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], 892 define_macros=[('WITH_APPINIT', 1)], 893 include_dirs = include_dirs, 894 libraries = [], 895 extra_compile_args = frameworks, 896 extra_link_args = frameworks, 897 ) 898 self.extensions.append(ext) 899 return 1 900 901 902 def detect_tkinter(self, inc_dirs, lib_dirs): 903 # The _tkinter module. 904 905 # Rather than complicate the code below, detecting and building 906 # AquaTk is a separate method. Only one Tkinter will be built on 907 # Darwin - either AquaTk, if it is found, or X11 based Tk. 908 platform = self.get_platform() 909 if platform == 'darwin' and \ 910 self.detect_tkinter_darwin(inc_dirs, lib_dirs): 911 return 912 913 # Assume we haven't found any of the libraries or include files 914 # The versions with dots are used on Unix, and the versions without 915 # dots on Windows, for detection by cygwin. 916 tcllib = tklib = tcl_includes = tk_includes = None 917 for version in ['8.4', '84', '8.3', '83', '8.2', 918 '82', '8.1', '81', '8.0', '80']: 919 tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version) 920 tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version) 921 if tklib and tcllib: 922 # Exit the loop when we've found the Tcl/Tk libraries 923 break 924 925 # Now check for the header files 926 if tklib and tcllib: 927 # Check for the include files on Debian, where 928 # they're put in /usr/include/{tcl,tk}X.Y 929 debian_tcl_include = [ '/usr/include/tcl' + version ] 930 debian_tk_include = [ '/usr/include/tk' + version ] + \ 931 debian_tcl_include 932 tcl_includes = find_file('tcl.h', inc_dirs, debian_tcl_include) 933 tk_includes = find_file('tk.h', inc_dirs, debian_tk_include) 934 935 if (tcllib is None or tklib is None and 936 tcl_includes is None or tk_includes is None): 937 # Something's missing, so give up 938 return 939 940 # OK... everything seems to be present for Tcl/Tk. 941 942 include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = [] 943 for dir in tcl_includes + tk_includes: 944 if dir not in include_dirs: 945 include_dirs.append(dir) 946 947 # Check for various platform-specific directories 948 if platform == 'sunos5': 949 include_dirs.append('/usr/openwin/include') 950 added_lib_dirs.append('/usr/openwin/lib') 951 elif os.path.exists('/usr/X11R6/include'): 952 include_dirs.append('/usr/X11R6/include') 953 added_lib_dirs.append('/usr/X11R6/lib') 954 elif os.path.exists('/usr/X11R5/include'): 955 include_dirs.append('/usr/X11R5/include') 956 added_lib_dirs.append('/usr/X11R5/lib') 957 else: 958 # Assume default location for X11 959 include_dirs.append('/usr/X11/include') 960 added_lib_dirs.append('/usr/X11/lib') 961 962 # If Cygwin, then verify that X is installed before proceeding 963 if platform == 'cygwin': 964 x11_inc = find_file('X11/Xlib.h', [], include_dirs) 965 if x11_inc is None: 966 return 967 968 # Check for BLT extension 969 if self.compiler.find_library_file(lib_dirs + added_lib_dirs, 970 'BLT8.0'): 971 defs.append( ('WITH_BLT', 1) ) 972 libs.append('BLT8.0') 973 elif self.compiler.find_library_file(lib_dirs + added_lib_dirs, 974 'BLT'): 975 defs.append( ('WITH_BLT', 1) ) 976 libs.append('BLT') 977 978 # Add the Tcl/Tk libraries 979 libs.append('tk'+ version) 980 libs.append('tcl'+ version) 981 982 if platform in ['aix3', 'aix4']: 983 libs.append('ld') 984 985 # Finally, link with the X11 libraries (not appropriate on cygwin) 986 if platform != "cygwin": 987 libs.append('X11') 988 989 ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], 990 define_macros=[('WITH_APPINIT', 1)] + defs, 991 include_dirs = include_dirs, 992 libraries = libs, 993 library_dirs = added_lib_dirs, 994 ) 995 self.extensions.append(ext) 996 997## # Uncomment these lines if you want to play with xxmodule.c 998## ext = Extension('xx', ['xxmodule.c']) 999## self.extensions.append(ext) 1000 1001 # XXX handle these, but how to detect? 1002 # *** Uncomment and edit for PIL (TkImaging) extension only: 1003 # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ 1004 # *** Uncomment and edit for TOGL extension only: 1005 # -DWITH_TOGL togl.c \ 1006 # *** Uncomment these for TOGL extension only: 1007 # -lGL -lGLU -lXext -lXmu \ 1008 1009class PyBuildInstall(install): 1010 # Suppress the warning about installation into the lib_dynload 1011 # directory, which is not in sys.path when running Python during 1012 # installation: 1013 def initialize_options (self): 1014 install.initialize_options(self) 1015 self.warn_dir=0 1016 1017class PyBuildInstallLib(install_lib): 1018 # Do exactly what install_lib does but make sure correct access modes get 1019 # set on installed directories and files. All installed files with get 1020 # mode 644 unless they are a shared library in which case they will get 1021 # mode 755. All installed directories will get mode 755. 1022 1023 so_ext = sysconfig.get_config_var("SO") 1024 1025 def install(self): 1026 outfiles = install_lib.install(self) 1027 self.set_file_modes(outfiles, 0644, 0755) 1028 self.set_dir_modes(self.install_dir, 0755) 1029 return outfiles 1030 1031 def set_file_modes(self, files, defaultMode, sharedLibMode): 1032 if not self.is_chmod_supported(): return 1033 if not files: return 1034 1035 for filename in files: 1036 if os.path.islink(filename): continue 1037 mode = defaultMode 1038 if filename.endswith(self.so_ext): mode = sharedLibMode 1039 log.info("changing mode of %s to %o", filename, mode) 1040 if not self.dry_run: os.chmod(filename, mode) 1041 1042 def set_dir_modes(self, dirname, mode): 1043 if not self.is_chmod_supported(): return 1044 os.path.walk(dirname, self.set_dir_modes_visitor, mode) 1045 1046 def set_dir_modes_visitor(self, mode, dirname, names): 1047 if os.path.islink(dirname): return 1048 log.info("changing mode of %s to %o", dirname, mode) 1049 if not self.dry_run: os.chmod(dirname, mode) 1050 1051 def is_chmod_supported(self): 1052 return hasattr(os, 'chmod') 1053 1054SUMMARY = """ 1055Python is an interpreted, interactive, object-oriented programming 1056language. It is often compared to Tcl, Perl, Scheme or Java. 1057 1058Python combines remarkable power with very clear syntax. It has 1059modules, classes, exceptions, very high level dynamic data types, and 1060dynamic typing. There are interfaces to many system calls and 1061libraries, as well as to various windowing systems (X11, Motif, Tk, 1062Mac, MFC). New built-in modules are easily written in C or C++. Python 1063is also usable as an extension language for applications that need a 1064programmable interface. 1065 1066The Python implementation is portable: it runs on many brands of UNIX, 1067on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't 1068listed here, it may still be supported, if there's a C compiler for 1069it. Ask around on comp.lang.python -- or just try compiling Python 1070yourself. 1071""" 1072 1073CLASSIFIERS = """ 1074Development Status :: 3 - Alpha 1075Development Status :: 6 - Mature 1076License :: OSI Approved :: Python Software Foundation License 1077Natural Language :: English 1078Programming Language :: C 1079Programming Language :: Python 1080Topic :: Software Development 1081""" 1082 1083def main(): 1084 # turn off warnings when deprecated modules are imported 1085 import warnings 1086 warnings.filterwarnings("ignore",category=DeprecationWarning) 1087 setup(# PyPI Metadata (PEP 301) 1088 name = "Python", 1089 version = sys.version.split()[0], 1090 url = "http://www.python.org/%s" % sys.version[:3], 1091 maintainer = "Guido van Rossum and the Python community", 1092 maintainer_email = "python-dev@python.org", 1093 description = "A high-level object-oriented programming language", 1094 long_description = SUMMARY.strip(), 1095 license = "PSF license", 1096 classifiers = filter(None, CLASSIFIERS.split("\n")), 1097 platforms = ["Many"], 1098 1099 # Build info 1100 cmdclass = {'build_ext':PyBuildExt, 'install':PyBuildInstall, 1101 'install_lib':PyBuildInstallLib}, 1102 # The struct module is defined here, because build_ext won't be 1103 # called unless there's at least one extension module defined. 1104 ext_modules=[Extension('struct', ['structmodule.c'])], 1105 1106 # Scripts to install 1107 scripts = ['Tools/scripts/pydoc'] 1108 ) 1109 1110# --install-platlib 1111if __name__ == '__main__': 1112 main() 1113