Commit 59c061c2 authored by Denis Bilenko's avatar Denis Bilenko

setup.py: add support for compiling libevent statically on windows

parent 596077e9
......@@ -10,6 +10,8 @@ non-standard location, use the options to point to the right dirs:
-Ldir add library dir
-1 prefer libevent1
-2 prefer libevent2
--static link libevent statically (default on win32)
--dynamic link libevent dynamically (default on any platform other than win32)
Also,
......@@ -20,6 +22,10 @@ is a shortcut for
setup.py build -IDIR -IDIR/include LDIR/.libs
"""
# XXX Options --static and --dynamic aren't tested for values other than theirs
# defaults (that is, --static on win32, --dynamic on everything else)
import sys
import os
import re
......@@ -34,15 +40,25 @@ except ImportError:
__version__ = re.search("__version__\s*=\s*'(.*)'", open('gevent/__init__.py').read(), re.M).group(1).strip()
assert __version__
include_dirs = []
library_dirs = []
extra_compile_args = []
LIBEVENT_MAJOR = None # 1 or 2
include_dirs = [] # specified by -I
library_dirs = [] # specified by -L
libevent_source_path = None # specified by --libevent
LIBEVENT_MAJOR = None # 1 or 2, specified by -1 or -2
VERBOSE = '-v' in sys.argv
static = sys.platform == 'win32' # set to True with --static; set to False with --dynamic
extra_compile_args = []
sources=['gevent/core.c']
libraries = []
extra_objects = []
libevent_fn = 'libevent.so'
libevent_shared_name = 'libevent.so'
if sys.platform == 'darwin':
libevent_fn = 'libevent.dylib'
libevent_shared_name = 'libevent.dylib'
elif sys.platform == 'win32':
libevent_shared_name = 'libevent.dll'
def check_dir(path, must_exist):
if not isdir(path):
......@@ -119,8 +135,8 @@ def get_version_from_path(path):
def get_version_from_library_path(d):
if VERBOSE:
print 'checking %s for %s' % (d, libevent_fn)
libevent_fpath = join(d, libevent_fn)
print 'checking %s for %s' % (d, libevent_shared_name)
libevent_fpath = join(d, libevent_shared_name)
if exists(libevent_fpath):
if ctypes:
return get_version_from_ctypes( ctypes.CDLL(libevent_fpath), libevent_fpath )
......@@ -136,7 +152,9 @@ def unique(lst):
return result
# parse options: -I name / -Iname / -L name / -Lname / -1 / -2
# parse options: -I NAME / -INAME / -L NAME / -LNAME / -1 / -2 / --libevent DIR / --static / --dynamic
# we're cutting out options from sys.path instead of using optparse
# so that these option can co-exists with distutils' options
i = 1
while i < len(sys.argv):
arg = sys.argv[i]
......@@ -160,35 +178,42 @@ while i < len(sys.argv):
add_include_dir(join(libevent_source_path, 'include'), must_exist=False)
add_include_dir(libevent_source_path, must_exist=False)
add_library_dir(join(libevent_source_path, '.libs'), must_exist=False)
if sys.platform == 'win32':
add_include_dir(join(libevent_source_path, 'compat'), must_exist=False)
add_include_dir(join(libevent_source_path, 'WIN32-Code'), must_exist=False)
elif arg == '--static':
static = True
elif arg == '--dynamic':
static = False
else:
i = i+1
continue
del sys.argv[i]
if not sys.argv[1:] or '-h' in sys.argv or '--help' in sys.argv:
print __doc__
else:
def guess_libevent_major():
# try to figure out libevent version from -I and -L options
for d in include_dirs:
if LIBEVENT_MAJOR is not None:
break
LIBEVENT_MAJOR = get_version_from_include_path(d)
result = get_version_from_include_path(d)
if result:
return result
for d in library_dirs:
if LIBEVENT_MAJOR is not None:
break
LIBEVENT_MAJOR = get_version_from_library_path(d)
result = get_version_from_library_path(d)
if result:
return result
if LIBEVENT_MAJOR is None and ctypes:
if ctypes:
try:
libevent = ctypes.cdll.LoadLibrary(libevent_fn)
LIBEVENT_MAJOR = get_version_from_ctypes(libevent, libevent_fn)
libevent = ctypes.cdll.LoadLibrary(libevent_shared_name)
result = get_version_from_ctypes(libevent, libevent_shared_name)
if result:
return result
except OSError:
pass
# search system library dirs (unless explicit library directory was provided)
if LIBEVENT_MAJOR is None and not library_dirs:
if not library_dirs:
library_paths = os.environ.get('LD_LIBRARY_PATH', '').split(':')
library_paths += ['%s/lib' % sys.prefix,
'%s/lib64' % sys.prefix,
......@@ -198,23 +223,56 @@ else:
'/usr/local/lib64/']
for x in unique(library_paths):
LIBEVENT_MAJOR = get_version_from_library_path(x)
if LIBEVENT_MAJOR is not None:
result = get_version_from_library_path(x)
if result:
add_library_dir(x)
break
return result
if not sys.argv[1:] or '-h' in sys.argv or '--help' in sys.argv:
print __doc__
else:
LIBEVENT_MAJOR = guess_libevent_major()
if LIBEVENT_MAJOR is None:
print 'Cannot guess the version of libevent installed on your system. DEFAULTING TO 1.'
LIBEVENT_MAJOR = 1
extra_compile_args.append( '-DUSE_LIBEVENT_%s' % LIBEVENT_MAJOR )
if static:
if not libevent_source_path:
sys.exit('Please provide path to libevent source with --libevent DIR')
extra_compile_args += ['-DHAVE_CONFIG_H']
libevent_sources = ['event.c',
'buffer.c',
'evbuffer.c',
'event_tagging.c',
'evutil.c',
'log.c',
'signal.c',
'evdns.c',
'http.c',
'strlcpy.c']
if sys.platform == 'win32':
libraries = ['wsock32', 'advapi32']
include_dirs.extend([ join(libevent_source_path, 'WIN32-Code'),
join(libevent_source_path, 'compat') ])
libevent_sources.append('WIN32-Code/win32.c')
extra_compile_args += ['-DWIN32']
else:
libevent_sources += ['select.c']
print 'XXX --static is not well supported on non-win32 platforms: only select is enabled'
for filename in libevent_sources:
sources.append( join(libevent_source_path, filename) )
else:
libraries = ['event']
gevent_core = Extension(name = 'gevent.core',
sources=['gevent/core.c'],
gevent_core = Extension(name='gevent.core',
sources=sources,
include_dirs=include_dirs,
library_dirs=library_dirs,
libraries=['event'],
libraries=libraries,
extra_objects=extra_objects,
extra_compile_args=extra_compile_args)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment