summaryrefslogtreecommitdiff
path: root/setup.py
diff options
context:
space:
mode:
Diffstat (limited to 'setup.py')
-rw-r--r--setup.py113
1 files changed, 83 insertions, 30 deletions
diff --git a/setup.py b/setup.py
index 277965837c..174ce720c8 100644
--- a/setup.py
+++ b/setup.py
@@ -25,6 +25,11 @@ cflags = sysconfig.get_config_var('CFLAGS')
py_cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST')
sysconfig.get_config_vars()['CFLAGS'] = cflags + ' ' + py_cflags_nodist
+class Dummy:
+ """Hack for parallel build"""
+ ProcessPoolExecutor = None
+sys.modules['concurrent.futures.process'] = Dummy
+
def get_platform():
# cross build
if "_PYTHON_HOST_PLATFORM" in os.environ:
@@ -131,6 +136,22 @@ def find_library_file(compiler, libname, std_dirs, paths):
p = p.rstrip(os.sep)
if host_platform == 'darwin' and is_macosx_sdk_path(p):
+ # Note that, as of Xcode 7, Apple SDKs may contain textual stub
+ # libraries with .tbd extensions rather than the normal .dylib
+ # shared libraries installed in /. The Apple compiler tool
+ # chain handles this transparently but it can cause problems
+ # for programs that are being built with an SDK and searching
+ # for specific libraries. Distutils find_library_file() now
+ # knows to also search for and return .tbd files. But callers
+ # of find_library_file need to keep in mind that the base filename
+ # of the returned SDK library file might have a different extension
+ # from that of the library file installed on the running system,
+ # for example:
+ # /Applications/Xcode.app/Contents/Developer/Platforms/
+ # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/
+ # usr/lib/libedit.tbd
+ # vs
+ # /usr/lib/libedit.dylib
if os.path.join(sysroot, p[1:]) == dirname:
return [ ]
@@ -173,6 +194,9 @@ class PyBuildExt(build_ext):
def __init__(self, dist):
build_ext.__init__(self, dist)
self.failed = []
+ self.failed_on_import = []
+ if '-j' in os.environ.get('MAKEFLAGS', ''):
+ self.parallel = True
def build_extensions(self):
@@ -252,9 +276,13 @@ class PyBuildExt(build_ext):
build_ext.build_extensions(self)
+ for ext in self.extensions:
+ self.check_extension_import(ext)
+
longest = max([len(e.name) for e in self.extensions], default=0)
- if self.failed:
- longest = max(longest, max([len(name) for name in self.failed]))
+ if self.failed or self.failed_on_import:
+ all_failed = self.failed + self.failed_on_import
+ longest = max(longest, max([len(name) for name in all_failed]))
def print_three_column(lst):
lst.sort(key=str.lower)
@@ -282,6 +310,14 @@ class PyBuildExt(build_ext):
print_three_column(failed)
print()
+ if self.failed_on_import:
+ failed = self.failed_on_import[:]
+ print()
+ print("Following modules built successfully"
+ " but were removed because they could not be imported:")
+ print_three_column(failed)
+ print()
+
def build_extension(self, ext):
if ext.name == '_ctypes':
@@ -295,6 +331,15 @@ class PyBuildExt(build_ext):
(ext.name, sys.exc_info()[1]))
self.failed.append(ext.name)
return
+
+ def check_extension_import(self, ext):
+ # Don't try to import an extension that has failed to compile
+ if ext.name in self.failed:
+ self.announce(
+ 'WARNING: skipping import check for failed build "%s"' %
+ ext.name, level=1)
+ return
+
# Workaround for Mac OS X: The Carbon-based modules cannot be
# reliably imported into a command-line Python
if 'Carbon' in ext.extra_link_args:
@@ -338,9 +383,9 @@ class PyBuildExt(build_ext):
spec = importlib.util.spec_from_file_location(ext.name, ext_filename,
loader=loader)
try:
- importlib._bootstrap._SpecMethods(spec).load()
+ importlib._bootstrap._load(spec)
except ImportError as why:
- self.failed.append(ext.name)
+ self.failed_on_import.append(ext.name)
self.announce('*** WARNING: renaming "%s" since importing it'
' failed: %s' % (ext.name, why), level=3)
assert not self.inplace
@@ -350,17 +395,6 @@ class PyBuildExt(build_ext):
os.remove(newname)
os.rename(ext_filename, newname)
- # XXX -- This relies on a Vile HACK in
- # distutils.command.build_ext.build_extension(). The
- # _built_objects attribute is stored there strictly for
- # use here.
- # If there is a failure, _built_objects may not be there,
- # so catch the AttributeError and move on.
- try:
- for filename in self._built_objects:
- os.remove(filename)
- except AttributeError:
- self.announce('unable to remove files (ignored)')
except:
exc_type, why, tb = sys.exc_info()
self.announce('*** WARNING: importing extension "%s" '
@@ -446,6 +480,13 @@ class PyBuildExt(build_ext):
finally:
os.unlink(tmpfile)
+ def detect_math_libs(self):
+ # Check for MacOS X, which doesn't need libm.a at all
+ if host_platform == 'darwin':
+ return []
+ else:
+ return ['m']
+
def detect_modules(self):
# Ensure that /usr/local is always used, but the local build
# directories (i.e. '.' and 'Include') must be first. See issue
@@ -550,10 +591,7 @@ class PyBuildExt(build_ext):
if item.startswith('-L'):
lib_dirs.append(item[2:])
- # Check for MacOS X, which doesn't need libm.a at all
- math_libs = ['m']
- if host_platform == 'darwin':
- math_libs = []
+ math_libs = self.detect_math_libs()
# XXX Omitted modules: gl, pure, dl, SGI-specific modules
@@ -564,13 +602,17 @@ class PyBuildExt(build_ext):
# array objects
exts.append( Extension('array', ['arraymodule.c']) )
+
+ shared_math = 'Modules/_math.o'
# complex math library functions
- exts.append( Extension('cmath', ['cmathmodule.c', '_math.c'],
- depends=['_math.h'],
+ exts.append( Extension('cmath', ['cmathmodule.c'],
+ extra_objects=[shared_math],
+ depends=['_math.h', shared_math],
libraries=math_libs) )
# math library functions, e.g. sin()
- exts.append( Extension('math', ['mathmodule.c', '_math.c'],
- depends=['_math.h'],
+ exts.append( Extension('math', ['mathmodule.c'],
+ extra_objects=[shared_math],
+ depends=['_math.h', shared_math],
libraries=math_libs) )
# time libraries: librt may be needed for clock_gettime()
@@ -582,7 +624,10 @@ class PyBuildExt(build_ext):
# time operations and variables
exts.append( Extension('time', ['timemodule.c'],
libraries=time_libs) )
- exts.append( Extension('_datetime', ['_datetimemodule.c']) )
+ # math_libs is needed by delta_new() that uses round() and by accum()
+ # that uses modf().
+ exts.append( Extension('_datetime', ['_datetimemodule.c'],
+ libraries=math_libs) )
# random number generator implemented in C
exts.append( Extension("_random", ["_randommodule.c"]) )
# bisect
@@ -602,6 +647,8 @@ class PyBuildExt(build_ext):
exts.append( Extension('_testbuffer', ['_testbuffer.c']) )
# Test loading multiple modules from one compiled file (http://bugs.python.org/issue16421)
exts.append( Extension('_testimportmultiple', ['_testimportmultiple.c']) )
+ # Test multi-phase extension module init (PEP 489)
+ exts.append( Extension('_testmultiphase', ['_testmultiphase.c']) )
# profiler (_lsprof is for cProfile.py)
exts.append( Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c']) )
# static Unicode character database
@@ -651,11 +698,14 @@ class PyBuildExt(build_ext):
# Multimedia modules
# These don't work for 64-bit platforms!!!
# These represent audio samples or images as strings:
-
+ #
# Operations on audio samples
# According to #993173, this one should actually work fine on
# 64-bit platforms.
- exts.append( Extension('audioop', ['audioop.c']) )
+ #
+ # audioop needs math_libs for floor() in multiple functions.
+ exts.append( Extension('audioop', ['audioop.c'],
+ libraries=math_libs) )
# readline
do_readline = self.compiler.find_library_file(lib_dirs, 'readline')
@@ -718,7 +768,7 @@ class PyBuildExt(build_ext):
# In every directory on the search path search for a dynamic
# library and then a static library, instead of first looking
# for dynamic libraries on the entire path.
- # This way a staticly linked custom readline gets picked up
+ # This way a statically linked custom readline gets picked up
# before the (possibly broken) dynamic library in /usr/lib.
readline_extra_link_args = ('-Wl,-search_paths_first',)
else:
@@ -1557,7 +1607,7 @@ class PyBuildExt(build_ext):
if 'd' not in sys.abiflags:
ext = Extension('xxlimited', ['xxlimited.c'],
- define_macros=[('Py_LIMITED_API', '0x03040000')])
+ define_macros=[('Py_LIMITED_API', '0x03050000')])
self.extensions.append(ext)
return missing
@@ -1572,7 +1622,7 @@ class PyBuildExt(build_ext):
# --with-tcltk-libs="-L/path/to/tcllibs -ltclm.n \
# -L/path/to/tklibs -ltkm.n"
#
- # These values can also be specified or overriden via make:
+ # These values can also be specified or overridden via make:
# make TCLTK_INCLUDES="..." TCLTK_LIBS="..."
#
# This can be useful for building and testing tkinter with multiple
@@ -1897,6 +1947,7 @@ class PyBuildExt(build_ext):
'_ctypes/stgdict.c',
'_ctypes/cfield.c']
depends = ['_ctypes/ctypes.h']
+ math_libs = self.detect_math_libs()
if host_platform == 'darwin':
sources.append('_ctypes/malloc_closure.c')
@@ -1927,8 +1978,10 @@ class PyBuildExt(build_ext):
libraries=[],
sources=sources,
depends=depends)
+ # function my_sqrt() needs math library for sqrt()
ext_test = Extension('_ctypes_test',
- sources=['_ctypes/_ctypes_test.c'])
+ sources=['_ctypes/_ctypes_test.c'],
+ libraries=math_libs)
self.extensions.extend([ext, ext_test])
if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"):