diff options
Diffstat (limited to 'setup.py')
-rw-r--r-- | setup.py | 113 |
1 files changed, 83 insertions, 30 deletions
@@ -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"): |