setup.py 49.8 KB
Newer Older
1 2
# Autodetecting setup.py script for building the Python extensions
#
3

4 5
__version__ = "$Revision$"

6
import sys, os, getopt, imp, re
7 8

from distutils import log
9
from distutils import sysconfig
10
from distutils import text_file
11
from distutils.errors import *
12 13
from distutils.core import Extension, setup
from distutils.command.build_ext import build_ext
14
from distutils.command.install import install
15
from distutils.command.install_lib import install_lib
16 17 18 19

# This global variable is used to hold the list of modules to be disabled.
disabled_module_list = []

20 21 22 23
def add_dir_to_list(dirlist, dir):
    """Add the directory 'dir' to the list 'dirlist' (at the front) if
    1) 'dir' is not already in 'dirlist'
    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 26
        dirlist.insert(0, dir)

27 28 29 30
def find_file(filename, std_dirs, paths):
    """Searches for the directory where a given file is located,
    and returns a possibly-empty list of additional directories, or None
    if the file couldn't be found at all.
31

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
    'filename' is the name of a file, such as readline.h or libcrypto.a.
    'std_dirs' is the list of standard system directories; if the
        file is found in one of them, no additional directives are needed.
    'paths' is a list of additional locations to check; if the file is
        found in one of them, the resulting list will contain the directory.
    """

    # Check the standard locations
    for dir in std_dirs:
        f = os.path.join(dir, filename)
        if os.path.exists(f): return []

    # Check the additional directories
    for dir in paths:
        f = os.path.join(dir, filename)
        if os.path.exists(f):
            return [dir]

    # Not found anywhere
51 52
    return None

53
def find_library_file(compiler, libname, std_dirs, paths):
54 55 56
    result = compiler.find_library_file(std_dirs + paths, libname)
    if result is None:
        return None
57

58 59 60 61
    # Check whether the found file is in one of the standard directories
    dirname = os.path.dirname(result)
    for p in std_dirs:
        # Ensure path doesn't end with path separator
62
        p = p.rstrip(os.sep)
63 64
        if p == dirname:
            return [ ]
65

66 67 68 69
    # Otherwise, it must have been in one of the additional directories,
    # so we have to figure out which one.
    for p in paths:
        # Ensure path doesn't end with path separator
70
        p = p.rstrip(os.sep)
71 72 73 74
        if p == dirname:
            return [p]
    else:
        assert False, "Internal error: Path not found in std_dirs or paths"
Tim Peters's avatar
Tim Peters committed
75

76 77 78 79 80
def module_enabled(extlist, modname):
    """Returns whether the module 'modname' is present in the list
    of extensions 'extlist'."""
    extlist = [ext for ext in extlist if ext.name == modname]
    return len(extlist)
81

82 83 84 85 86 87 88
def find_module_file(module, dirlist):
    """Find a module in a set of possible folders. If it is not found
    return the unadorned filename"""
    list = find_file(module, [], dirlist)
    if not list:
        return module
    if len(list) > 1:
89
        log.info("WARNING: multiple copies of %s found"%module)
90
    return os.path.join(list[0], module)
91

92
class PyBuildExt(build_ext):
93

94 95 96 97 98 99 100 101
    def build_extensions(self):

        # Detect which modules should be compiled
        self.detect_modules()

        # Remove modules that are present on the disabled list
        self.extensions = [ext for ext in self.extensions
                           if ext.name not in disabled_module_list]
102

103 104 105
        # Fix up the autodetected modules, prefixing all the source files
        # with Modules/ and adding Python's include directory to the path.
        (srcdir,) = sysconfig.get_config_vars('srcdir')
Guido van Rossum's avatar
Guido van Rossum committed
106 107 108
        if not srcdir:
            # Maybe running on Windows but not using CYGWIN?
            raise ValueError("No source directory; cannot proceed.")
109

110 111
        # Figure out the location of the source code for extension modules
        moddir = os.path.join(os.getcwd(), srcdir, 'Modules')
112 113 114 115
        moddir = os.path.normpath(moddir)
        srcdir, tail = os.path.split(moddir)
        srcdir = os.path.normpath(srcdir)
        moddir = os.path.normpath(moddir)
116

117 118
        moddirlist = [moddir]
        incdirlist = ['./Include']
119

120 121
        # Platform-dependent module source and include directories
        platform = self.get_platform()
122
        if platform in ('darwin', 'mac'):
123 124 125 126
            # Mac OS X also includes some mac-specific modules
            macmoddir = os.path.join(os.getcwd(), srcdir, 'Mac/Modules')
            moddirlist.append(macmoddir)
            incdirlist.append('./Mac/Include')
127

128 129
        alldirlist = moddirlist + incdirlist

130 131 132 133
        # Fix up the paths for scripts, too
        self.distribution.scripts = [os.path.join(srcdir, filename)
                                     for filename in self.distribution.scripts]

134
        for ext in self.extensions[:]:
135
            ext.sources = [ find_module_file(filename, moddirlist)
136
                            for filename in ext.sources ]
137 138 139
            if ext.depends is not None:
                ext.depends = [find_module_file(filename, alldirlist)
                               for filename in ext.depends]
140 141 142
            ext.include_dirs.append( '.' ) # to get config.h
            for incdir in incdirlist:
                ext.include_dirs.append( os.path.join(srcdir, incdir) )
143

144
            # If a module has already been built statically,
145
            # don't build it here
146
            if ext.name in sys.builtin_module_names:
147
                self.extensions.remove(ext)
148

149 150 151 152 153 154 155 156 157 158 159
        if platform != 'mac':
            # Parse Modules/Setup to figure out which modules are turned
            # on in the file.
            input = text_file.TextFile('Modules/Setup', join_lines=1)
            remove_modules = []
            while 1:
                line = input.readline()
                if not line: break
                line = line.split()
                remove_modules.append( line[0] )
            input.close()
Tim Peters's avatar
Tim Peters committed
160

161 162 163
            for ext in self.extensions[:]:
                if ext.name in remove_modules:
                    self.extensions.remove(ext)
164

165 166 167 168 169 170 171 172 173
        # When you run "make CC=altcc" or something similar, you really want
        # those environment variables passed into the setup.py phase.  Here's
        # a small set of useful ones.
        compiler = os.environ.get('CC')
        linker_so = os.environ.get('LDSHARED')
        args = {}
        # unfortunately, distutils doesn't let us provide separate C and C++
        # compilers
        if compiler is not None:
174 175
            (ccshared,opt,base) = sysconfig.get_config_vars('CCSHARED','OPT','BASECFLAGS')
            args['compiler_so'] = compiler + ' ' + opt + ' ' + ccshared + ' ' + base
176
        if linker_so is not None:
177
            args['linker_so'] = linker_so
178 179
        self.compiler.set_executables(**args)

180 181
        build_ext.build_extensions(self)

182 183 184 185 186 187 188
    def build_extension(self, ext):

        try:
            build_ext.build_extension(self, ext)
        except (CCompilerError, DistutilsError), why:
            self.announce('WARNING: building of extension "%s" failed: %s' %
                          (ext.name, sys.exc_info()[1]))
189
            return
190 191 192
        # Workaround for Mac OS X: The Carbon-based modules cannot be
        # reliably imported into a command-line Python
        if 'Carbon' in ext.extra_link_args:
193 194 195 196
            self.announce(
                'WARNING: skipping import check for Carbon-based "%s"' %
                ext.name)
            return
197 198 199 200 201 202
        # Workaround for Cygwin: Cygwin currently has fork issues when many
        # modules have been imported
        if self.get_platform() == 'cygwin':
            self.announce('WARNING: skipping import check for Cygwin-based "%s"'
                % ext.name)
            return
Michael W. Hudson's avatar
Michael W. Hudson committed
203 204 205
        ext_filename = os.path.join(
            self.build_lib,
            self.get_ext_filename(self.get_ext_fullname(ext.name)))
206
        try:
Michael W. Hudson's avatar
Michael W. Hudson committed
207
            imp.load_dynamic(ext.name, ext_filename)
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
        except ImportError, why:
            self.announce('*** WARNING: renaming "%s" since importing it'
                          ' failed: %s' % (ext.name, why), level=3)
            assert not self.inplace
            basename, tail = os.path.splitext(ext_filename)
            newname = basename + "_failed" + tail
            if os.path.exists(newname):
                os.remove(newname)
            os.rename(ext_filename, newname)

            # XXX -- This relies on a Vile HACK in
            # distutils.command.build_ext.build_extension().  The
            # _built_objects attribute is stored there strictly for
            # use here.
            # If there is a failure, _built_objects may not be there,
            # so catch the AttributeError and move on.
            try:
                for filename in self._built_objects:
                    os.remove(filename)
            except AttributeError:
                self.announce('unable to remove files (ignored)')
229 230
        except:
            exc_type, why, tb = sys.exc_info()
231 232 233
            self.announce('*** WARNING: importing extension "%s" '
                          'failed with %s: %s' % (ext.name, exc_type, why),
                          level=3)
234

235
    def get_platform (self):
236 237 238 239
        # Get value of sys.platform
        platform = sys.platform
        if platform[:6] =='cygwin':
            platform = 'cygwin'
240 241
        elif platform[:4] =='beos':
            platform = 'beos'
242 243
        elif platform[:6] == 'darwin':
            platform = 'darwin'
244 245
        elif platform[:6] == 'atheos':
            platform = 'atheos'
246 247
        elif platform[:4] == 'osf1':
            platform = 'osf1'
248

249
        return platform
250

251
    def detect_modules(self):
252
        # Ensure that /usr/local is always used
253 254 255
        add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
        add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')

256 257 258 259 260 261
        # fink installs lots of goodies in /sw/... - make sure we
        # check there
        if sys.platform == "darwin":
            add_dir_to_list(self.compiler.library_dirs, '/sw/lib')
            add_dir_to_list(self.compiler.include_dirs, '/sw/include')

Michael W. Hudson's avatar
Michael W. Hudson committed
262 263 264 265 266
        if os.path.normpath(sys.prefix) != '/usr':
            add_dir_to_list(self.compiler.library_dirs,
                            sysconfig.get_config_var("LIBDIR"))
            add_dir_to_list(self.compiler.include_dirs,
                            sysconfig.get_config_var("INCLUDEDIR"))
267

268 269 270 271 272
        try:
            have_unicode = unicode
        except NameError:
            have_unicode = 0

273 274 275 276
        # lib_dirs and inc_dirs are used to search for files;
        # if a file is found in one of those directories, it can
        # be assumed that no additional -I,-L directives are needed.
        lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib']
277
        inc_dirs = self.compiler.include_dirs + ['/usr/include']
278 279
        exts = []

280
        platform = self.get_platform()
281
        (srcdir,) = sysconfig.get_config_vars('srcdir')
282

283 284 285 286 287 288 289
        # Check for AtheOS which has libraries in non-standard locations
        if platform == 'atheos':
            lib_dirs += ['/system/libs', '/atheos/autolnk/lib']
            lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep)
            inc_dirs += ['/system/include', '/atheos/autolnk/include']
            inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep)

290
        # OSF/1 has some stuff in /usr/ccs/lib (like -ldb)
291
        if platform == 'osf1':
292 293
            lib_dirs += ['/usr/ccs/lib']

294 295
        # Check for MacOS X, which doesn't need libm.a at all
        math_libs = ['m']
296
        if platform in ['darwin', 'beos', 'mac']:
297
            math_libs = []
298

299 300 301 302 303 304
        # XXX Omitted modules: gl, pure, dl, SGI-specific modules

        #
        # The following modules are all pretty straightforward, and compile
        # on pretty much any POSIXish platform.
        #
305

306 307 308
        # Some modules that are normally always on:
        exts.append( Extension('regex', ['regexmodule.c', 'regexpr.c']) )
        exts.append( Extension('pcre', ['pcremodule.c', 'pypcre.c']) )
309

Fred Drake's avatar
Fred Drake committed
310
        exts.append( Extension('_hotshot', ['_hotshot.c']) )
311
        exts.append( Extension('_weakref', ['_weakref.c']) )
Andrew M. Kuchling's avatar
Andrew M. Kuchling committed
312
        exts.append( Extension('xreadlines', ['xreadlinesmodule.c']) )
313 314 315 316

        # array objects
        exts.append( Extension('array', ['arraymodule.c']) )
        # complex math library functions
317 318
        exts.append( Extension('cmath', ['cmathmodule.c'],
                               libraries=math_libs) )
319

320
        # math library functions, e.g. sin()
321 322
        exts.append( Extension('math',  ['mathmodule.c'],
                               libraries=math_libs) )
323 324 325
        # fast string operations implemented in C
        exts.append( Extension('strop', ['stropmodule.c']) )
        # time operations and variables
326 327
        exts.append( Extension('time', ['timemodule.c'],
                               libraries=math_libs) )
328 329
        exts.append( Extension('datetime', ['datetimemodule.c'],
                               libraries=math_libs) )
330
        # random number generator implemented in C
Tim Peters's avatar
Tim Peters committed
331
        exts.append( Extension("_random", ["_randommodule.c"]) )
332 333
        # fast iterator tools implemented in C
        exts.append( Extension("itertools", ["itertoolsmodule.c"]) )
334 335
        # operator.add() and similar goodies
        exts.append( Extension('operator', ['operator.c']) )
336
        # Python C API test module
337
        exts.append( Extension('_testcapi', ['_testcapimodule.c']) )
338
        # static Unicode character database
339 340
        if have_unicode:
            exts.append( Extension('unicodedata', ['unicodedata.c']) )
341
        # access to ISO C locale support
342
        if platform in ['cygwin', 'aix4']:
343 344 345 346 347
            locale_libs = ['intl']
        else:
            locale_libs = []
        exts.append( Extension('_locale', ['_localemodule.c'],
                               libraries=locale_libs ) )
348 349 350 351 352 353 354

        # Modules with some UNIX dependencies -- on by default:
        # (If you have a really backward UNIX, select and socket may not be
        # supported...)

        # fcntl(2) and ioctl(2)
        exts.append( Extension('fcntl', ['fcntlmodule.c']) )
355 356
        if platform not in ['mac']:
                # pwd(3)
Tim Peters's avatar
Tim Peters committed
357 358 359
            exts.append( Extension('pwd', ['pwdmodule.c']) )
            # grp(3)
            exts.append( Extension('grp', ['grpmodule.c']) )
360 361 362 363
        # select(2); not on ancient System V
        exts.append( Extension('select', ['selectmodule.c']) )

        # The md5 module implements the RSA Data Security, Inc. MD5
Fred Drake's avatar
Fred Drake committed
364 365
        # Message-Digest Algorithm, described in RFC 1321.  The
        # necessary files md5c.c and md5.h are included here.
366 367 368 369 370 371 372 373 374 375 376 377
        exts.append( Extension('md5', ['md5module.c', 'md5c.c']) )

        # The sha module implements the SHA checksum algorithm.
        # (NIST's Secure Hash Algorithm.)
        exts.append( Extension('sha', ['shamodule.c']) )

        # Helper module for various ascii-encoders
        exts.append( Extension('binascii', ['binascii.c']) )

        # Fred Drake's interface to the Python parser
        exts.append( Extension('parser', ['parsermodule.c']) )

378
        # cStringIO and cPickle
379 380 381 382
        exts.append( Extension('cStringIO', ['cStringIO.c']) )
        exts.append( Extension('cPickle', ['cPickle.c']) )

        # Memory-mapped files (also works on Win32).
383
        if platform not in ['atheos', 'mac']:
384
            exts.append( Extension('mmap', ['mmapmodule.c']) )
385 386 387 388

        # Lance Ellinghaus's modules:
        # enigma-inspired encryption
        exts.append( Extension('rotor', ['rotormodule.c']) )
389
        if platform not in ['mac']:
Tim Peters's avatar
Tim Peters committed
390 391
            # syslog daemon interface
            exts.append( Extension('syslog', ['syslogmodule.c']) )
392 393 394 395 396

        # George Neville-Neil's timing module:
        exts.append( Extension('timing', ['timingmodule.c']) )

        #
397 398
        # Here ends the simple stuff.  From here on, modules need certain
        # libraries, are platform-specific, or present other surprises.
399 400 401 402 403 404
        #

        # Multimedia modules
        # These don't work for 64-bit platforms!!!
        # These represent audio samples or images as strings:

405
        # Disabled on 64-bit platforms
406 407 408 409 410 411 412 413 414
        if sys.maxint != 9223372036854775807L:
            # Operations on audio samples
            exts.append( Extension('audioop', ['audioop.c']) )
            # Operations on images
            exts.append( Extension('imageop', ['imageop.c']) )
            # Read SGI RGB image files (but coded portably)
            exts.append( Extension('rgbimg', ['rgbimgmodule.c']) )

        # readline
415 416
        if self.compiler.find_library_file(lib_dirs, 'readline'):
            readline_libs = ['readline']
417 418 419
            if self.compiler.find_library_file(lib_dirs,
                                                 'ncurses'):
                readline_libs.append('ncurses')
420 421
            elif self.compiler.find_library_file(lib_dirs, 'curses'):
                readline_libs.append('curses')
422
            elif self.compiler.find_library_file(lib_dirs +
423 424 425
                                               ['/usr/lib/termcap'],
                                               'termcap'):
                readline_libs.append('termcap')
426
            exts.append( Extension('readline', ['readline.c'],
427
                                   library_dirs=['/usr/lib/termcap'],
428
                                   libraries=readline_libs) )
429 430
        if platform not in ['mac']:
                # crypt module.
Tim Peters's avatar
Tim Peters committed
431 432 433 434 435 436

            if self.compiler.find_library_file(lib_dirs, 'crypt'):
                libs = ['crypt']
            else:
                libs = []
            exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
437

438 439 440
        # CSV files
        exts.append( Extension('_csv', ['_csv.c']) )

441
        # socket(2)
442
        exts.append( Extension('_socket', ['socketmodule.c'],
443
                               depends = ['socketmodule.h']) )
444
        # Detect SSL support for the socket module (via _ssl)
445
        ssl_incs = find_file('openssl/ssl.h', inc_dirs,
446 447 448
                             ['/usr/local/ssl/include',
                              '/usr/contrib/ssl/include/'
                             ]
449
                             )
450 451 452 453 454
        if ssl_incs is not None:
            krb5_h = find_file('krb5.h', inc_dirs,
                               ['/usr/kerberos/include'])
            if krb5_h:
                ssl_incs += krb5_h
455
        ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
456 457 458
                                     ['/usr/local/ssl/lib',
                                      '/usr/contrib/ssl/lib/'
                                     ] )
459

460 461
        if (ssl_incs is not None and
            ssl_libs is not None):
462
            exts.append( Extension('_ssl', ['_ssl.c'],
463
                                   include_dirs = ssl_incs,
464
                                   library_dirs = ssl_libs,
465
                                   libraries = ['ssl', 'crypto'],
466
                                   depends = ['socketmodule.h']), )
467 468 469 470 471 472 473 474

        # Modules that provide persistent dictionary-like semantics.  You will
        # probably want to arrange for at least one of them to be available on
        # your machine, though none are defined by default because of library
        # dependencies.  The Python module anydbm.py provides an
        # implementation independent wrapper for these; dumbdbm.py provides
        # similar functionality (but slower of course) implemented in Python.

475
        # Sleepycat Berkeley DB interface.  http://www.sleepycat.com
476
        #
477 478 479
        # This requires the Sleepycat DB code. The earliest supported version
        # of that library is 3.0, the latest supported version is 4.1.  A list
        # of available releases can be found at
480
        #
481
        # http://www.sleepycat.com/update/index.html
482 483

        # when sorted in reverse order, keys for this dict must appear in the
484
        # order you wish to search - e.g., search for db4 before db3
485
        db_try_this = {
486 487 488
            'db4': {'libs': ('db-4.1', 'db-4.0',),
                    'libdirs': ('/usr/local/BerkeleyDB.4.1/lib',
                                '/usr/local/BerkeleyDB.4.0/lib',
489
                                '/usr/local/lib',
490 491 492
                                '/opt/sfw',
                                '/sw/lib',
                                ),
493 494
                    'incdirs': ('/usr/local/BerkeleyDB.4.1/include',
                                '/usr/local/BerkeleyDB.4.0/include',
495 496 497 498
                                '/usr/local/include/db4',
                                '/opt/sfw/include/db4',
                                '/sw/include/db4',
                                '/usr/include/db4',
499
                                )},
500
            'db3': {'libs': ('db-3.3', 'db-3.2', 'db-3.1'),
501 502 503
                    'libdirs': ('/usr/local/BerkeleyDB.3.3/lib',
                                '/usr/local/BerkeleyDB.3.2/lib',
                                '/usr/local/BerkeleyDB.3.1/lib',
504
                                '/usr/local/lib',
505
                                '/opt/sfw/lib',
506 507 508 509 510
                                '/sw/lib',
                                ),
                    'incdirs': ('/usr/local/BerkeleyDB.3.3/include',
                                '/usr/local/BerkeleyDB.3.2/include',
                                '/usr/local/BerkeleyDB.3.1/include',
511
                                '/usr/local/include/db3',
512 513
                                '/opt/sfw/include/db3',
                                '/sw/include/db3',
514
                                '/usr/include/db3',
515
                                )},
516 517 518 519 520
            }

        db_search_order = db_try_this.keys()
        db_search_order.sort()
        db_search_order.reverse()
Tim Peters's avatar
Tim Peters committed
521

522 523
        class found(Exception): pass
        try:
524 525 526 527 528 529 530 531 532 533
            # See whether there is a Sleepycat header in the standard
            # search path.
            std_dbinc = None
            for d in inc_dirs:
                f = os.path.join(d, "db.h")
                if os.path.exists(f):
                    f = open(f).read()
                    m = re.search(r"#define\WDB_VERSION_MAJOR\W([1-9]+)", f)
                    if m:
                        std_dbinc = 'db' + m.group(1)
534 535 536
            for dbkey in db_search_order:
                dbd = db_try_this[dbkey]
                for dblib in dbd['libs']:
537 538 539 540 541 542 543 544 545 546 547
                    # Prefer version-specific includes over standard
                    # include locations.
                    db_incs = find_file('db.h', [], dbd['incdirs'])
                    dblib_dir = find_library_file(self.compiler,
                                                  dblib,
                                                  lib_dirs,
                                                  list(dbd['libdirs']))
                    if (db_incs or dbkey == std_dbinc) and \
                           dblib_dir is not None:
                        dblibs = [dblib]
                        raise found
548
        except found:
549
            dblibs = [dblib]
550 551 552 553 554 555 556 557
            # A default source build puts Berkeley DB in something like
            # /usr/local/Berkeley.3.3 and the lib dir under that isn't
            # normally on ld.so's search path, unless the sysadmin has hacked
            # /etc/ld.so.conf.  We add the directory to runtime_library_dirs
            # so the proper -R/--rpath flags get passed to the linker.  This
            # is usually correct and most trouble free, but may cause problems
            # in some unusual system configurations (e.g. the directory is on
            # an NFS server that goes away).
558
            exts.append(Extension('_bsddb', ['_bsddb.c'],
559 560
                                  library_dirs=dblib_dir,
                                  runtime_library_dirs=dblib_dir,
561 562
                                  include_dirs=db_incs,
                                  libraries=dblibs))
563 564 565 566 567
        else:
            db_incs = None
            dblibs = []
            dblib_dir = None

568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590

        # Look for Berkeley db 1.85.   Note that it is built as a different
        # module name so it can be included even when later versions are
        # available.  A very restrictive search is performed to avoid
        # accidentally building this module with a later version of the
        # underlying db library.  May BSD-ish Unixes incorporate db 1.85
        # symbols into libc and place the include file in /usr/include.
        f = "/usr/include/db.h"
        if os.path.exists(f):
            data = open(f).read()
            m = re.search(r"#s*define\s+HASHVERSION\s+2\s*", data)
            if m is not None:
                # bingo - old version used hash file format version 2
                ### XXX this should be fixed to not be platform-dependent
                ### but I don't have direct access to an osf1 platform and
                ### seemed to be muffing the search somehow
                libraries = platform == "osf1" and ['db'] or None
                if libraries is not None:
                    exts.append(Extension('bsddb185', ['bsddbmodule.c'],
                                          libraries=libraries))
                else:
                    exts.append(Extension('bsddb185', ['bsddbmodule.c']))

591
        # The standard Unix dbm module:
592
        if platform not in ['cygwin']:
593 594 595 596 597 598
            if find_file("ndbm.h", inc_dirs, []) is not None:
                # Some systems have -lndbm, others don't
                if self.compiler.find_library_file(lib_dirs, 'ndbm'):
                    ndbm_libs = ['ndbm']
                else:
                    ndbm_libs = []
599
                exts.append( Extension('dbm', ['dbmmodule.c'],
600
                                       define_macros=[('HAVE_NDBM_H',None)],
601
                                       libraries = ndbm_libs ) )
602 603 604 605
            elif (self.compiler.find_library_file(lib_dirs, 'gdbm')
                  and find_file("gdbm/ndbm.h", inc_dirs, []) is not None):
                exts.append( Extension('dbm', ['dbmmodule.c'],
                                       define_macros=[('HAVE_GDBM_NDBM_H',None)],
606 607 608
                                       libraries = ['gdbm'] ) )
            elif db_incs is not None:
                exts.append( Extension('dbm', ['dbmmodule.c'],
609 610
                                       library_dirs=dblib_dir,
                                       runtime_library_dirs=dblib_dir,
611
                                       include_dirs=db_incs,
612 613
                                       define_macros=[('HAVE_BERKDB_H',None),
                                                      ('DB_DBM_HSEARCH',None)],
614
                                       libraries=dblibs))
615

616 617 618 619 620 621
        # Anthony Baxter's gdbm module.  GNU dbm(3) will require -lgdbm:
        if (self.compiler.find_library_file(lib_dirs, 'gdbm')):
            exts.append( Extension('gdbm', ['gdbmmodule.c'],
                                   libraries = ['gdbm'] ) )

        # The mpz module interfaces to the GNU Multiple Precision library.
622
        # You need to ftp the GNU MP library.
623 624
        # This was originally written and tested against GMP 1.2 and 1.3.2.
        # It has been modified by Rob Hooft to work with 2.0.2 as well, but I
625 626 627 628
        # haven't tested it recently, and it definitely doesn't work with
        # GMP 4.0.  For more complete modules, refer to
        # http://gmpy.sourceforge.net and
        # http://www.egenix.com/files/python/mxNumber.html
629

630
        # A compatible MP library unencumbered by the GPL also exists.  It was
631 632 633 634 635 636 637 638 639 640
        # posted to comp.sources.misc in volume 40 and is widely available from
        # FTP archive sites. One URL for it is:
        # ftp://gatekeeper.dec.com/.b/usenet/comp.sources.misc/volume40/fgmp/part01.Z

        if (self.compiler.find_library_file(lib_dirs, 'gmp')):
            exts.append( Extension('mpz', ['mpzmodule.c'],
                                   libraries = ['gmp'] ) )


        # Unix-only modules
641
        if platform not in ['mac', 'win32']:
642 643 644
            # Steen Lumholt's termios module
            exts.append( Extension('termios', ['termios.c']) )
            # Jeremy Hylton's rlimit interface
Tim Peters's avatar
Tim Peters committed
645
            if platform not in ['atheos']:
646
                exts.append( Extension('resource', ['resource.c']) )
647

648
            # Sun yellow pages. Some systems have the functions in libc.
649
            if platform not in ['cygwin', 'atheos']:
650 651 652 653 654 655
                if (self.compiler.find_library_file(lib_dirs, 'nsl')):
                    libs = ['nsl']
                else:
                    libs = []
                exts.append( Extension('nis', ['nismodule.c'],
                                       libraries = libs) )
656 657

        # Curses support, requring the System V version of curses, often
658
        # provided by the ncurses library.
659
        if platform == 'sunos4':
660
            inc_dirs += ['/usr/5include']
661 662 663 664 665 666
            lib_dirs += ['/usr/5lib']

        if (self.compiler.find_library_file(lib_dirs, 'ncurses')):
            curses_libs = ['ncurses']
            exts.append( Extension('_curses', ['_cursesmodule.c'],
                                   libraries = curses_libs) )
Fred Drake's avatar
Fred Drake committed
667 668
        elif (self.compiler.find_library_file(lib_dirs, 'curses')
              and platform != 'darwin'):
669 670
                # OSX has an old Berkeley curses, not good enough for
                # the _curses module.
671 672
            if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
                curses_libs = ['curses', 'terminfo']
673
            elif (self.compiler.find_library_file(lib_dirs, 'termcap')):
674
                curses_libs = ['curses', 'termcap']
675 676
            else:
                curses_libs = ['curses']
677

678 679
            exts.append( Extension('_curses', ['_cursesmodule.c'],
                                   libraries = curses_libs) )
680

681
        # If the curses module is enabled, check for the panel module
682
        if (module_enabled(exts, '_curses') and
683 684 685
            self.compiler.find_library_file(lib_dirs, 'panel')):
            exts.append( Extension('_curses_panel', ['_curses_panel.c'],
                                   libraries = ['panel'] + curses_libs) )
686 687


688 689 690 691 692 693 694 695 696 697 698 699
        # Andrew Kuchling's zlib module.  Note that some versions of zlib
        # 1.1.3 have security problems.  See CERT Advisory CA-2002-07:
        # http://www.cert.org/advisories/CA-2002-07.html
        #
        # zlib 1.1.4 is fixed, but at least one vendor (RedHat) has decided to
        # patch its zlib 1.1.3 package instead of upgrading to 1.1.4.  For
        # now, we still accept 1.1.3, because we think it's difficult to
        # exploit this in Python, and we'd rather make it RedHat's problem
        # than our problem <wink>.
        #
        # You can upgrade zlib to version 1.1.4 yourself by going to
        # http://www.gzip.org/zlib/
700 701 702 703
        zlib_inc = find_file('zlib.h', [], inc_dirs)
        if zlib_inc is not None:
            zlib_h = zlib_inc[0] + '/zlib.h'
            version = '"0.0.0"'
704
            version_req = '"1.1.3"'
705 706 707 708 709
            fp = open(zlib_h)
            while 1:
                line = fp.readline()
                if not line:
                    break
710
                if line.startswith('#define ZLIB_VERSION'):
711 712 713 714 715 716
                    version = line.split()[2]
                    break
            if version >= version_req:
                if (self.compiler.find_library_file(lib_dirs, 'z')):
                    exts.append( Extension('zlib', ['zlibmodule.c'],
                                           libraries = ['z']) )
717

718 719 720 721 722
        # Gustavo Niemeyer's bz2 module.
        if (self.compiler.find_library_file(lib_dirs, 'bz2')):
            exts.append( Extension('bz2', ['bz2module.c'],
                                   libraries = ['bz2']) )

723 724
        # Interface to the Expat XML parser
        #
725 726 727 728 729 730 731 732 733
        # Expat was written by James Clark and is now maintained by a
        # group of developers on SourceForge; see www.libexpat.org for
        # more information.  The pyexpat module was written by Paul
        # Prescod after a prototype by Jack Jansen.  Source of Expat
        # 1.95.2 is included in Modules/expat/.  Usage of a system
        # shared libexpat.so/expat.dll is not advised.
        #
        # More information on Expat can be found at www.libexpat.org.
        #
734
        if sys.byteorder == "little":
735
            xmlbo = "1234"
736
        else:
737
            xmlbo = "4321"
738
        expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')
739 740 741 742 743 744 745 746 747 748
        exts.append(Extension('pyexpat',
                              sources = [
            'pyexpat.c',
            'expat/xmlparse.c',
            'expat/xmlrole.c',
            'expat/xmltok.c',
            ],
                              define_macros = [
            ('XML_NS', '1'),
            ('XML_DTD', '1'),
749
            ('BYTEORDER', xmlbo),
750 751
            ('XML_CONTEXT_BYTES','1024'),
            ],
752
                              include_dirs = [expatinc]
Tim Peters's avatar
Tim Peters committed
753
                               ))
754

755
        # Dynamic loading module
756 757 758
        if sys.maxint == 0x7fffffff:
            # This requires sizeof(int) == sizeof(long) == sizeof(char*)
            dl_inc = find_file('dlfcn.h', [], inc_dirs)
759
            if (dl_inc is not None) and (platform not in ['atheos', 'darwin']):
760
                exts.append( Extension('dl', ['dlmodule.c']) )
761

762
        # Platform-specific libraries
763
        if platform == 'linux2':
764 765
            # Linux-specific modules
            exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
766

767
        if platform in ('linux2', 'freebsd4'):
768
            exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
769

770
        if platform == 'sunos5':
771
            # SunOS specific modules
772
            exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
773

774
        if platform == 'darwin':
775
            # Mac OS X specific modules.
776
            exts.append( Extension('_CF', ['cf/_CFmodule.c', 'cf/pycfbridge.c'],
777
                        extra_link_args=['-framework', 'CoreFoundation']) )
778

779 780
            exts.append( Extension('autoGIL', ['autoGIL.c'],
                        extra_link_args=['-framework', 'CoreFoundation']) )
781
            exts.append( Extension('gestalt', ['gestaltmodule.c'],
782
                        extra_link_args=['-framework', 'Carbon']) )
783
            exts.append( Extension('MacOS', ['macosmodule.c'],
784
                        extra_link_args=['-framework', 'Carbon']) )
785 786
            exts.append( Extension('OSATerminology', ['OSATerminology.c'],
                        extra_link_args=['-framework', 'Carbon']) )
787
            exts.append( Extension('icglue', ['icgluemodule.c'],
788
                        extra_link_args=['-framework', 'Carbon']) )
789
            exts.append( Extension('_Res', ['res/_Resmodule.c'],
790
                        extra_link_args=['-framework', 'Carbon']) )
791
            exts.append( Extension('_Snd', ['snd/_Sndmodule.c'],
792
                        extra_link_args=['-framework', 'Carbon']) )
793 794 795 796 797 798 799 800 801 802 803
            exts.append( Extension('Nav', ['Nav.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_AE', ['ae/_AEmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_AH', ['ah/_AHmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_App', ['app/_Appmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_CarbonEvt', ['carbonevt/_CarbonEvtmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_CG', ['cg/_CGmodule.c'],
804
                    extra_link_args=['-framework', 'ApplicationServices']) )
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849
            exts.append( Extension('_Cm', ['cm/_Cmmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Ctl', ['ctl/_Ctlmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Dlg', ['dlg/_Dlgmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Drag', ['drag/_Dragmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Evt', ['evt/_Evtmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_File', ['file/_Filemodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Folder', ['folder/_Foldermodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Fm', ['fm/_Fmmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Help', ['help/_Helpmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Icn', ['icn/_Icnmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_IBCarbon', ['ibcarbon/_IBCarbon.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_List', ['list/_Listmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Menu', ['menu/_Menumodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Mlte', ['mlte/_Mltemodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Qd', ['qd/_Qdmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Qdoffs', ['qdoffs/_Qdoffsmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_Qt', ['qt/_Qtmodule.c'],
                    extra_link_args=['-framework', 'QuickTime',
                                     '-framework', 'Carbon']) )
            exts.append( Extension('_Scrap', ['scrap/_Scrapmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            exts.append( Extension('_TE', ['te/_TEmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
            # As there is no standardized place (yet) to put
            # user-installed Mac libraries on OSX, we search for "waste"
            # in parent directories of the Python source tree. You
            # should put a symlink to your Waste installation in the
            # same folder as your python source tree.  Or modify the
            # next few lines:-)
Tim Peters's avatar
Tim Peters committed
850
            waste_incs = find_file("WASTE.h", [],
851 852 853 854 855 856 857
                    ['../'*n + 'waste/C_C++ Headers' for n in (0,1,2,3,4)])
            waste_libs = find_library_file(self.compiler, "WASTE", [],
                    ["../"*n + "waste/Static Libraries" for n in (0,1,2,3,4)])
            if waste_incs != None and waste_libs != None:
                (srcdir,) = sysconfig.get_config_vars('srcdir')
                exts.append( Extension('waste',
                               ['waste/wastemodule.c'] + [
Tim Peters's avatar
Tim Peters committed
858
                                os.path.join(srcdir, d) for d in
859 860 861 862 863 864 865 866 867 868 869
                                'Mac/Wastemods/WEObjectHandlers.c',
                                'Mac/Wastemods/WETabHooks.c',
                                'Mac/Wastemods/WETabs.c'
                               ],
                               include_dirs = waste_incs + [os.path.join(srcdir, 'Mac/Wastemods')],
                               library_dirs = waste_libs,
                               libraries = ['WASTE'],
                               extra_link_args = ['-framework', 'Carbon'],
                ) )
            exts.append( Extension('_Win', ['win/_Winmodule.c'],
                    extra_link_args=['-framework', 'Carbon']) )
870

871 872 873 874
        self.extensions.extend(exts)

        # Call the method for detecting whether _tkinter can be compiled
        self.detect_tkinter(inc_dirs, lib_dirs)
875

876 877 878 879 880
    def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
        # The _tkinter module, using frameworks. Since frameworks are quite
        # different the UNIX search logic is not sharable.
        from os.path import join, exists
        framework_dirs = [
Tim Peters's avatar
Tim Peters committed
881 882
            '/System/Library/Frameworks/',
            '/Library/Frameworks',
883 884 885 886 887 888 889
            join(os.getenv('HOME'), '/Library/Frameworks')
        ]

        # Find the directory that contains the Tcl.framwork and Tk.framework
        # bundles.
        # XXX distutils should support -F!
        for F in framework_dirs:
Tim Peters's avatar
Tim Peters committed
890
            # both Tcl.framework and Tk.framework should be present
891
            for fw in 'Tcl', 'Tk':
Tim Peters's avatar
Tim Peters committed
892
                if not exists(join(F, fw + '.framework')):
893 894 895 896 897 898 899 900 901
                    break
            else:
                # ok, F is now directory with both frameworks. Continure
                # building
                break
        else:
            # Tk and Tcl frameworks not found. Normal "unix" tkinter search
            # will now resume.
            return 0
Tim Peters's avatar
Tim Peters committed
902

903 904
        # For 8.4a2, we must add -I options that point inside the Tcl and Tk
        # frameworks. In later release we should hopefully be able to pass
Tim Peters's avatar
Tim Peters committed
905
        # the -F option to gcc, which specifies a framework lookup path.
906 907
        #
        include_dirs = [
Tim Peters's avatar
Tim Peters committed
908
            join(F, fw + '.framework', H)
909 910 911 912
            for fw in 'Tcl', 'Tk'
            for H in 'Headers', 'Versions/Current/PrivateHeaders'
        ]

Tim Peters's avatar
Tim Peters committed
913
        # For 8.4a2, the X11 headers are not included. Rather than include a
914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
        # complicated search, this is a hard-coded path. It could bail out
        # if X11 libs are not found...
        include_dirs.append('/usr/X11R6/include')
        frameworks = ['-framework', 'Tcl', '-framework', 'Tk']

        ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
                        define_macros=[('WITH_APPINIT', 1)],
                        include_dirs = include_dirs,
                        libraries = [],
                        extra_compile_args = frameworks,
                        extra_link_args = frameworks,
                        )
        self.extensions.append(ext)
        return 1

Tim Peters's avatar
Tim Peters committed
929

930
    def detect_tkinter(self, inc_dirs, lib_dirs):
931
        # The _tkinter module.
932

933 934 935 936 937 938
        # Rather than complicate the code below, detecting and building
        # AquaTk is a separate method. Only one Tkinter will be built on
        # Darwin - either AquaTk, if it is found, or X11 based Tk.
        platform = self.get_platform()
        if platform == 'darwin' and \
           self.detect_tkinter_darwin(inc_dirs, lib_dirs):
Tim Peters's avatar
Tim Peters committed
939
            return
940

941
        # Assume we haven't found any of the libraries or include files
942 943
        # The versions with dots are used on Unix, and the versions without
        # dots on Windows, for detection by cygwin.
944
        tcllib = tklib = tcl_includes = tk_includes = None
945 946
        for version in ['8.4', '84', '8.3', '83', '8.2',
                        '82', '8.1', '81', '8.0', '80']:
947 948
            tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version)
            tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version)
949
            if tklib and tcllib:
950 951
                # Exit the loop when we've found the Tcl/Tk libraries
                break
952

953
        # Now check for the header files
954 955 956
        if tklib and tcllib:
            # Check for the include files on Debian, where
            # they're put in /usr/include/{tcl,tk}X.Y
957
            debian_tcl_include = [ '/usr/include/tcl' + version ]
Fred Drake's avatar
Fred Drake committed
958 959
            debian_tk_include =  [ '/usr/include/tk'  + version ] + \
                                 debian_tcl_include
960 961
            tcl_includes = find_file('tcl.h', inc_dirs, debian_tcl_include)
            tk_includes = find_file('tk.h', inc_dirs, debian_tk_include)
962

963
        if (tcllib is None or tklib is None or
964 965 966
            tcl_includes is None or tk_includes is None):
            # Something's missing, so give up
            return
967

968 969 970 971 972 973
        # OK... everything seems to be present for Tcl/Tk.

        include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
        for dir in tcl_includes + tk_includes:
            if dir not in include_dirs:
                include_dirs.append(dir)
974

975
        # Check for various platform-specific directories
976
        if platform == 'sunos5':
977 978 979 980 981 982 983 984 985
            include_dirs.append('/usr/openwin/include')
            added_lib_dirs.append('/usr/openwin/lib')
        elif os.path.exists('/usr/X11R6/include'):
            include_dirs.append('/usr/X11R6/include')
            added_lib_dirs.append('/usr/X11R6/lib')
        elif os.path.exists('/usr/X11R5/include'):
            include_dirs.append('/usr/X11R5/include')
            added_lib_dirs.append('/usr/X11R5/lib')
        else:
986
            # Assume default location for X11
987 988 989
            include_dirs.append('/usr/X11/include')
            added_lib_dirs.append('/usr/X11/lib')

990 991 992 993 994 995
        # If Cygwin, then verify that X is installed before proceeding
        if platform == 'cygwin':
            x11_inc = find_file('X11/Xlib.h', [], include_dirs)
            if x11_inc is None:
                return

996
        # Check for BLT extension
Fred Drake's avatar
Fred Drake committed
997 998
        if self.compiler.find_library_file(lib_dirs + added_lib_dirs,
                                           'BLT8.0'):
999 1000
            defs.append( ('WITH_BLT', 1) )
            libs.append('BLT8.0')
1001 1002 1003 1004
        elif self.compiler.find_library_file(lib_dirs + added_lib_dirs,
                                           'BLT'):
            defs.append( ('WITH_BLT', 1) )
            libs.append('BLT')
1005 1006

        # Add the Tcl/Tk libraries
1007 1008
        libs.append('tk'+ version)
        libs.append('tcl'+ version)
1009

1010
        if platform in ['aix3', 'aix4']:
1011 1012
            libs.append('ld')

1013 1014 1015
        # Finally, link with the X11 libraries (not appropriate on cygwin)
        if platform != "cygwin":
            libs.append('X11')
1016 1017 1018 1019 1020 1021 1022 1023

        ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
                        define_macros=[('WITH_APPINIT', 1)] + defs,
                        include_dirs = include_dirs,
                        libraries = libs,
                        library_dirs = added_lib_dirs,
                        )
        self.extensions.append(ext)
1024

1025 1026 1027 1028
##         # Uncomment these lines if you want to play with xxmodule.c
##         ext = Extension('xx', ['xxmodule.c'])
##         self.extensions.append(ext)

1029
        # XXX handle these, but how to detect?
1030
        # *** Uncomment and edit for PIL (TkImaging) extension only:
1031
        #       -DWITH_PIL -I../Extensions/Imaging/libImaging  tkImaging.c \
1032
        # *** Uncomment and edit for TOGL extension only:
1033
        #       -DWITH_TOGL togl.c \
1034
        # *** Uncomment these for TOGL extension only:
1035
        #       -lGL -lGLU -lXext -lXmu \
1036

1037 1038 1039 1040 1041 1042 1043
class PyBuildInstall(install):
    # Suppress the warning about installation into the lib_dynload
    # directory, which is not in sys.path when running Python during
    # installation:
    def initialize_options (self):
        install.initialize_options(self)
        self.warn_dir=0
1044

1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
class PyBuildInstallLib(install_lib):
    # Do exactly what install_lib does but make sure correct access modes get
    # set on installed directories and files. All installed files with get
    # mode 644 unless they are a shared library in which case they will get
    # mode 755. All installed directories will get mode 755.

    so_ext = sysconfig.get_config_var("SO")

    def install(self):
        outfiles = install_lib.install(self)
        self.set_file_modes(outfiles, 0644, 0755)
        self.set_dir_modes(self.install_dir, 0755)
        return outfiles

    def set_file_modes(self, files, defaultMode, sharedLibMode):
        if not self.is_chmod_supported(): return
        if not files: return

        for filename in files:
            if os.path.islink(filename): continue
            mode = defaultMode
            if filename.endswith(self.so_ext): mode = sharedLibMode
            log.info("changing mode of %s to %o", filename, mode)
            if not self.dry_run: os.chmod(filename, mode)

    def set_dir_modes(self, dirname, mode):
        if not self.is_chmod_supported(): return
        os.path.walk(dirname, self.set_dir_modes_visitor, mode)

    def set_dir_modes_visitor(self, mode, dirname, names):
        if os.path.islink(dirname): return
        log.info("changing mode of %s to %o", dirname, mode)
        if not self.dry_run: os.chmod(dirname, mode)

    def is_chmod_supported(self):
        return hasattr(os, 'chmod')

Guido van Rossum's avatar
Guido van Rossum committed
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
SUMMARY = """
Python is an interpreted, interactive, object-oriented programming
language. It is often compared to Tcl, Perl, Scheme or Java.

