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

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

parent 596077e9
...@@ -6,10 +6,12 @@ gevent build & installation script ...@@ -6,10 +6,12 @@ gevent build & installation script
If you have more than one libevent installed or it is installed in a If you have more than one libevent installed or it is installed in a
non-standard location, use the options to point to the right dirs: non-standard location, use the options to point to the right dirs:
-Idir add include dir -Idir add include dir
-Ldir add library dir -Ldir add library dir
-1 prefer libevent1 -1 prefer libevent1
-2 prefer libevent2 -2 prefer libevent2
--static link libevent statically (default on win32)
--dynamic link libevent dynamically (default on any platform other than win32)
Also, Also,
...@@ -20,6 +22,10 @@ is a shortcut for ...@@ -20,6 +22,10 @@ is a shortcut for
setup.py build -IDIR -IDIR/include LDIR/.libs 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 sys
import os import os
import re import re
...@@ -34,15 +40,25 @@ except ImportError: ...@@ -34,15 +40,25 @@ except ImportError:
__version__ = re.search("__version__\s*=\s*'(.*)'", open('gevent/__init__.py').read(), re.M).group(1).strip() __version__ = re.search("__version__\s*=\s*'(.*)'", open('gevent/__init__.py').read(), re.M).group(1).strip()
assert __version__ assert __version__
include_dirs = []
library_dirs = [] include_dirs = [] # specified by -I
extra_compile_args = [] library_dirs = [] # specified by -L
LIBEVENT_MAJOR = None # 1 or 2 libevent_source_path = None # specified by --libevent
LIBEVENT_MAJOR = None # 1 or 2, specified by -1 or -2
VERBOSE = '-v' in sys.argv 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': 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): def check_dir(path, must_exist):
if not isdir(path): if not isdir(path):
...@@ -119,8 +135,8 @@ def get_version_from_path(path): ...@@ -119,8 +135,8 @@ def get_version_from_path(path):
def get_version_from_library_path(d): def get_version_from_library_path(d):
if VERBOSE: if VERBOSE:
print 'checking %s for %s' % (d, libevent_fn) print 'checking %s for %s' % (d, libevent_shared_name)
libevent_fpath = join(d, libevent_fn) libevent_fpath = join(d, libevent_shared_name)
if exists(libevent_fpath): if exists(libevent_fpath):
if ctypes: if ctypes:
return get_version_from_ctypes( ctypes.CDLL(libevent_fpath), libevent_fpath ) return get_version_from_ctypes( ctypes.CDLL(libevent_fpath), libevent_fpath )
...@@ -136,7 +152,9 @@ def unique(lst): ...@@ -136,7 +152,9 @@ def unique(lst):
return result 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 i = 1
while i < len(sys.argv): while i < len(sys.argv):
arg = sys.argv[i] arg = sys.argv[i]
...@@ -160,35 +178,42 @@ while i < len(sys.argv): ...@@ -160,35 +178,42 @@ while i < len(sys.argv):
add_include_dir(join(libevent_source_path, 'include'), must_exist=False) add_include_dir(join(libevent_source_path, 'include'), must_exist=False)
add_include_dir(libevent_source_path, must_exist=False) add_include_dir(libevent_source_path, must_exist=False)
add_library_dir(join(libevent_source_path, '.libs'), 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: else:
i = i+1 i = i+1
continue continue
del sys.argv[i] del sys.argv[i]
if not sys.argv[1:] or '-h' in sys.argv or '--help' in sys.argv: def guess_libevent_major():
print __doc__
else:
# try to figure out libevent version from -I and -L options # try to figure out libevent version from -I and -L options
for d in include_dirs: for d in include_dirs:
if LIBEVENT_MAJOR is not None: result = get_version_from_include_path(d)
break if result:
LIBEVENT_MAJOR = get_version_from_include_path(d) return result
for d in library_dirs: for d in library_dirs:
if LIBEVENT_MAJOR is not None: result = get_version_from_library_path(d)
break if result:
LIBEVENT_MAJOR = get_version_from_library_path(d) return result
if LIBEVENT_MAJOR is None and ctypes: if ctypes:
try: try:
libevent = ctypes.cdll.LoadLibrary(libevent_fn) libevent = ctypes.cdll.LoadLibrary(libevent_shared_name)
LIBEVENT_MAJOR = get_version_from_ctypes(libevent, libevent_fn) result = get_version_from_ctypes(libevent, libevent_shared_name)
if result:
return result
except OSError: except OSError:
pass pass
# search system library dirs (unless explicit library directory was provided) # 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 = os.environ.get('LD_LIBRARY_PATH', '').split(':')
library_paths += ['%s/lib' % sys.prefix, library_paths += ['%s/lib' % sys.prefix,
'%s/lib64' % sys.prefix, '%s/lib64' % sys.prefix,
...@@ -198,23 +223,56 @@ else: ...@@ -198,23 +223,56 @@ else:
'/usr/local/lib64/'] '/usr/local/lib64/']
for x in unique(library_paths): for x in unique(library_paths):
LIBEVENT_MAJOR = get_version_from_library_path(x) result = get_version_from_library_path(x)
if LIBEVENT_MAJOR is not None: if result:
add_library_dir(x) 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: if LIBEVENT_MAJOR is None:
print 'Cannot guess the version of libevent installed on your system. DEFAULTING TO 1.' print 'Cannot guess the version of libevent installed on your system. DEFAULTING TO 1.'
LIBEVENT_MAJOR = 1 LIBEVENT_MAJOR = 1
extra_compile_args.append( '-DUSE_LIBEVENT_%s' % LIBEVENT_MAJOR ) 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', gevent_core = Extension(name='gevent.core',
sources=['gevent/core.c'], sources=sources,
include_dirs=include_dirs, include_dirs=include_dirs,
library_dirs=library_dirs, library_dirs=library_dirs,
libraries=['event'], libraries=libraries,
extra_objects=extra_objects,
extra_compile_args=extra_compile_args) 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