source: python/trunk/setup.py@ 388

Last change on this file since 388 was 384, checked in by dmik, 11 years ago

setup: Add '/@unixroot' include/lib entries for 'os2knix' platform.

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