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