Merged revisions 81782 via svnmerge from
[python/dscho.git] / setup.py
blob8eafeeb85db534ddf88edb4d44e55b52b27897f3
1 # Autodetecting setup.py script for building the Python extensions
4 __version__ = "$Revision$"
6 import sys, os, imp, re, optparse
7 from glob import glob
9 from distutils import log
10 from distutils import sysconfig
11 from distutils import text_file
12 from distutils.errors import *
13 from distutils.core import Extension, setup
14 from distutils.command.build_ext import build_ext
15 from distutils.command.install import install
16 from distutils.command.install_lib import install_lib
18 # This global variable is used to hold the list of modules to be disabled.
19 disabled_module_list = []
21 def add_dir_to_list(dirlist, dir):
22 """Add the directory 'dir' to the list 'dirlist' (at the front) if
23 1) 'dir' is not already in 'dirlist'
24 2) 'dir' actually exists, and is a directory."""
25 if dir is not None and os.path.isdir(dir) and dir not in dirlist:
26 dirlist.insert(0, dir)
28 def macosx_sdk_root():
29 """
30 Return the directory of the current OSX SDK,
31 or '/' if no SDK was specified.
32 """
33 cflags = sysconfig.get_config_var('CFLAGS')
34 m = re.search(r'-isysroot\s+(\S+)', cflags)
35 if m is None:
36 sysroot = '/'
37 else:
38 sysroot = m.group(1)
39 return sysroot
41 def is_macosx_sdk_path(path):
42 """
43 Returns True if 'path' can be located in an OSX SDK
44 """
45 return path.startswith('/usr/') or path.startswith('/System/')
47 def find_file(filename, std_dirs, paths):
48 """Searches for the directory where a given file is located,
49 and returns a possibly-empty list of additional directories, or None
50 if the file couldn't be found at all.
52 'filename' is the name of a file, such as readline.h or libcrypto.a.
53 'std_dirs' is the list of standard system directories; if the
54 file is found in one of them, no additional directives are needed.
55 'paths' is a list of additional locations to check; if the file is
56 found in one of them, the resulting list will contain the directory.
57 """
58 if sys.platform == 'darwin':
59 # Honor the MacOSX SDK setting when one was specified.
60 # An SDK is a directory with the same structure as a real
61 # system, but with only header files and libraries.
62 sysroot = macosx_sdk_root()
64 # Check the standard locations
65 for dir in std_dirs:
66 f = os.path.join(dir, filename)
68 if sys.platform == 'darwin' and is_macosx_sdk_path(dir):
69 f = os.path.join(sysroot, dir[1:], filename)
71 if os.path.exists(f): return []
73 # Check the additional directories
74 for dir in paths:
75 f = os.path.join(dir, filename)
77 if sys.platform == 'darwin' and is_macosx_sdk_path(dir):
78 f = os.path.join(sysroot, dir[1:], filename)
80 if os.path.exists(f):
81 return [dir]
83 # Not found anywhere
84 return None
86 def find_library_file(compiler, libname, std_dirs, paths):
87 result = compiler.find_library_file(std_dirs + paths, libname)
88 if result is None:
89 return None
91 if sys.platform == 'darwin':
92 sysroot = macosx_sdk_root()
94 # Check whether the found file is in one of the standard directories
95 dirname = os.path.dirname(result)
96 for p in std_dirs:
97 # Ensure path doesn't end with path separator
98 p = p.rstrip(os.sep)
100 if sys.platform == 'darwin' and is_macosx_sdk_path(p):
101 if os.path.join(sysroot, p[1:]) == dirname:
102 return [ ]
104 if p == dirname:
105 return [ ]
107 # Otherwise, it must have been in one of the additional directories,
108 # so we have to figure out which one.
109 for p in paths:
110 # Ensure path doesn't end with path separator
111 p = p.rstrip(os.sep)
113 if sys.platform == 'darwin' and is_macosx_sdk_path(p):
114 if os.path.join(sysroot, p[1:]) == dirname:
115 return [ p ]
117 if p == dirname:
118 return [p]
119 else:
120 assert False, "Internal error: Path not found in std_dirs or paths"
122 def module_enabled(extlist, modname):
123 """Returns whether the module 'modname' is present in the list
124 of extensions 'extlist'."""
125 extlist = [ext for ext in extlist if ext.name == modname]
126 return len(extlist)
128 def find_module_file(module, dirlist):
129 """Find a module in a set of possible folders. If it is not found
130 return the unadorned filename"""
131 list = find_file(module, [], dirlist)
132 if not list:
133 return module
134 if len(list) > 1:
135 log.info("WARNING: multiple copies of %s found"%module)
136 return os.path.join(list[0], module)
138 class PyBuildExt(build_ext):
140 def __init__(self, dist):
141 build_ext.__init__(self, dist)
142 self.failed = []
144 def build_extensions(self):
146 # Detect which modules should be compiled
147 missing = self.detect_modules()
149 # Remove modules that are present on the disabled list
150 extensions = [ext for ext in self.extensions
151 if ext.name not in disabled_module_list]
152 # move ctypes to the end, it depends on other modules
153 ext_map = dict((ext.name, i) for i, ext in enumerate(extensions))
154 if "_ctypes" in ext_map:
155 ctypes = extensions.pop(ext_map["_ctypes"])
156 extensions.append(ctypes)
157 self.extensions = extensions
159 # Fix up the autodetected modules, prefixing all the source files
160 # with Modules/.
161 srcdir = sysconfig.get_config_var('srcdir')
162 if not srcdir:
163 # Maybe running on Windows but not using CYGWIN?
164 raise ValueError("No source directory; cannot proceed.")
165 srcdir = os.path.abspath(srcdir)
166 moddirlist = [os.path.join(srcdir, 'Modules')]
168 # Platform-dependent module source and include directories
169 platform = self.get_platform()
171 # Fix up the paths for scripts, too
172 self.distribution.scripts = [os.path.join(srcdir, filename)
173 for filename in self.distribution.scripts]
175 # Python header files
176 headers = [sysconfig.get_config_h_filename()]
177 headers += glob(os.path.join(sysconfig.get_python_inc(), "*.h"))
179 for ext in self.extensions[:]:
180 ext.sources = [ find_module_file(filename, moddirlist)
181 for filename in ext.sources ]
182 if ext.depends is not None:
183 ext.depends = [find_module_file(filename, moddirlist)
184 for filename in ext.depends]
185 else:
186 ext.depends = []
187 # re-compile extensions if a header file has been changed
188 ext.depends.extend(headers)
190 # If a module has already been built statically,
191 # don't build it here
192 if ext.name in sys.builtin_module_names:
193 self.extensions.remove(ext)
195 if platform != 'mac':
196 # Parse Modules/Setup and Modules/Setup.local to figure out which
197 # modules are turned on in the file.
198 remove_modules = []
199 for filename in ('Modules/Setup', 'Modules/Setup.local'):
200 input = text_file.TextFile(filename, join_lines=1)
201 while 1:
202 line = input.readline()
203 if not line: break
204 line = line.split()
205 remove_modules.append(line[0])
206 input.close()
208 for ext in self.extensions[:]:
209 if ext.name in remove_modules:
210 self.extensions.remove(ext)
212 # When you run "make CC=altcc" or something similar, you really want
213 # those environment variables passed into the setup.py phase. Here's
214 # a small set of useful ones.
215 compiler = os.environ.get('CC')
216 args = {}
217 # unfortunately, distutils doesn't let us provide separate C and C++
218 # compilers
219 if compiler is not None:
220 (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS')
221 args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags
222 self.compiler.set_executables(**args)
224 build_ext.build_extensions(self)
226 longest = max([len(e.name) for e in self.extensions])
227 if self.failed:
228 longest = max(longest, max([len(name) for name in self.failed]))
230 def print_three_column(lst):
231 lst.sort(key=str.lower)
232 # guarantee zip() doesn't drop anything
233 while len(lst) % 3:
234 lst.append("")
235 for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]):
236 print("%-*s %-*s %-*s" % (longest, e, longest, f,
237 longest, g))
239 if missing:
240 print()
241 print("Python build finished, but the necessary bits to build "
242 "these modules were not found:")
243 print_three_column(missing)
244 print("To find the necessary bits, look in setup.py in"
245 " detect_modules() for the module's name.")
246 print()
248 if self.failed:
249 failed = self.failed[:]
250 print()
251 print("Failed to build these modules:")
252 print_three_column(failed)
253 print()
255 def build_extension(self, ext):
257 if ext.name == '_ctypes':
258 if not self.configure_ctypes(ext):
259 return
261 try:
262 build_ext.build_extension(self, ext)
263 except (CCompilerError, DistutilsError) as why:
264 self.announce('WARNING: building of extension "%s" failed: %s' %
265 (ext.name, sys.exc_info()[1]))
266 self.failed.append(ext.name)
267 return
268 # Workaround for Mac OS X: The Carbon-based modules cannot be
269 # reliably imported into a command-line Python
270 if 'Carbon' in ext.extra_link_args:
271 self.announce(
272 'WARNING: skipping import check for Carbon-based "%s"' %
273 ext.name)
274 return
276 if self.get_platform() == 'darwin' and (
277 sys.maxsize > 2**32 and '-arch' in ext.extra_link_args):
278 # Don't bother doing an import check when an extension was
279 # build with an explicit '-arch' flag on OSX. That's currently
280 # only used to build 32-bit only extensions in a 4-way
281 # universal build and loading 32-bit code into a 64-bit
282 # process will fail.
283 self.announce(
284 'WARNING: skipping import check for "%s"' %
285 ext.name)
286 return
288 # Workaround for Cygwin: Cygwin currently has fork issues when many
289 # modules have been imported
290 if self.get_platform() == 'cygwin':
291 self.announce('WARNING: skipping import check for Cygwin-based "%s"'
292 % ext.name)
293 return
294 ext_filename = os.path.join(
295 self.build_lib,
296 self.get_ext_filename(self.get_ext_fullname(ext.name)))
298 # If the build directory didn't exist when setup.py was
299 # started, sys.path_importer_cache has a negative result
300 # cached. Clear that cache before trying to import.
301 sys.path_importer_cache.clear()
303 try:
304 imp.load_dynamic(ext.name, ext_filename)
305 except ImportError as why:
306 self.failed.append(ext.name)
307 self.announce('*** WARNING: renaming "%s" since importing it'
308 ' failed: %s' % (ext.name, why), level=3)
309 assert not self.inplace
310 basename, tail = os.path.splitext(ext_filename)
311 newname = basename + "_failed" + tail
312 if os.path.exists(newname):
313 os.remove(newname)
314 os.rename(ext_filename, newname)
316 # XXX -- This relies on a Vile HACK in
317 # distutils.command.build_ext.build_extension(). The
318 # _built_objects attribute is stored there strictly for
319 # use here.
320 # If there is a failure, _built_objects may not be there,
321 # so catch the AttributeError and move on.
322 try:
323 for filename in self._built_objects:
324 os.remove(filename)
325 except AttributeError:
326 self.announce('unable to remove files (ignored)')
327 except:
328 exc_type, why, tb = sys.exc_info()
329 self.announce('*** WARNING: importing extension "%s" '
330 'failed with %s: %s' % (ext.name, exc_type, why),
331 level=3)
332 self.failed.append(ext.name)
334 def get_platform(self):
335 # Get value of sys.platform
336 for platform in ['cygwin', 'darwin', 'atheos', 'osf1']:
337 if sys.platform.startswith(platform):
338 return platform
339 return sys.platform
341 def detect_modules(self):
342 # Ensure that /usr/local is always used
343 add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib')
344 add_dir_to_list(self.compiler.include_dirs, '/usr/local/include')
346 # Add paths specified in the environment variables LDFLAGS and
347 # CPPFLAGS for header and library files.
348 # We must get the values from the Makefile and not the environment
349 # directly since an inconsistently reproducible issue comes up where
350 # the environment variable is not set even though the value were passed
351 # into configure and stored in the Makefile (issue found on OS X 10.3).
352 for env_var, arg_name, dir_list in (
353 ('LDFLAGS', '-R', self.compiler.runtime_library_dirs),
354 ('LDFLAGS', '-L', self.compiler.library_dirs),
355 ('CPPFLAGS', '-I', self.compiler.include_dirs)):
356 env_val = sysconfig.get_config_var(env_var)
357 if env_val:
358 # To prevent optparse from raising an exception about any
359 # options in env_val that it doesn't know about we strip out
360 # all double dashes and any dashes followed by a character
361 # that is not for the option we are dealing with.
363 # Please note that order of the regex is important! We must
364 # strip out double-dashes first so that we don't end up with
365 # substituting "--Long" to "-Long" and thus lead to "ong" being
366 # used for a library directory.
367 env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1],
368 ' ', env_val)
369 parser = optparse.OptionParser()
370 # Make sure that allowing args interspersed with options is
371 # allowed
372 parser.allow_interspersed_args = True
373 parser.error = lambda msg: None
374 parser.add_option(arg_name, dest="dirs", action="append")
375 options = parser.parse_args(env_val.split())[0]
376 if options.dirs:
377 for directory in reversed(options.dirs):
378 add_dir_to_list(dir_list, directory)
380 if os.path.normpath(sys.prefix) != '/usr':
381 add_dir_to_list(self.compiler.library_dirs,
382 sysconfig.get_config_var("LIBDIR"))
383 add_dir_to_list(self.compiler.include_dirs,
384 sysconfig.get_config_var("INCLUDEDIR"))
386 # lib_dirs and inc_dirs are used to search for files;
387 # if a file is found in one of those directories, it can
388 # be assumed that no additional -I,-L directives are needed.
389 lib_dirs = self.compiler.library_dirs + [
390 '/lib64', '/usr/lib64',
391 '/lib', '/usr/lib',
393 inc_dirs = self.compiler.include_dirs + ['/usr/include']
394 exts = []
395 missing = []
397 config_h = sysconfig.get_config_h_filename()
398 config_h_vars = sysconfig.parse_config_h(open(config_h))
400 platform = self.get_platform()
401 srcdir = sysconfig.get_config_var('srcdir')
403 # Check for AtheOS which has libraries in non-standard locations
404 if platform == 'atheos':
405 lib_dirs += ['/system/libs', '/atheos/autolnk/lib']
406 lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep)
407 inc_dirs += ['/system/include', '/atheos/autolnk/include']
408 inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep)
410 # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb)
411 if platform in ['osf1', 'unixware7', 'openunix8']:
412 lib_dirs += ['/usr/ccs/lib']
414 if platform == 'darwin':
415 # This should work on any unixy platform ;-)
416 # If the user has bothered specifying additional -I and -L flags
417 # in OPT and LDFLAGS we might as well use them here.
418 # NOTE: using shlex.split would technically be more correct, but
419 # also gives a bootstrap problem. Let's hope nobody uses directories
420 # with whitespace in the name to store libraries.
421 cflags, ldflags = sysconfig.get_config_vars(
422 'CFLAGS', 'LDFLAGS')
423 for item in cflags.split():
424 if item.startswith('-I'):
425 inc_dirs.append(item[2:])
427 for item in ldflags.split():
428 if item.startswith('-L'):
429 lib_dirs.append(item[2:])
431 # Check for MacOS X, which doesn't need libm.a at all
432 math_libs = ['m']
433 if platform in ['darwin', 'mac']:
434 math_libs = []
436 # XXX Omitted modules: gl, pure, dl, SGI-specific modules
439 # The following modules are all pretty straightforward, and compile
440 # on pretty much any POSIXish platform.
443 # Some modules that are normally always on:
444 exts.append( Extension('_weakref', ['_weakref.c']) )
446 # array objects
447 exts.append( Extension('array', ['arraymodule.c']) )
448 # complex math library functions
449 exts.append( Extension('cmath', ['cmathmodule.c'],
450 libraries=math_libs) )
452 # math library functions, e.g. sin()
453 exts.append( Extension('math', ['mathmodule.c'],
454 libraries=math_libs) )
455 # time operations and variables
456 exts.append( Extension('time', ['timemodule.c'],
457 libraries=math_libs) )
458 exts.append( Extension('datetime', ['datetimemodule.c', 'timemodule.c'],
459 libraries=math_libs) )
460 # fast iterator tools implemented in C
461 exts.append( Extension("itertools", ["itertoolsmodule.c"]) )
462 # random number generator implemented in C
463 exts.append( Extension("_random", ["_randommodule.c"]) )
464 # high-performance collections
465 exts.append( Extension("_collections", ["_collectionsmodule.c"]) )
466 # bisect
467 exts.append( Extension("_bisect", ["_bisectmodule.c"]) )
468 # heapq
469 exts.append( Extension("_heapq", ["_heapqmodule.c"]) )
470 # operator.add() and similar goodies
471 exts.append( Extension('operator', ['operator.c']) )
472 # C-optimized pickle replacement
473 exts.append( Extension("_pickle", ["_pickle.c"]) )
474 # atexit
475 exts.append( Extension("atexit", ["atexitmodule.c"]) )
476 # _json speedups
477 exts.append( Extension("_json", ["_json.c"]) )
478 # Python C API test module
479 exts.append( Extension('_testcapi', ['_testcapimodule.c'],
480 depends=['testcapi_long.h']) )
481 # profiler (_lsprof is for cProfile.py)
482 exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) )
483 # static Unicode character database
484 exts.append( Extension('unicodedata', ['unicodedata.c']) )
486 # Modules with some UNIX dependencies -- on by default:
487 # (If you have a really backward UNIX, select and socket may not be
488 # supported...)
490 # fcntl(2) and ioctl(2)
491 exts.append( Extension('fcntl', ['fcntlmodule.c']) )
492 if platform not in ['mac']:
493 # pwd(3)
494 exts.append( Extension('pwd', ['pwdmodule.c']) )
495 # grp(3)
496 exts.append( Extension('grp', ['grpmodule.c']) )
497 # spwd, shadow passwords
498 if (config_h_vars.get('HAVE_GETSPNAM', False) or
499 config_h_vars.get('HAVE_GETSPENT', False)):
500 exts.append( Extension('spwd', ['spwdmodule.c']) )
501 else:
502 missing.append('spwd')
503 else:
504 missing.extend(['pwd', 'grp', 'spwd'])
506 # select(2); not on ancient System V
507 exts.append( Extension('select', ['selectmodule.c']) )
509 # Fred Drake's interface to the Python parser
510 exts.append( Extension('parser', ['parsermodule.c']) )
512 # Memory-mapped files (also works on Win32).
513 if platform not in ['atheos', 'mac']:
514 exts.append( Extension('mmap', ['mmapmodule.c']) )
515 else:
516 missing.append('mmap')
518 # Lance Ellinghaus's syslog module
519 if platform not in ['mac']:
520 # syslog daemon interface
521 exts.append( Extension('syslog', ['syslogmodule.c']) )
522 else:
523 missing.append('syslog')
526 # Here ends the simple stuff. From here on, modules need certain
527 # libraries, are platform-specific, or present other surprises.
530 # Multimedia modules
531 # These don't work for 64-bit platforms!!!
532 # These represent audio samples or images as strings:
534 # Operations on audio samples
535 # According to #993173, this one should actually work fine on
536 # 64-bit platforms.
537 exts.append( Extension('audioop', ['audioop.c']) )
539 # readline
540 do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
541 if platform == 'darwin': # and os.uname()[2] < '9.':
542 # MacOSX 10.4 has a broken readline. Don't try to build
543 # the readline module unless the user has installed a fixed
544 # readline package
545 # FIXME: The readline emulation on 10.5 is better, but the
546 # readline module doesn't compile out of the box.
547 if find_file('readline/rlconf.h', inc_dirs, []) is None:
548 do_readline = False
549 if do_readline:
550 if sys.platform == 'darwin':
551 # In every directory on the search path search for a dynamic
552 # library and then a static library, instead of first looking
553 # for dynamic libraries on the entire path.
554 # This way a staticly linked custom readline gets picked up
555 # before the (possibly broken) dynamic library in /usr/lib.
556 readline_extra_link_args = ('-Wl,-search_paths_first',)
557 else:
558 readline_extra_link_args = ()
560 readline_libs = ['readline']
561 if self.compiler.find_library_file(lib_dirs,
562 'ncursesw'):
563 readline_libs.append('ncursesw')
564 elif self.compiler.find_library_file(lib_dirs,
565 'ncurses'):
566 readline_libs.append('ncurses')
567 elif self.compiler.find_library_file(lib_dirs, 'curses'):
568 readline_libs.append('curses')
569 elif self.compiler.find_library_file(lib_dirs +
570 ['/usr/lib/termcap'],
571 'termcap'):
572 readline_libs.append('termcap')
573 exts.append( Extension('readline', ['readline.c'],
574 library_dirs=['/usr/lib/termcap'],
575 extra_link_args=readline_extra_link_args,
576 libraries=readline_libs) )
577 else:
578 missing.append('readline')
580 if platform not in ['mac']:
581 # crypt module.
583 if self.compiler.find_library_file(lib_dirs, 'crypt'):
584 libs = ['crypt']
585 else:
586 libs = []
587 exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
588 else:
589 missing.append('crypt')
591 # CSV files
592 exts.append( Extension('_csv', ['_csv.c']) )
594 # socket(2)
595 exts.append( Extension('_socket', ['socketmodule.c'],
596 depends = ['socketmodule.h']) )
597 # Detect SSL support for the socket module (via _ssl)
598 search_for_ssl_incs_in = [
599 '/usr/local/ssl/include',
600 '/usr/contrib/ssl/include/'
602 ssl_incs = find_file('openssl/ssl.h', inc_dirs,
603 search_for_ssl_incs_in
605 if ssl_incs is not None:
606 krb5_h = find_file('krb5.h', inc_dirs,
607 ['/usr/kerberos/include'])
608 if krb5_h:
609 ssl_incs += krb5_h
610 ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
611 ['/usr/local/ssl/lib',
612 '/usr/contrib/ssl/lib/'
615 if (ssl_incs is not None and
616 ssl_libs is not None):
617 exts.append( Extension('_ssl', ['_ssl.c'],
618 include_dirs = ssl_incs,
619 library_dirs = ssl_libs,
620 libraries = ['ssl', 'crypto'],
621 depends = ['socketmodule.h']), )
622 else:
623 missing.append('_ssl')
625 # find out which version of OpenSSL we have
626 openssl_ver = 0
627 openssl_ver_re = re.compile(
628 '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
630 # look for the openssl version header on the compiler search path.
631 opensslv_h = find_file('openssl/opensslv.h', [],
632 inc_dirs + search_for_ssl_incs_in)
633 if opensslv_h:
634 name = os.path.join(opensslv_h[0], 'openssl/opensslv.h')
635 if sys.platform == 'darwin' and is_macosx_sdk_path(name):
636 name = os.path.join(macosx_sdk_root(), name[1:])
637 try:
638 incfile = open(name, 'r')
639 for line in incfile:
640 m = openssl_ver_re.match(line)
641 if m:
642 openssl_ver = eval(m.group(1))
643 except IOError as msg:
644 print("IOError while reading opensshv.h:", msg)
645 pass
647 #print('openssl_ver = 0x%08x' % openssl_ver)
649 if ssl_incs is not None and ssl_libs is not None:
650 if openssl_ver >= 0x00907000:
651 # The _hashlib module wraps optimized implementations
652 # of hash functions from the OpenSSL library.
653 exts.append( Extension('_hashlib', ['_hashopenssl.c'],
654 include_dirs = ssl_incs,
655 library_dirs = ssl_libs,
656 libraries = ['ssl', 'crypto']) )
657 else:
658 print("warning: openssl 0x%08x is too old for _hashlib" %
659 openssl_ver)
660 missing.append('_hashlib')
661 else:
662 missing.append('_hashlib')
664 if openssl_ver < 0x00908000:
665 # OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash
666 exts.append( Extension('_sha256', ['sha256module.c']) )
667 exts.append( Extension('_sha512', ['sha512module.c']) )
669 if openssl_ver < 0x00907000:
670 # no openssl at all, use our own md5 and sha1
671 exts.append( Extension('_md5', ['md5module.c']) )
672 exts.append( Extension('_sha1', ['sha1module.c']) )
674 # Modules that provide persistent dictionary-like semantics. You will
675 # probably want to arrange for at least one of them to be available on
676 # your machine, though none are defined by default because of library
677 # dependencies. The Python module dbm/__init__.py provides an
678 # implementation independent wrapper for these; dbm/dumb.py provides
679 # similar functionality (but slower of course) implemented in Python.
681 # Sleepycat^WOracle Berkeley DB interface.
682 # http://www.oracle.com/database/berkeley-db/db/index.html
684 # This requires the Sleepycat^WOracle DB code. The supported versions
685 # are set below. Visit the URL above to download
686 # a release. Most open source OSes come with one or more
687 # versions of BerkeleyDB already installed.
689 max_db_ver = (4, 7)
690 min_db_ver = (3, 3)
691 db_setup_debug = False # verbose debug prints from this script?
693 def allow_db_ver(db_ver):
694 """Returns a boolean if the given BerkeleyDB version is acceptable.
696 Args:
697 db_ver: A tuple of the version to verify.
699 if not (min_db_ver <= db_ver <= max_db_ver):
700 return False
701 return True
703 def gen_db_minor_ver_nums(major):
704 if major == 4:
705 for x in range(max_db_ver[1]+1):
706 if allow_db_ver((4, x)):
707 yield x
708 elif major == 3:
709 for x in (3,):
710 if allow_db_ver((3, x)):
711 yield x
712 else:
713 raise ValueError("unknown major BerkeleyDB version", major)
715 # construct a list of paths to look for the header file in on
716 # top of the normal inc_dirs.
717 db_inc_paths = [
718 '/usr/include/db4',
719 '/usr/local/include/db4',
720 '/opt/sfw/include/db4',
721 '/usr/include/db3',
722 '/usr/local/include/db3',
723 '/opt/sfw/include/db3',
724 # Fink defaults (http://fink.sourceforge.net/)
725 '/sw/include/db4',
726 '/sw/include/db3',
728 # 4.x minor number specific paths
729 for x in gen_db_minor_ver_nums(4):
730 db_inc_paths.append('/usr/include/db4%d' % x)
731 db_inc_paths.append('/usr/include/db4.%d' % x)
732 db_inc_paths.append('/usr/local/BerkeleyDB.4.%d/include' % x)
733 db_inc_paths.append('/usr/local/include/db4%d' % x)
734 db_inc_paths.append('/pkg/db-4.%d/include' % x)
735 db_inc_paths.append('/opt/db-4.%d/include' % x)
736 # MacPorts default (http://www.macports.org/)
737 db_inc_paths.append('/opt/local/include/db4%d' % x)
738 # 3.x minor number specific paths
739 for x in gen_db_minor_ver_nums(3):
740 db_inc_paths.append('/usr/include/db3%d' % x)
741 db_inc_paths.append('/usr/local/BerkeleyDB.3.%d/include' % x)
742 db_inc_paths.append('/usr/local/include/db3%d' % x)
743 db_inc_paths.append('/pkg/db-3.%d/include' % x)
744 db_inc_paths.append('/opt/db-3.%d/include' % x)
746 # Add some common subdirectories for Sleepycat DB to the list,
747 # based on the standard include directories. This way DB3/4 gets
748 # picked up when it is installed in a non-standard prefix and
749 # the user has added that prefix into inc_dirs.
750 std_variants = []
751 for dn in inc_dirs:
752 std_variants.append(os.path.join(dn, 'db3'))
753 std_variants.append(os.path.join(dn, 'db4'))
754 for x in gen_db_minor_ver_nums(4):
755 std_variants.append(os.path.join(dn, "db4%d"%x))
756 std_variants.append(os.path.join(dn, "db4.%d"%x))
757 for x in gen_db_minor_ver_nums(3):
758 std_variants.append(os.path.join(dn, "db3%d"%x))
759 std_variants.append(os.path.join(dn, "db3.%d"%x))
761 db_inc_paths = std_variants + db_inc_paths
762 db_inc_paths = [p for p in db_inc_paths if os.path.exists(p)]
764 db_ver_inc_map = {}
766 if sys.platform == 'darwin':
767 sysroot = macosx_sdk_root()
769 class db_found(Exception): pass
770 try:
771 # See whether there is a Sleepycat header in the standard
772 # search path.
773 for d in inc_dirs + db_inc_paths:
774 f = os.path.join(d, "db.h")
775 if sys.platform == 'darwin' and is_macosx_sdk_path(d):
776 f = os.path.join(sysroot, d[1:], "db.h")
778 if db_setup_debug: print("db: looking for db.h in", f)
779 if os.path.exists(f):
780 f = open(f, "rb").read()
781 m = re.search(br"#define\WDB_VERSION_MAJOR\W(\d+)", f)
782 if m:
783 db_major = int(m.group(1))
784 m = re.search(br"#define\WDB_VERSION_MINOR\W(\d+)", f)
785 db_minor = int(m.group(1))
786 db_ver = (db_major, db_minor)
788 # Avoid 4.6 prior to 4.6.21 due to a BerkeleyDB bug
789 if db_ver == (4, 6):
790 m = re.search(br"#define\WDB_VERSION_PATCH\W(\d+)", f)
791 db_patch = int(m.group(1))
792 if db_patch < 21:
793 print("db.h:", db_ver, "patch", db_patch,
794 "being ignored (4.6.x must be >= 4.6.21)")
795 continue
797 if ( (db_ver not in db_ver_inc_map) and
798 allow_db_ver(db_ver) ):
799 # save the include directory with the db.h version
800 # (first occurrence only)
801 db_ver_inc_map[db_ver] = d
802 if db_setup_debug:
803 print("db.h: found", db_ver, "in", d)
804 else:
805 # we already found a header for this library version
806 if db_setup_debug: print("db.h: ignoring", d)
807 else:
808 # ignore this header, it didn't contain a version number
809 if db_setup_debug:
810 print("db.h: no version number version in", d)
812 db_found_vers = list(db_ver_inc_map.keys())
813 db_found_vers.sort()
815 while db_found_vers:
816 db_ver = db_found_vers.pop()
817 db_incdir = db_ver_inc_map[db_ver]
819 # check lib directories parallel to the location of the header
820 db_dirs_to_check = [
821 db_incdir.replace("include", 'lib64'),
822 db_incdir.replace("include", 'lib'),
825 if sys.platform != 'darwin':
826 db_dirs_to_check = list(filter(os.path.isdir, db_dirs_to_check))
828 else:
829 # Same as other branch, but takes OSX SDK into account
830 tmp = []
831 for dn in db_dirs_to_check:
832 if is_macosx_sdk_path(dn):
833 if os.path.isdir(os.path.join(sysroot, dn[1:])):
834 tmp.append(dn)
835 else:
836 if os.path.isdir(dn):
837 tmp.append(dn)
839 db_dirs_to_check = tmp
841 # Look for a version specific db-X.Y before an ambiguoius dbX
842 # XXX should we -ever- look for a dbX name? Do any
843 # systems really not name their library by version and
844 # symlink to more general names?
845 for dblib in (('db-%d.%d' % db_ver),
846 ('db%d%d' % db_ver),
847 ('db%d' % db_ver[0])):
848 dblib_file = self.compiler.find_library_file(
849 db_dirs_to_check + lib_dirs, dblib )
850 if dblib_file:
851 dblib_dir = [ os.path.abspath(os.path.dirname(dblib_file)) ]
852 raise db_found
853 else:
854 if db_setup_debug: print("db lib: ", dblib, "not found")
856 except db_found:
857 if db_setup_debug:
858 print("bsddb using BerkeleyDB lib:", db_ver, dblib)
859 print("bsddb lib dir:", dblib_dir, " inc dir:", db_incdir)
860 db_incs = [db_incdir]
861 dblibs = [dblib]
862 else:
863 if db_setup_debug: print("db: no appropriate library found")
864 db_incs = None
865 dblibs = []
866 dblib_dir = None
868 # The sqlite interface
869 sqlite_setup_debug = False # verbose debug prints from this script?
871 # We hunt for #define SQLITE_VERSION "n.n.n"
872 # We need to find >= sqlite version 3.0.8
873 sqlite_incdir = sqlite_libdir = None
874 sqlite_inc_paths = [ '/usr/include',
875 '/usr/include/sqlite',
876 '/usr/include/sqlite3',
877 '/usr/local/include',
878 '/usr/local/include/sqlite',
879 '/usr/local/include/sqlite3',
881 MIN_SQLITE_VERSION_NUMBER = (3, 0, 8)
882 MIN_SQLITE_VERSION = ".".join([str(x)
883 for x in MIN_SQLITE_VERSION_NUMBER])
885 # Scan the default include directories before the SQLite specific
886 # ones. This allows one to override the copy of sqlite on OSX,
887 # where /usr/include contains an old version of sqlite.
888 if sys.platform == 'darwin':
889 sysroot = macosx_sdk_root()
891 for d in inc_dirs + sqlite_inc_paths:
892 f = os.path.join(d, "sqlite3.h")
894 if sys.platform == 'darwin' and is_macosx_sdk_path(d):
895 f = os.path.join(sysroot, d[1:], "sqlite3.h")
897 if os.path.exists(f):
898 if sqlite_setup_debug: print("sqlite: found %s"%f)
899 incf = open(f).read()
900 m = re.search(
901 r'\s*.*#\s*.*define\s.*SQLITE_VERSION\W*"(.*)"', incf)
902 if m:
903 sqlite_version = m.group(1)
904 sqlite_version_tuple = tuple([int(x)
905 for x in sqlite_version.split(".")])
906 if sqlite_version_tuple >= MIN_SQLITE_VERSION_NUMBER:
907 # we win!
908 if sqlite_setup_debug:
909 print("%s/sqlite3.h: version %s"%(d, sqlite_version))
910 sqlite_incdir = d
911 break
912 else:
913 if sqlite_setup_debug:
914 print("%s: version %d is too old, need >= %s"%(d,
915 sqlite_version, MIN_SQLITE_VERSION))
916 elif sqlite_setup_debug:
917 print("sqlite: %s had no SQLITE_VERSION"%(f,))
919 if sqlite_incdir:
920 sqlite_dirs_to_check = [
921 os.path.join(sqlite_incdir, '..', 'lib64'),
922 os.path.join(sqlite_incdir, '..', 'lib'),
923 os.path.join(sqlite_incdir, '..', '..', 'lib64'),
924 os.path.join(sqlite_incdir, '..', '..', 'lib'),
926 sqlite_libfile = self.compiler.find_library_file(
927 sqlite_dirs_to_check + lib_dirs, 'sqlite3')
928 if sqlite_libfile:
929 sqlite_libdir = [os.path.abspath(os.path.dirname(sqlite_libfile))]
931 if sqlite_incdir and sqlite_libdir:
932 sqlite_srcs = ['_sqlite/cache.c',
933 '_sqlite/connection.c',
934 '_sqlite/cursor.c',
935 '_sqlite/microprotocols.c',
936 '_sqlite/module.c',
937 '_sqlite/prepare_protocol.c',
938 '_sqlite/row.c',
939 '_sqlite/statement.c',
940 '_sqlite/util.c', ]
942 sqlite_defines = []
943 if sys.platform != "win32":
944 sqlite_defines.append(('MODULE_NAME', '"sqlite3"'))
945 else:
946 sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"'))
949 if sys.platform == 'darwin':
950 # In every directory on the search path search for a dynamic
951 # library and then a static library, instead of first looking
952 # for dynamic libraries on the entiry path.
953 # This way a staticly linked custom sqlite gets picked up
954 # before the dynamic library in /usr/lib.
955 sqlite_extra_link_args = ('-Wl,-search_paths_first',)
956 else:
957 sqlite_extra_link_args = ()
959 exts.append(Extension('_sqlite3', sqlite_srcs,
960 define_macros=sqlite_defines,
961 include_dirs=["Modules/_sqlite",
962 sqlite_incdir],
963 library_dirs=sqlite_libdir,
964 runtime_library_dirs=sqlite_libdir,
965 extra_link_args=sqlite_extra_link_args,
966 libraries=["sqlite3",]))
967 else:
968 missing.append('_sqlite3')
970 dbm_order = ['gdbm']
971 # The standard Unix dbm module:
972 if platform not in ['cygwin']:
973 config_args = [arg.strip("'")
974 for arg in sysconfig.get_config_var("CONFIG_ARGS").split()]
975 dbm_args = [arg for arg in config_args
976 if arg.startswith('--with-dbmliborder=')]
977 if dbm_args:
978 dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":")
979 else:
980 dbm_order = "ndbm:gdbm:bdb".split(":")
981 dbmext = None
982 for cand in dbm_order:
983 if cand == "ndbm":
984 if find_file("ndbm.h", inc_dirs, []) is not None:
985 # Some systems have -lndbm, others don't
986 if self.compiler.find_library_file(lib_dirs, 'ndbm'):
987 ndbm_libs = ['ndbm']
988 else:
989 ndbm_libs = []
990 print("building dbm using ndbm")
991 dbmext = Extension('_dbm', ['_dbmmodule.c'],
992 define_macros=[
993 ('HAVE_NDBM_H',None),
995 libraries=ndbm_libs)
996 break
998 elif cand == "gdbm":
999 if self.compiler.find_library_file(lib_dirs, 'gdbm'):
1000 gdbm_libs = ['gdbm']
1001 if self.compiler.find_library_file(lib_dirs, 'gdbm_compat'):
1002 gdbm_libs.append('gdbm_compat')
1003 if find_file("gdbm/ndbm.h", inc_dirs, []) is not None:
1004 print("building dbm using gdbm")
1005 dbmext = Extension(
1006 '_dbm', ['_dbmmodule.c'],
1007 define_macros=[
1008 ('HAVE_GDBM_NDBM_H', None),
1010 libraries = gdbm_libs)
1011 break
1012 if find_file("gdbm-ndbm.h", inc_dirs, []) is not None:
1013 print("building dbm using gdbm")
1014 dbmext = Extension(
1015 '_dbm', ['_dbmmodule.c'],
1016 define_macros=[
1017 ('HAVE_GDBM_DASH_NDBM_H', None),
1019 libraries = gdbm_libs)
1020 break
1021 elif cand == "bdb":
1022 if db_incs is not None:
1023 print("building dbm using bdb")
1024 dbmext = Extension('_dbm', ['_dbmmodule.c'],
1025 library_dirs=dblib_dir,
1026 runtime_library_dirs=dblib_dir,
1027 include_dirs=db_incs,
1028 define_macros=[
1029 ('HAVE_BERKDB_H', None),
1030 ('DB_DBM_HSEARCH', None),
1032 libraries=dblibs)
1033 break
1034 if dbmext is not None:
1035 exts.append(dbmext)
1036 else:
1037 missing.append('_dbm')
1039 # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
1040 if ('gdbm' in dbm_order and
1041 self.compiler.find_library_file(lib_dirs, 'gdbm')):
1042 exts.append( Extension('_gdbm', ['_gdbmmodule.c'],
1043 libraries = ['gdbm'] ) )
1044 else:
1045 missing.append('_gdbm')
1047 # Unix-only modules
1048 if platform not in ['mac', 'win32']:
1049 # Steen Lumholt's termios module
1050 exts.append( Extension('termios', ['termios.c']) )
1051 # Jeremy Hylton's rlimit interface
1052 if platform not in ['atheos']:
1053 exts.append( Extension('resource', ['resource.c']) )
1054 else:
1055 missing.append('resource')
1057 # Sun yellow pages. Some systems have the functions in libc.
1058 if (platform not in ['cygwin', 'qnx6'] and
1059 find_file('rpcsvc/yp_prot.h', inc_dirs, []) is not None):
1060 if (self.compiler.find_library_file(lib_dirs, 'nsl')):
1061 libs = ['nsl']
1062 else:
1063 libs = []
1064 exts.append( Extension('nis', ['nismodule.c'],
1065 libraries = libs) )
1066 else:
1067 missing.append('nis')
1068 else:
1069 missing.extend(['nis', 'resource', 'termios'])
1071 # Curses support, requiring the System V version of curses, often
1072 # provided by the ncurses library.
1073 panel_library = 'panel'
1074 if (self.compiler.find_library_file(lib_dirs, 'ncursesw')):
1075 curses_libs = ['ncursesw']
1076 # Bug 1464056: If _curses.so links with ncursesw,
1077 # _curses_panel.so must link with panelw.
1078 panel_library = 'panelw'
1079 exts.append( Extension('_curses', ['_cursesmodule.c'],
1080 libraries = curses_libs) )
1081 elif (self.compiler.find_library_file(lib_dirs, 'ncurses')):
1082 curses_libs = ['ncurses']
1083 exts.append( Extension('_curses', ['_cursesmodule.c'],
1084 libraries = curses_libs) )
1085 elif (self.compiler.find_library_file(lib_dirs, 'curses')
1086 and platform != 'darwin'):
1087 # OSX has an old Berkeley curses, not good enough for
1088 # the _curses module.
1089 if (self.compiler.find_library_file(lib_dirs, 'terminfo')):
1090 curses_libs = ['curses', 'terminfo']
1091 elif (self.compiler.find_library_file(lib_dirs, 'termcap')):
1092 curses_libs = ['curses', 'termcap']
1093 else:
1094 curses_libs = ['curses']
1096 exts.append( Extension('_curses', ['_cursesmodule.c'],
1097 libraries = curses_libs) )
1098 else:
1099 missing.append('_curses')
1101 # If the curses module is enabled, check for the panel module
1102 if (module_enabled(exts, '_curses') and
1103 self.compiler.find_library_file(lib_dirs, panel_library)):
1104 exts.append( Extension('_curses_panel', ['_curses_panel.c'],
1105 libraries = [panel_library] + curses_libs) )
1106 else:
1107 missing.append('_curses_panel')
1109 # Andrew Kuchling's zlib module. Note that some versions of zlib
1110 # 1.1.3 have security problems. See CERT Advisory CA-2002-07:
1111 # http://www.cert.org/advisories/CA-2002-07.html
1113 # zlib 1.1.4 is fixed, but at least one vendor (RedHat) has decided to
1114 # patch its zlib 1.1.3 package instead of upgrading to 1.1.4. For
1115 # now, we still accept 1.1.3, because we think it's difficult to
1116 # exploit this in Python, and we'd rather make it RedHat's problem
1117 # than our problem <wink>.
1119 # You can upgrade zlib to version 1.1.4 yourself by going to
1120 # http://www.gzip.org/zlib/
1121 zlib_inc = find_file('zlib.h', [], inc_dirs)
1122 have_zlib = False
1123 if zlib_inc is not None:
1124 zlib_h = zlib_inc[0] + '/zlib.h'
1125 version = '"0.0.0"'
1126 version_req = '"1.1.3"'
1127 fp = open(zlib_h)
1128 while 1:
1129 line = fp.readline()
1130 if not line:
1131 break
1132 if line.startswith('#define ZLIB_VERSION'):
1133 version = line.split()[2]
1134 break
1135 if version >= version_req:
1136 if (self.compiler.find_library_file(lib_dirs, 'z')):
1137 if sys.platform == "darwin":
1138 zlib_extra_link_args = ('-Wl,-search_paths_first',)
1139 else:
1140 zlib_extra_link_args = ()
1141 exts.append( Extension('zlib', ['zlibmodule.c'],
1142 libraries = ['z'],
1143 extra_link_args = zlib_extra_link_args))
1144 have_zlib = True
1145 else:
1146 missing.append('zlib')
1147 else:
1148 missing.append('zlib')
1149 else:
1150 missing.append('zlib')
1152 # Helper module for various ascii-encoders. Uses zlib for an optimized
1153 # crc32 if we have it. Otherwise binascii uses its own.
1154 if have_zlib:
1155 extra_compile_args = ['-DUSE_ZLIB_CRC32']
1156 libraries = ['z']
1157 extra_link_args = zlib_extra_link_args
1158 else:
1159 extra_compile_args = []
1160 libraries = []
1161 extra_link_args = []
1162 exts.append( Extension('binascii', ['binascii.c'],
1163 extra_compile_args = extra_compile_args,
1164 libraries = libraries,
1165 extra_link_args = extra_link_args) )
1167 # Gustavo Niemeyer's bz2 module.
1168 if (self.compiler.find_library_file(lib_dirs, 'bz2')):
1169 if sys.platform == "darwin":
1170 bz2_extra_link_args = ('-Wl,-search_paths_first',)
1171 else:
1172 bz2_extra_link_args = ()
1173 exts.append( Extension('bz2', ['bz2module.c'],
1174 libraries = ['bz2'],
1175 extra_link_args = bz2_extra_link_args) )
1176 else:
1177 missing.append('bz2')
1179 # Interface to the Expat XML parser
1181 # Expat was written by James Clark and is now maintained by a
1182 # group of developers on SourceForge; see www.libexpat.org for
1183 # more information. The pyexpat module was written by Paul
1184 # Prescod after a prototype by Jack Jansen. The Expat source
1185 # is included in Modules/expat/. Usage of a system
1186 # shared libexpat.so/expat.dll is not advised.
1188 # More information on Expat can be found at www.libexpat.org.
1190 expatinc = os.path.join(os.getcwd(), srcdir, 'Modules', 'expat')
1191 define_macros = [
1192 ('HAVE_EXPAT_CONFIG_H', '1'),
1195 exts.append(Extension('pyexpat',
1196 define_macros = define_macros,
1197 include_dirs = [expatinc],
1198 sources = ['pyexpat.c',
1199 'expat/xmlparse.c',
1200 'expat/xmlrole.c',
1201 'expat/xmltok.c',
1205 # Fredrik Lundh's cElementTree module. Note that this also
1206 # uses expat (via the CAPI hook in pyexpat).
1208 if os.path.isfile(os.path.join(srcdir, 'Modules', '_elementtree.c')):
1209 define_macros.append(('USE_PYEXPAT_CAPI', None))
1210 exts.append(Extension('_elementtree',
1211 define_macros = define_macros,
1212 include_dirs = [expatinc],
1213 sources = ['_elementtree.c'],
1215 else:
1216 missing.append('_elementtree')
1218 # Hye-Shik Chang's CJKCodecs modules.
1219 exts.append(Extension('_multibytecodec',
1220 ['cjkcodecs/multibytecodec.c']))
1221 for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
1222 exts.append(Extension('_codecs_%s' % loc,
1223 ['cjkcodecs/_codecs_%s.c' % loc]))
1225 # Thomas Heller's _ctypes module
1226 self.detect_ctypes(inc_dirs, lib_dirs)
1228 # Richard Oudkerk's multiprocessing module
1229 if platform == 'win32': # Windows
1230 macros = dict()
1231 libraries = ['ws2_32']
1233 elif platform == 'darwin': # Mac OSX
1234 macros = dict()
1235 libraries = []
1237 elif platform == 'cygwin': # Cygwin
1238 macros = dict()
1239 libraries = []
1241 elif platform in ('freebsd4', 'freebsd5', 'freebsd6', 'freebsd7', 'freebsd8'):
1242 # FreeBSD's P1003.1b semaphore support is very experimental
1243 # and has many known problems. (as of June 2008)
1244 macros = dict()
1245 libraries = []
1247 elif platform.startswith('openbsd'):
1248 macros = dict()
1249 libraries = []
1251 elif platform.startswith('netbsd'):
1252 macros = dict()
1253 libraries = []
1255 else: # Linux and other unices
1256 macros = dict()
1257 libraries = ['rt']
1259 if platform == 'win32':
1260 multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
1261 '_multiprocessing/semaphore.c',
1262 '_multiprocessing/pipe_connection.c',
1263 '_multiprocessing/socket_connection.c',
1264 '_multiprocessing/win32_functions.c'
1267 else:
1268 multiprocessing_srcs = [ '_multiprocessing/multiprocessing.c',
1269 '_multiprocessing/socket_connection.c'
1271 if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not
1272 sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')):
1273 multiprocessing_srcs.append('_multiprocessing/semaphore.c')
1275 if sysconfig.get_config_var('WITH_THREAD'):
1276 exts.append ( Extension('_multiprocessing', multiprocessing_srcs,
1277 define_macros=list(macros.items()),
1278 include_dirs=["Modules/_multiprocessing"]))
1279 else:
1280 missing.append('_multiprocessing')
1281 # End multiprocessing
1283 # Platform-specific libraries
1284 if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
1285 'freebsd7', 'freebsd8'):
1286 exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
1287 else:
1288 missing.append('ossaudiodev')
1290 if sys.platform == 'darwin':
1291 exts.append(
1292 Extension('_gestalt', ['_gestalt.c'],
1293 extra_link_args=['-framework', 'Carbon'])
1295 exts.append(
1296 Extension('_scproxy', ['_scproxy.c'],
1297 extra_link_args=[
1298 '-framework', 'SystemConfiguration',
1299 '-framework', 'CoreFoundation',
1302 self.extensions.extend(exts)
1304 # Call the method for detecting whether _tkinter can be compiled
1305 self.detect_tkinter(inc_dirs, lib_dirs)
1307 if '_tkinter' not in [e.name for e in self.extensions]:
1308 missing.append('_tkinter')
1310 return missing
1312 def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
1313 # The _tkinter module, using frameworks. Since frameworks are quite
1314 # different the UNIX search logic is not sharable.
1315 from os.path import join, exists
1316 framework_dirs = [
1317 '/Library/Frameworks',
1318 '/System/Library/Frameworks/',
1319 join(os.getenv('HOME'), '/Library/Frameworks')
1322 sysroot = macosx_sdk_root()
1324 # Find the directory that contains the Tcl.framework and Tk.framework
1325 # bundles.
1326 # XXX distutils should support -F!
1327 for F in framework_dirs:
1328 # both Tcl.framework and Tk.framework should be present
1331 for fw in 'Tcl', 'Tk':
1332 if is_macosx_sdk_path(F):
1333 if not exists(join(sysroot, F[1:], fw + '.framework')):
1334 break
1335 else:
1336 if not exists(join(F, fw + '.framework')):
1337 break
1338 else:
1339 # ok, F is now directory with both frameworks. Continure
1340 # building
1341 break
1342 else:
1343 # Tk and Tcl frameworks not found. Normal "unix" tkinter search
1344 # will now resume.
1345 return 0
1347 # For 8.4a2, we must add -I options that point inside the Tcl and Tk
1348 # frameworks. In later release we should hopefully be able to pass
1349 # the -F option to gcc, which specifies a framework lookup path.
1351 include_dirs = [
1352 join(F, fw + '.framework', H)
1353 for fw in ('Tcl', 'Tk')
1354 for H in ('Headers', 'Versions/Current/PrivateHeaders')
1357 # For 8.4a2, the X11 headers are not included. Rather than include a
1358 # complicated search, this is a hard-coded path. It could bail out
1359 # if X11 libs are not found...
1360 include_dirs.append('/usr/X11R6/include')
1361 frameworks = ['-framework', 'Tcl', '-framework', 'Tk']
1363 # All existing framework builds of Tcl/Tk don't support 64-bit
1364 # architectures.
1365 cflags = sysconfig.get_config_vars('CFLAGS')[0]
1366 archs = re.findall('-arch\s+(\w+)', cflags)
1368 tmpfile = os.path.join(self.build_temp, 'tk.arch')
1369 if not os.path.exists(self.build_temp):
1370 os.makedirs(self.build_temp)
1372 # Note: cannot use os.popen or subprocess here, that
1373 # requires extensions that are not available here.
1374 if is_macosx_sdk_path(F):
1375 os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile))
1376 else:
1377 os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile))
1378 fp = open(tmpfile)
1380 detected_archs = []
1381 for ln in fp:
1382 a = ln.split()[-1]
1383 if a in archs:
1384 detected_archs.append(ln.split()[-1])
1385 fp.close()
1386 os.unlink(tmpfile)
1388 for a in detected_archs:
1389 frameworks.append('-arch')
1390 frameworks.append(a)
1392 ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
1393 define_macros=[('WITH_APPINIT', 1)],
1394 include_dirs = include_dirs,
1395 libraries = [],
1396 extra_compile_args = frameworks[2:],
1397 extra_link_args = frameworks,
1399 self.extensions.append(ext)
1400 return 1
1403 def detect_tkinter(self, inc_dirs, lib_dirs):
1404 # The _tkinter module.
1406 # Rather than complicate the code below, detecting and building
1407 # AquaTk is a separate method. Only one Tkinter will be built on
1408 # Darwin - either AquaTk, if it is found, or X11 based Tk.
1409 platform = self.get_platform()
1410 if (platform == 'darwin' and
1411 self.detect_tkinter_darwin(inc_dirs, lib_dirs)):
1412 return
1414 # Assume we haven't found any of the libraries or include files
1415 # The versions with dots are used on Unix, and the versions without
1416 # dots on Windows, for detection by cygwin.
1417 tcllib = tklib = tcl_includes = tk_includes = None
1418 for version in ['8.5', '85', '8.4', '84', '8.3', '83', '8.2',
1419 '82', '8.1', '81', '8.0', '80']:
1420 tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version)
1421 tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version)
1422 if tklib and tcllib:
1423 # Exit the loop when we've found the Tcl/Tk libraries
1424 break
1426 # Now check for the header files
1427 if tklib and tcllib:
1428 # Check for the include files on Debian and {Free,Open}BSD, where
1429 # they're put in /usr/include/{tcl,tk}X.Y
1430 dotversion = version
1431 if '.' not in dotversion and "bsd" in sys.platform.lower():
1432 # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a,
1433 # but the include subdirs are named like .../include/tcl8.3.
1434 dotversion = dotversion[:-1] + '.' + dotversion[-1]
1435 tcl_include_sub = []
1436 tk_include_sub = []
1437 for dir in inc_dirs:
1438 tcl_include_sub += [dir + os.sep + "tcl" + dotversion]
1439 tk_include_sub += [dir + os.sep + "tk" + dotversion]
1440 tk_include_sub += tcl_include_sub
1441 tcl_includes = find_file('tcl.h', inc_dirs, tcl_include_sub)
1442 tk_includes = find_file('tk.h', inc_dirs, tk_include_sub)
1444 if (tcllib is None or tklib is None or
1445 tcl_includes is None or tk_includes is None):
1446 self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2)
1447 return
1449 # OK... everything seems to be present for Tcl/Tk.
1451 include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = []
1452 for dir in tcl_includes + tk_includes:
1453 if dir not in include_dirs:
1454 include_dirs.append(dir)
1456 # Check for various platform-specific directories
1457 if platform == 'sunos5':
1458 include_dirs.append('/usr/openwin/include')
1459 added_lib_dirs.append('/usr/openwin/lib')
1460 elif os.path.exists('/usr/X11R6/include'):
1461 include_dirs.append('/usr/X11R6/include')
1462 added_lib_dirs.append('/usr/X11R6/lib64')
1463 added_lib_dirs.append('/usr/X11R6/lib')
1464 elif os.path.exists('/usr/X11R5/include'):
1465 include_dirs.append('/usr/X11R5/include')
1466 added_lib_dirs.append('/usr/X11R5/lib')
1467 else:
1468 # Assume default location for X11
1469 include_dirs.append('/usr/X11/include')
1470 added_lib_dirs.append('/usr/X11/lib')
1472 # If Cygwin, then verify that X is installed before proceeding
1473 if platform == 'cygwin':
1474 x11_inc = find_file('X11/Xlib.h', [], include_dirs)
1475 if x11_inc is None:
1476 return
1478 # Check for BLT extension
1479 if self.compiler.find_library_file(lib_dirs + added_lib_dirs,
1480 'BLT8.0'):
1481 defs.append( ('WITH_BLT', 1) )
1482 libs.append('BLT8.0')
1483 elif self.compiler.find_library_file(lib_dirs + added_lib_dirs,
1484 'BLT'):
1485 defs.append( ('WITH_BLT', 1) )
1486 libs.append('BLT')
1488 # Add the Tcl/Tk libraries
1489 libs.append('tk'+ version)
1490 libs.append('tcl'+ version)
1492 if platform in ['aix3', 'aix4']:
1493 libs.append('ld')
1495 # Finally, link with the X11 libraries (not appropriate on cygwin)
1496 if platform != "cygwin":
1497 libs.append('X11')
1499 ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'],
1500 define_macros=[('WITH_APPINIT', 1)] + defs,
1501 include_dirs = include_dirs,
1502 libraries = libs,
1503 library_dirs = added_lib_dirs,
1505 self.extensions.append(ext)
1507 ## # Uncomment these lines if you want to play with xxmodule.c
1508 ## ext = Extension('xx', ['xxmodule.c'])
1509 ## self.extensions.append(ext)
1511 # XXX handle these, but how to detect?
1512 # *** Uncomment and edit for PIL (TkImaging) extension only:
1513 # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \
1514 # *** Uncomment and edit for TOGL extension only:
1515 # -DWITH_TOGL togl.c \
1516 # *** Uncomment these for TOGL extension only:
1517 # -lGL -lGLU -lXext -lXmu \
1519 def configure_ctypes_darwin(self, ext):
1520 # Darwin (OS X) uses preconfigured files, in
1521 # the Modules/_ctypes/libffi_osx directory.
1522 srcdir = sysconfig.get_config_var('srcdir')
1523 ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
1524 '_ctypes', 'libffi_osx'))
1525 sources = [os.path.join(ffi_srcdir, p)
1526 for p in ['ffi.c',
1527 'x86/darwin64.S',
1528 'x86/x86-darwin.S',
1529 'x86/x86-ffi_darwin.c',
1530 'x86/x86-ffi64.c',
1531 'powerpc/ppc-darwin.S',
1532 'powerpc/ppc-darwin_closure.S',
1533 'powerpc/ppc-ffi_darwin.c',
1534 'powerpc/ppc64-darwin_closure.S',
1537 # Add .S (preprocessed assembly) to C compiler source extensions.
1538 self.compiler.src_extensions.append('.S')
1540 include_dirs = [os.path.join(ffi_srcdir, 'include'),
1541 os.path.join(ffi_srcdir, 'powerpc')]
1542 ext.include_dirs.extend(include_dirs)
1543 ext.sources.extend(sources)
1544 return True
1546 def configure_ctypes(self, ext):
1547 if not self.use_system_libffi:
1548 if sys.platform == 'darwin':
1549 return self.configure_ctypes_darwin(ext)
1551 srcdir = sysconfig.get_config_var('srcdir')
1552 ffi_builddir = os.path.join(self.build_temp, 'libffi')
1553 ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules',
1554 '_ctypes', 'libffi'))
1555 ffi_configfile = os.path.join(ffi_builddir, 'fficonfig.py')
1557 from distutils.dep_util import newer_group
1559 config_sources = [os.path.join(ffi_srcdir, fname)
1560 for fname in os.listdir(ffi_srcdir)
1561 if os.path.isfile(os.path.join(ffi_srcdir, fname))]
1562 if self.force or newer_group(config_sources,
1563 ffi_configfile):
1564 from distutils.dir_util import mkpath
1565 mkpath(ffi_builddir)
1566 config_args = []
1568 # Pass empty CFLAGS because we'll just append the resulting
1569 # CFLAGS to Python's; -g or -O2 is to be avoided.
1570 cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \
1571 % (ffi_builddir, ffi_srcdir, " ".join(config_args))
1573 res = os.system(cmd)
1574 if res or not os.path.exists(ffi_configfile):
1575 print("Failed to configure _ctypes module")
1576 return False
1578 fficonfig = {}
1579 fp = open(ffi_configfile)
1580 try:
1581 script = fp.read()
1582 finally:
1583 fp.close()
1584 exec(script, globals(), fficonfig)
1585 ffi_srcdir = os.path.join(fficonfig['ffi_srcdir'], 'src')
1587 # Add .S (preprocessed assembly) to C compiler source extensions.
1588 self.compiler.src_extensions.append('.S')
1590 include_dirs = [os.path.join(ffi_builddir, 'include'),
1591 ffi_builddir, ffi_srcdir]
1592 extra_compile_args = fficonfig['ffi_cflags'].split()
1594 ext.sources.extend(fficonfig['ffi_sources'])
1595 ext.include_dirs.extend(include_dirs)
1596 ext.extra_compile_args.extend(extra_compile_args)
1597 return True
1599 def detect_ctypes(self, inc_dirs, lib_dirs):
1600 self.use_system_libffi = False
1601 include_dirs = []
1602 extra_compile_args = []
1603 extra_link_args = []
1604 sources = ['_ctypes/_ctypes.c',
1605 '_ctypes/callbacks.c',
1606 '_ctypes/callproc.c',
1607 '_ctypes/stgdict.c',
1608 '_ctypes/cfield.c',
1609 '_ctypes/malloc_closure.c']
1610 depends = ['_ctypes/ctypes.h']
1612 if sys.platform == 'darwin':
1613 sources.append('_ctypes/darwin/dlfcn_simple.c')
1614 extra_compile_args.append('-DMACOSX')
1615 include_dirs.append('_ctypes/darwin')
1616 # XXX Is this still needed?
1617 ## extra_link_args.extend(['-read_only_relocs', 'warning'])
1619 elif sys.platform == 'sunos5':
1620 # XXX This shouldn't be necessary; it appears that some
1621 # of the assembler code is non-PIC (i.e. it has relocations
1622 # when it shouldn't. The proper fix would be to rewrite
1623 # the assembler code to be PIC.
1624 # This only works with GCC; the Sun compiler likely refuses
1625 # this option. If you want to compile ctypes with the Sun
1626 # compiler, please research a proper solution, instead of
1627 # finding some -z option for the Sun compiler.
1628 extra_link_args.append('-mimpure-text')
1630 elif sys.platform.startswith('hp-ux'):
1631 extra_link_args.append('-fPIC')
1633 ext = Extension('_ctypes',
1634 include_dirs=include_dirs,
1635 extra_compile_args=extra_compile_args,
1636 extra_link_args=extra_link_args,
1637 libraries=[],
1638 sources=sources,
1639 depends=depends)
1640 ext_test = Extension('_ctypes_test',
1641 sources=['_ctypes/_ctypes_test.c'])
1642 self.extensions.extend([ext, ext_test])
1644 if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"):
1645 return
1647 if sys.platform == 'darwin':
1648 # OS X 10.5 comes with libffi.dylib; the include files are
1649 # in /usr/include/ffi
1650 inc_dirs.append('/usr/include/ffi')
1652 ffi_inc = find_file('ffi.h', [], inc_dirs)
1653 if ffi_inc is not None:
1654 ffi_h = ffi_inc[0] + '/ffi.h'
1655 fp = open(ffi_h)
1656 while 1:
1657 line = fp.readline()
1658 if not line:
1659 ffi_inc = None
1660 break
1661 if line.startswith('#define LIBFFI_H'):
1662 break
1663 ffi_lib = None
1664 if ffi_inc is not None:
1665 for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'):
1666 if (self.compiler.find_library_file(lib_dirs, lib_name)):
1667 ffi_lib = lib_name
1668 break
1670 if ffi_inc and ffi_lib:
1671 ext.include_dirs.extend(ffi_inc)
1672 ext.libraries.append(ffi_lib)
1673 self.use_system_libffi = True
1676 class PyBuildInstall(install):
1677 # Suppress the warning about installation into the lib_dynload
1678 # directory, which is not in sys.path when running Python during
1679 # installation:
1680 def initialize_options (self):
1681 install.initialize_options(self)
1682 self.warn_dir=0
1684 class PyBuildInstallLib(install_lib):
1685 # Do exactly what install_lib does but make sure correct access modes get
1686 # set on installed directories and files. All installed files with get
1687 # mode 644 unless they are a shared library in which case they will get
1688 # mode 755. All installed directories will get mode 755.
1690 so_ext = sysconfig.get_config_var("SO")
1692 def install(self):
1693 outfiles = install_lib.install(self)
1694 self.set_file_modes(outfiles, 0o644, 0o755)
1695 self.set_dir_modes(self.install_dir, 0o755)
1696 return outfiles
1698 def set_file_modes(self, files, defaultMode, sharedLibMode):
1699 if not self.is_chmod_supported(): return
1700 if not files: return
1702 for filename in files:
1703 if os.path.islink(filename): continue
1704 mode = defaultMode
1705 if filename.endswith(self.so_ext): mode = sharedLibMode
1706 log.info("changing mode of %s to %o", filename, mode)
1707 if not self.dry_run: os.chmod(filename, mode)
1709 def set_dir_modes(self, dirname, mode):
1710 if not self.is_chmod_supported(): return
1711 for dirpath, dirnames, fnames in os.walk(dirname):
1712 if os.path.islink(dirpath):
1713 continue
1714 log.info("changing mode of %s to %o", dirpath, mode)
1715 if not self.dry_run: os.chmod(dirpath, mode)
1717 def is_chmod_supported(self):
1718 return hasattr(os, 'chmod')
1720 SUMMARY = """
1721 Python is an interpreted, interactive, object-oriented programming
1722 language. It is often compared to Tcl, Perl, Scheme or Java.
1724 Python combines remarkable power with very clear syntax. It has
1725 modules, classes, exceptions, very high level dynamic data types, and
1726 dynamic typing. There are interfaces to many system calls and
1727 libraries, as well as to various windowing systems (X11, Motif, Tk,
1728 Mac, MFC). New built-in modules are easily written in C or C++. Python
1729 is also usable as an extension language for applications that need a
1730 programmable interface.
1732 The Python implementation is portable: it runs on many brands of UNIX,
1733 on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't
1734 listed here, it may still be supported, if there's a C compiler for
1735 it. Ask around on comp.lang.python -- or just try compiling Python
1736 yourself.
1739 CLASSIFIERS = """
1740 Development Status :: 6 - Mature
1741 License :: OSI Approved :: Python Software Foundation License
1742 Natural Language :: English
1743 Programming Language :: C
1744 Programming Language :: Python
1745 Topic :: Software Development
1748 def main():
1749 # turn off warnings when deprecated modules are imported
1750 import warnings
1751 warnings.filterwarnings("ignore",category=DeprecationWarning)
1752 setup(# PyPI Metadata (PEP 301)
1753 name = "Python",
1754 version = sys.version.split()[0],
1755 url = "http://www.python.org/%s" % sys.version[:3],
1756 maintainer = "Guido van Rossum and the Python community",
1757 maintainer_email = "python-dev@python.org",
1758 description = "A high-level object-oriented programming language",
1759 long_description = SUMMARY.strip(),
1760 license = "PSF license",
1761 classifiers = [x for x in CLASSIFIERS.split("\n") if x],
1762 platforms = ["Many"],
1764 # Build info
1765 cmdclass = {'build_ext':PyBuildExt, 'install':PyBuildInstall,
1766 'install_lib':PyBuildInstallLib},
1767 # The struct module is defined here, because build_ext won't be
1768 # called unless there's at least one extension module defined.
1769 ext_modules=[Extension('_struct', ['_struct.c'])],
1771 scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3",
1772 "Tools/scripts/2to3"]
1775 # --install-platlib
1776 if __name__ == '__main__':
1777 main()