import os
import platform
import sys
from setuptools import setup, find_packages
# --with-librabbitmq=
: path to librabbitmq package if needed
LRMQDIST = lambda *x: os.path.join('clib', *x)
LRMQSRC = lambda *x: LRMQDIST('librabbitmq', *x)
SPECPATH = lambda *x: os.path.join('rabbitmq-codegen', *x)
PYCP = lambda *x: os.path.join('Modules', '_librabbitmq', *x)
def senv(*k__v, **kwargs):
sep = kwargs.get('sep', ' ')
restore = {}
for k, v in k__v:
prev = restore[k] = os.environ.get(k)
os.environ[k] = (prev + sep if prev else '') + str(v)
return dict((k, v) for k, v in restore.iteritems() if v is not None)
def codegen():
codegen = LRMQSRC('codegen.py')
spec = SPECPATH('amqp-rabbitmq-0.9.1.json')
sys.path.insert(0, SPECPATH())
commands = [
(sys.executable, codegen, 'header', spec, LRMQSRC('amqp_framing.h')),
(sys.executable, codegen, 'body', spec, LRMQSRC('amqp_framing.c')),
]
restore = senv(('PYTHONPATH', SPECPATH()), sep=':')
try:
for command in commands:
print('- generating %r' % command[-1])
print(' '.join(command))
os.system(' '.join(command))
finally:
os.environ.update(restore)
def create_builder():
from setuptools import Extension
from distutils.command.build import build as _build
cmd = None
pkgdirs = [] # incdirs and libdirs get these
libs = []
defs = []
incdirs = []
libdirs = []
def append_env(L, e):
v = os.environ.get(e)
if v and os.path.exists(v):
L.append(v)
append_env(pkgdirs, 'LIBRABBITMQ')
# Hack up sys.argv, yay
unprocessed = []
for arg in sys.argv[1:]:
if arg == '--gen-setup':
cmd = arg[2:]
elif '=' in arg:
if arg.startswith('--with-librabbitmq='):
pkgdirs.append(arg.split('=', 1)[1])
continue
unprocessed.append(arg)
sys.argv[1:] = unprocessed
incdirs.append(LRMQSRC())
PyC_files = map(PYCP, [
'connection.c',
])
librabbit_files = map(LRMQSRC, [
'amqp_api.c',
'amqp_connection.c',
'amqp_consumer.c',
'amqp_framing.c',
'amqp_hostcheck.c',
'amqp_mem.c',
'amqp_socket.c',
'amqp_table.c',
'amqp_tcp_socket.c',
'amqp_timer.c',
'amqp_url.c',
])
incdirs.append(LRMQDIST()) # for config.h
if is_linux: # Issue #42
libs.append('rt') # -lrt for clock_gettime
librabbitmq_ext = Extension(
'_librabbitmq',
sources=PyC_files + librabbit_files,
libraries=libs, include_dirs=incdirs,
library_dirs=libdirs, define_macros=defs,
)
# Hidden secret:
# If environment variable GEN_SETUP is set, generate Setup file.
if cmd == 'gen-setup':
line = ' '.join((
librabbitmq_ext.name,
' '.join('-l' + lib for lib in librabbitmq_ext.libraries),
' '.join('-I' + incdir for incdir in librabbitmq_ext.include_dirs),
' '.join('-L' + libdir for libdir in librabbitmq_ext.library_dirs),
' '.join('-D' + name + ('=' + str(value), '')[value is None]
for name, value in librabbitmq_ext.define_macros)))
open('Setup', 'w').write(line + '\n')
sys.exit(0)
class build(_build):
stdcflags = [
'-DHAVE_CONFIG_H',
]
if os.environ.get('PEDANTIC'):
# Python.h breaks -pedantic, so can only use it while developing.
stdcflags.append('-pedantic -Werror')
def run(self):
from distutils import sysconfig
here = os.path.abspath(os.getcwd())
config = sysconfig.get_config_vars()
try:
vars = {'ld': config['LDFLAGS'],
'c': config['CFLAGS']}
for key in list(vars):
vars[key] = vars[key].replace('-lSystem', '')
# Python on Maverics sets this, but not supported on clang
vars[key] = vars[key].replace('-mno-fused-madd', '')
vars[key] = vars[key].replace(
'-isysroot /Developer/SDKs/MacOSX10.6.sdk', '')
vars[key] = vars[key].replace('-Wall', '')
restore = senv(
('CFLAGS', vars['c']),
('LDFLAGS', vars['ld']),
)
try:
os.chdir(LRMQDIST())
if not os.path.isfile('config.h'):
print('- configure rabbitmq-c...')
if os.system('/bin/sh configure --disable-tools \
--disable-docs --disable-dependency-tracking'):
return
finally:
os.environ.update(restore)
finally:
os.chdir(here)
restore = senv(
('CFLAGS', ' '.join(self.stdcflags)),
)
codegen()
try:
_build.run(self)
finally:
os.environ.update(restore)
return librabbitmq_ext, build
def find_make(alt=('gmake', 'gnumake', 'make', 'nmake')):
for path in os.environ['PATH'].split(':'):
for make in (os.path.join(path, m) for m in alt):
if os.path.isfile(make):
return make
long_description = open('README.rst', 'U').read()
distmeta = open(PYCP('distmeta.h')).read().strip().splitlines()
distmeta = [item.split('\"')[1] for item in distmeta]
version = distmeta[0].strip()
author = distmeta[1].strip()
contact = distmeta[2].strip()
homepage = distmeta[3].strip()
ext_modules = []
cmdclass = {}
packages = []
goahead = False
is_jython = sys.platform.startswith('java')
is_pypy = hasattr(sys, 'pypy_version_info')
is_py3k = sys.version_info[0] == 3
is_win = platform.system() == 'Windows'
is_linux = platform.system() == 'Linux'
if is_jython or is_pypy or is_py3k or is_win:
pass
elif find_make():
try:
librabbitmq_ext, build = create_builder()
except Exception, exc:
print('Could not create builder: %r' % (exc, ))
raise
else:
goahead = True
ext_modules = [librabbitmq_ext]
cmdclass = {'build': build}
packages = find_packages(exclude=['ez_setup', 'tests', 'tests.*'])
if not goahead:
ext_modules = []
cmdclass = {}
packages = []
# 'install doesn't always call build for some reason
if 'install' in sys.argv and 'build' not in sys.argv:
_index = sys.argv.index('install')
sys.argv[:] = (
sys.argv[:_index] + ['build', 'install'] + sys.argv[_index + 1:]
)
setup(
name='librabbitmq',
version=version,
url=homepage,
author=author,
author_email=contact,
license='MPL',
description='AMQP Client using the rabbitmq-c library.',
long_description=long_description,
test_suite='nose.collector',
zip_safe=False,
packages=packages,
cmdclass=cmdclass,
install_requires=[
'amqp>=1.4.6',
],
ext_modules=ext_modules,
classifiers=[
'Development Status :: 5 - Production/Stable',
'Operating System :: POSIX',
'Operating System :: Microsoft :: Windows',
'Programming Language :: C',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: Implementation :: CPython',
'Intended Audience :: Developers',
'License :: OSI Approved :: Mozilla Public License 1.0 (MPL)',
'Topic :: Communications',
'Topic :: System :: Networking',
'Topic :: Software Development :: Libraries',
],
)