patch 1673619 - identify extension modules which cannot be built

This commit is contained in:
Skip Montanaro 2007-03-06 15:41:38 +00:00
parent ab8a6bba25
commit d1287323ca
2 changed files with 112 additions and 4 deletions

View File

@ -141,6 +141,9 @@ Core and builtins
Library
-------
- Patch #1673619: setup.py identifies extension modules it doesn't know how
to build and those it knows how to build but that fail to build.
- Patch #912410: Replace HTML entity references for attribute values
in HTMLParser.

113
setup.py
View File

@ -91,10 +91,14 @@ def find_module_file(module, dirlist):
class PyBuildExt(build_ext):
def __init__(self, dist):
build_ext.__init__(self, dist)
self.failed = []
def build_extensions(self):
# Detect which modules should be compiled
self.detect_modules()
missing = self.detect_modules()
# Remove modules that are present on the disabled list
self.extensions = [ext for ext in self.extensions
@ -178,6 +182,31 @@ class PyBuildExt(build_ext):
build_ext.build_extensions(self)
longest = max([len(e.name) for e in self.extensions])
if self.failed:
longest = max(longest, max([len(name) for name in self.failed]))
def print_three_column(lst):
lst.sort(cmp=str.lower)
# guarantee zip() doesn't drop anything
while len(lst) % 3:
lst.append("")
for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]):
print "%-*s %-*s %-*s" % (longest, e, longest, f,
longest, g)
print
if missing:
print
print "Failed to find the necessary bits to build these modules:"
print_three_column(missing)
if self.failed:
failed = self.failed[:]
print
print "Failed to build these modules:"
print_three_column(failed)
def build_extension(self, ext):
if ext.name == '_ctypes':
@ -189,6 +218,7 @@ class PyBuildExt(build_ext):
except (CCompilerError, DistutilsError), why:
self.announce('WARNING: building of extension "%s" failed: %s' %
(ext.name, sys.exc_info()[1]))
self.failed.append(ext.name)
return
# Workaround for Mac OS X: The Carbon-based modules cannot be
# reliably imported into a command-line Python
@ -209,6 +239,7 @@ class PyBuildExt(build_ext):
try:
imp.load_dynamic(ext.name, ext_filename)
except ImportError, why:
self.failed.append(ext.name)
self.announce('*** WARNING: renaming "%s" since importing it'
' failed: %s' % (ext.name, why), level=3)
assert not self.inplace
@ -234,6 +265,7 @@ class PyBuildExt(build_ext):
self.announce('*** WARNING: importing extension "%s" '
'failed with %s: %s' % (ext.name, exc_type, why),
level=3)
self.failed.append(ext.name)
def get_platform(self):
# Get value of sys.platform
@ -299,6 +331,7 @@ class PyBuildExt(build_ext):
]
inc_dirs = self.compiler.include_dirs + ['/usr/include']
exts = []
missing = []
config_h = sysconfig.get_config_h_filename()
config_h_vars = sysconfig.parse_config_h(open(config_h))
@ -387,6 +420,8 @@ class PyBuildExt(build_ext):
# static Unicode character database
if have_unicode:
exts.append( Extension('unicodedata', ['unicodedata.c']) )
else:
missing.append('unicodedata')
# access to ISO C locale support
data = open('pyconfig.h').read()
m = re.search(r"#s*define\s+WITH_LIBINTL\s+1\s*", data)
@ -419,6 +454,11 @@ class PyBuildExt(build_ext):
if (config_h_vars.get('HAVE_GETSPNAM', False) or
config_h_vars.get('HAVE_GETSPENT', False)):
exts.append( Extension('spwd', ['spwdmodule.c']) )
else:
missing.append('spwd')
else:
missing.extend(['pwd', 'grp', 'spwd'])
# select(2); not on ancient System V
exts.append( Extension('select', ['selectmodule.c']) )
@ -435,11 +475,15 @@ class PyBuildExt(build_ext):
# Memory-mapped files (also works on Win32).
if platform not in ['atheos', 'mac']:
exts.append( Extension('mmap', ['mmapmodule.c']) )
else:
missing.append('mmap')
# Lance Ellinghaus's syslog module
if platform not in ['mac']:
# syslog daemon interface
exts.append( Extension('syslog', ['syslogmodule.c']) )
else:
missing.append('syslog')
# George Neville-Neil's timing module:
# Deprecated in PEP 4 http://www.python.org/peps/pep-0004.html
@ -466,6 +510,8 @@ class PyBuildExt(build_ext):
exts.append( Extension('imageop', ['imageop.c']) )
# Read SGI RGB image files (but coded portably)
exts.append( Extension('rgbimg', ['rgbimgmodule.c']) )
else:
missing.extend(['imageop', 'rgbimg'])
# readline
do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
@ -503,6 +549,9 @@ class PyBuildExt(build_ext):
library_dirs=['/usr/lib/termcap'],
extra_link_args=readline_extra_link_args,
libraries=readline_libs) )
else:
missing.append('readline')
if platform not in ['mac']:
# crypt module.
@ -511,6 +560,8 @@ class PyBuildExt(build_ext):
else:
libs = []
exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) )
else:
missing.append('crypt')
# CSV files
exts.append( Extension('_csv', ['_csv.c']) )
@ -543,6 +594,8 @@ class PyBuildExt(build_ext):
library_dirs = ssl_libs,
libraries = ['ssl', 'crypto'],
depends = ['socketmodule.h']), )
else:
missing.append('_ssl')
# find out which version of OpenSSL we have
openssl_ver = 0
@ -576,6 +629,7 @@ class PyBuildExt(build_ext):
include_dirs = ssl_incs,
library_dirs = ssl_libs,
libraries = ['ssl', 'crypto']) )
missing.extend(['_sha', '_md5'])
else:
# The _sha module implements the SHA1 hash algorithm.
exts.append( Extension('_sha', ['shamodule.c']) )
@ -585,12 +639,14 @@ class PyBuildExt(build_ext):
exts.append( Extension('_md5',
sources = ['md5module.c', 'md5.c'],
depends = ['md5.h']) )
missing.append('_hashlib')
if (openssl_ver < 0x00908000):
# OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash
exts.append( Extension('_sha256', ['sha256module.c']) )
exts.append( Extension('_sha512', ['sha512module.c']) )
else:
missing.extend(['_sha256', '_sha512'])
# Modules that provide persistent dictionary-like semantics. You will
# probably want to arrange for at least one of them to be available on
@ -743,6 +799,7 @@ class PyBuildExt(build_ext):
db_incs = None
dblibs = []
dblib_dir = None
missing.append('_bsddb')
# The sqlite interface
sqlite_setup_debug = False # verbose debug prints from this script?
@ -835,6 +892,8 @@ class PyBuildExt(build_ext):
runtime_library_dirs=sqlite_libdir,
extra_link_args=sqlite_extra_link_args,
libraries=["sqlite3",]))
else:
missing.append('_sqlite3')
# Look for Berkeley db 1.85. Note that it is built as a different
# module name so it can be included even when later versions are
@ -857,6 +916,10 @@ class PyBuildExt(build_ext):
libraries=libraries))
else:
exts.append(Extension('bsddb185', ['bsddbmodule.c']))
else:
missing.append('bsddb185')
else:
missing.append('bsddb185')
# The standard Unix dbm module:
if platform not in ['cygwin']:
@ -882,11 +945,15 @@ class PyBuildExt(build_ext):
define_macros=[('HAVE_BERKDB_H',None),
('DB_DBM_HSEARCH',None)],
libraries=dblibs))
else:
missing.append('dbm')
# Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm:
if (self.compiler.find_library_file(lib_dirs, 'gdbm')):
exts.append( Extension('gdbm', ['gdbmmodule.c'],
libraries = ['gdbm'] ) )
else:
missing.append('gdbm')
# Unix-only modules
if platform not in ['mac', 'win32']:
@ -895,6 +962,8 @@ class PyBuildExt(build_ext):
# Jeremy Hylton's rlimit interface
if platform not in ['atheos']:
exts.append( Extension('resource', ['resource.c']) )
else:
missing.append('resource')
# Sun yellow pages. Some systems have the functions in libc.
if platform not in ['cygwin', 'atheos']:
@ -904,6 +973,10 @@ class PyBuildExt(build_ext):
libs = []
exts.append( Extension('nis', ['nismodule.c'],
libraries = libs) )
else:
missing.append('nis')
else:
missing.extend(['nis', 'resource', 'termios'])
# Curses support, requiring the System V version of curses, often
# provided by the ncurses library.
@ -932,13 +1005,16 @@ class PyBuildExt(build_ext):
exts.append( Extension('_curses', ['_cursesmodule.c'],
libraries = curses_libs) )
else:
missing.append('_curses')
# If the curses module is enabled, check for the panel module
if (module_enabled(exts, '_curses') and
self.compiler.find_library_file(lib_dirs, panel_library)):
exts.append( Extension('_curses_panel', ['_curses_panel.c'],
libraries = [panel_library] + curses_libs) )
else:
missing.append('_curses_panel')
# Andrew Kuchling's zlib module. Note that some versions of zlib
# 1.1.3 have security problems. See CERT Advisory CA-2002-07:
@ -974,6 +1050,12 @@ class PyBuildExt(build_ext):
exts.append( Extension('zlib', ['zlibmodule.c'],
libraries = ['z'],
extra_link_args = zlib_extra_link_args))
else:
missing.append('zlib')
else:
missing.append('zlib')
else:
missing.append('zlib')
# Gustavo Niemeyer's bz2 module.
if (self.compiler.find_library_file(lib_dirs, 'bz2')):
@ -984,6 +1066,8 @@ class PyBuildExt(build_ext):
exts.append( Extension('bz2', ['bz2module.c'],
libraries = ['bz2'],
extra_link_args = bz2_extra_link_args) )
else:
missing.append('bz2')
# Interface to the Expat XML parser
#
@ -1021,14 +1105,20 @@ class PyBuildExt(build_ext):
include_dirs = [expatinc],
sources = ['_elementtree.c'],
))
else:
missing.append('_elementtree')
# Hye-Shik Chang's CJKCodecs modules.
if have_unicode:
exts.append(Extension('_multibytecodec',
['cjkcodecs/multibytecodec.c']))
for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
exts.append(Extension('_codecs_' + loc,
exts.append(Extension('_codecs_%s' % loc,
['cjkcodecs/_codecs_%s.c' % loc]))
else:
missing.append('_multibytecodec')
for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'):
missing.append('_codecs_%s' % loc)
# Dynamic loading module
if sys.maxint == 0x7fffffff:
@ -1036,6 +1126,10 @@ class PyBuildExt(build_ext):
dl_inc = find_file('dlfcn.h', [], inc_dirs)
if (dl_inc is not None) and (platform not in ['atheos']):
exts.append( Extension('dl', ['dlmodule.c']) )
else:
missing.append('dl')
else:
missing.append('dl')
# Thomas Heller's _ctypes module
self.detect_ctypes(inc_dirs, lib_dirs)
@ -1044,14 +1138,20 @@ class PyBuildExt(build_ext):
if platform == 'linux2':
# Linux-specific modules
exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
else:
missing.append('linuxaudiodev')
if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
'freebsd7'):
exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
else:
missing.append('ossaudiodev')
if platform == 'sunos5':
# SunOS specific modules
exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
else:
missing.append('sunaudiodev')
if platform == 'darwin' and ("--disable-toolbox-glue" not in
sysconfig.get_config_var("CONFIG_ARGS")):
@ -1140,6 +1240,11 @@ class PyBuildExt(build_ext):
# Call the method for detecting whether _tkinter can be compiled
self.detect_tkinter(inc_dirs, lib_dirs)
if '_tkinter' not in [e.name for e in self.extensions]:
missing.append('_tkinter')
return missing
def detect_tkinter_darwin(self, inc_dirs, lib_dirs):
# The _tkinter module, using frameworks. Since frameworks are quite
# different the UNIX search logic is not sharable.