diff options
Diffstat (limited to 'setup.py')
-rw-r--r-- | setup.py | 250 |
1 files changed, 250 insertions, 0 deletions
diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..f980590 --- /dev/null +++ b/setup.py @@ -0,0 +1,250 @@ +import sys, os +import subprocess +import errno + +# on Windows we give up and always import setuptools early to fix things for us +if sys.platform == "win32": + import setuptools + + +sources = ['c/_cffi_backend.c'] +libraries = ['ffi'] +include_dirs = ['/usr/include/ffi', + '/usr/include/libffi'] # may be changed by pkg-config +define_macros = [] +library_dirs = [] +extra_compile_args = [] +extra_link_args = [] + + +def _ask_pkg_config(resultlist, option, result_prefix='', sysroot=False): + pkg_config = os.environ.get('PKG_CONFIG','pkg-config') + try: + p = subprocess.Popen([pkg_config, option, 'libffi'], + stdout=subprocess.PIPE) + except OSError as e: + if e.errno not in [errno.ENOENT, errno.EACCES]: + raise + else: + t = p.stdout.read().decode().strip() + p.stdout.close() + if p.wait() == 0: + res = t.split() + # '-I/usr/...' -> '/usr/...' + for x in res: + assert x.startswith(result_prefix) + res = [x[len(result_prefix):] for x in res] + #print 'PKG_CONFIG:', option, res + # + sysroot = sysroot and os.environ.get('PKG_CONFIG_SYSROOT_DIR', '') + if sysroot: + # old versions of pkg-config don't support this env var, + # so here we emulate its effect if needed + res = [path if path.startswith(sysroot) + else sysroot + path + for path in res] + # + resultlist[:] = res + +no_compiler_found = False +def no_working_compiler_found(): + sys.stderr.write(""" + No working compiler found, or bogus compiler options passed to + the compiler from Python's standard "distutils" module. See + the error messages above. Likely, the problem is not related + to CFFI but generic to the setup.py of any Python package that + tries to compile C code. (Hints: on OS/X 10.8, for errors about + -mno-fused-madd see http://stackoverflow.com/questions/22313407/ + Otherwise, see https://wiki.python.org/moin/CompLangPython or + the IRC channel #python on irc.freenode.net.) + + Trying to continue anyway. If you are trying to install CFFI from + a build done in a different context, you can ignore this warning. + \n""") + global no_compiler_found + no_compiler_found = True + +def get_config(): + from distutils.core import Distribution + from distutils.sysconfig import get_config_vars + get_config_vars() # workaround for a bug of distutils, e.g. on OS/X + config = Distribution().get_command_obj('config') + return config + +def ask_supports_thread(): + config = get_config() + ok = (sys.platform != 'win32' and + config.try_compile('__thread int some_threadlocal_variable_42;')) + if ok: + define_macros.append(('USE__THREAD', None)) + else: + ok1 = config.try_compile('int some_regular_variable_42;') + if not ok1: + no_working_compiler_found() + else: + sys.stderr.write("Note: will not use '__thread' in the C code\n") + _safe_to_ignore() + +def ask_supports_sync_synchronize(): + if sys.platform == 'win32' or no_compiler_found: + return + config = get_config() + ok = config.try_link('int main(void) { __sync_synchronize(); return 0; }') + if ok: + define_macros.append(('HAVE_SYNC_SYNCHRONIZE', None)) + else: + sys.stderr.write("Note: will not use '__sync_synchronize()'" + " in the C code\n") + _safe_to_ignore() + +def _safe_to_ignore(): + sys.stderr.write("***** The above error message can be safely ignored.\n\n") + +def uses_msvc(): + config = get_config() + return config.try_compile('#ifndef _MSC_VER\n#error "not MSVC"\n#endif') + +def use_pkg_config(): + if sys.platform == 'darwin' and os.path.exists('/usr/local/bin/brew'): + use_homebrew_for_libffi() + + _ask_pkg_config(include_dirs, '--cflags-only-I', '-I', sysroot=True) + _ask_pkg_config(extra_compile_args, '--cflags-only-other') + _ask_pkg_config(library_dirs, '--libs-only-L', '-L', sysroot=True) + _ask_pkg_config(extra_link_args, '--libs-only-other') + _ask_pkg_config(libraries, '--libs-only-l', '-l') + +def use_homebrew_for_libffi(): + # We can build by setting: + # PKG_CONFIG_PATH = $(brew --prefix libffi)/lib/pkgconfig + with os.popen('brew --prefix libffi') as brew_prefix_cmd: + prefix = brew_prefix_cmd.read().strip() + pkgconfig = os.path.join(prefix, 'lib', 'pkgconfig') + os.environ['PKG_CONFIG_PATH'] = ( + os.environ.get('PKG_CONFIG_PATH', '') + ':' + pkgconfig) + + +if sys.platform == 'win32' and uses_msvc(): + COMPILE_LIBFFI = 'c/libffi_msvc' # from the CPython distribution +else: + COMPILE_LIBFFI = None + +if COMPILE_LIBFFI: + assert os.path.isdir(COMPILE_LIBFFI), "directory not found!" + include_dirs[:] = [COMPILE_LIBFFI] + libraries[:] = [] + _filenames = [filename.lower() for filename in os.listdir(COMPILE_LIBFFI)] + _filenames = [filename for filename in _filenames + if filename.endswith('.c')] + if sys.maxsize > 2**32: + # 64-bit: unlist win32.c, and add instead win64.obj. If the obj + # happens to get outdated at some point in the future, you need to + # rebuild it manually from win64.asm. + _filenames.remove('win32.c') + extra_link_args.append(os.path.join(COMPILE_LIBFFI, 'win64.obj')) + sources.extend(os.path.join(COMPILE_LIBFFI, filename) + for filename in _filenames) +else: + use_pkg_config() + ask_supports_thread() + ask_supports_sync_synchronize() + +if 'freebsd' in sys.platform: + include_dirs.append('/usr/local/include') + library_dirs.append('/usr/local/lib') + +if 'darwin' in sys.platform: + try: + p = subprocess.Popen(['xcrun', '--show-sdk-path'], + stdout=subprocess.PIPE) + except OSError as e: + if e.errno not in [errno.ENOENT, errno.EACCES]: + raise + else: + t = p.stdout.read().decode().strip() + p.stdout.close() + if p.wait() == 0: + include_dirs.append(t + '/usr/include/ffi') + + + +if __name__ == '__main__': + from setuptools import setup, Distribution, Extension + + class CFFIDistribution(Distribution): + def has_ext_modules(self): + # Event if we don't have extension modules (e.g. on PyPy) we want to + # claim that we do so that wheels get properly tagged as Python + # specific. (thanks dstufft!) + return True + + # On PyPy, cffi is preinstalled and it is not possible, at least for now, + # to install a different version. We work around it by making the setup() + # arguments mostly empty in this case. + cpython = ('_cffi_backend' not in sys.builtin_module_names) + + setup( + name='cffi', + description='Foreign Function Interface for Python calling C code.', + long_description=""" +CFFI +==== + +Foreign Function Interface for Python calling C code. +Please see the `Documentation <http://cffi.readthedocs.org/>`_. + +Contact +------- + +`Mailing list <https://groups.google.com/forum/#!forum/python-cffi>`_ +""", + version='1.12.2', + packages=['cffi'] if cpython else [], + package_data={'cffi': ['_cffi_include.h', 'parse_c_type.h', + '_embedding.h', '_cffi_errors.h']} + if cpython else {}, + zip_safe=False, + + url='http://cffi.readthedocs.org', + author='Armin Rigo, Maciej Fijalkowski', + author_email='python-cffi@googlegroups.com', + + license='MIT', + + distclass=CFFIDistribution, + ext_modules=[Extension( + name='_cffi_backend', + include_dirs=include_dirs, + sources=sources, + libraries=libraries, + define_macros=define_macros, + library_dirs=library_dirs, + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, + )] if cpython else [], + + install_requires=[ + 'pycparser' if sys.version_info >= (2, 7) else 'pycparser<2.19', + ] if cpython else [], + + entry_points = { + "distutils.setup_keywords": [ + "cffi_modules = cffi.setuptools_ext:cffi_modules", + ], + }, + + classifiers=[ + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.6', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: Implementation :: CPython', + 'Programming Language :: Python :: Implementation :: PyPy', + ], + ) |