Python combines remarkable power with very clear syntax. It has
modules, classes, exceptions, very high level dynamic data types, and
dynamic typing. There are interfaces to many system calls and
libraries, as well as to various windowing systems (X11, Motif, Tk,
Mac, MFC). New built-in modules are easily written in C or C++. Python
is also usable as an extension language for applications that need a
programmable interface.

The Python implementation is portable: it runs on many brands of UNIX,
on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't
listed here, it may still be supported, if there's a C compiler for
it. Ask around on comp.lang.python -- or just try compiling Python
yourself.
"""

CLASSIFIERS = """
Development Status :: 3 - Alpha
Development Status :: 6 - Mature
License :: OSI Approved :: Python Software Foundation License
Natural Language :: English
Programming Language :: C
Programming Language :: Python
Topic :: Software Development
"""

1111
def main():
1112 1113 1114
    # turn off warnings when deprecated modules are imported
    import warnings
    warnings.filterwarnings("ignore",category=DeprecationWarning)
Guido van Rossum's avatar
Guido van Rossum committed
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
    setup(# PyPI Metadata (PEP 301)
          name = "Python",
          version = sys.version.split()[0],
          url = "http://www.python.org/%s" % sys.version[:3],
          maintainer = "Guido van Rossum and the Python community",
          maintainer_email = "python-dev@python.org",
          description = "A high-level object-oriented programming language",
          long_description = SUMMARY.strip(),
          license = "PSF license",
          classifiers = filter(None, CLASSIFIERS.split("\n")),
          platforms = ["Many"],

          # Build info
1128 1129
          cmdclass = {'build_ext':PyBuildExt, 'install':PyBuildInstall,
                      'install_lib':PyBuildInstallLib},
1130 1131
          # The struct module is defined here, because build_ext won't be
          # called unless there's at least one extension module defined.
1132 1133 1134 1135
          ext_modules=[Extension('struct', ['structmodule.c'])],

          # Scripts to install
          scripts = ['Tools/scripts/pydoc']
1136
        )
1137

1138 1139 1140
# --install-platlib
if __name__ == '__main__':
    main()