~ubuntu-branches/ubuntu/trusty/pyzmq/trusty

« back to all changes in this revision

Viewing changes to .pc/fix_distutils.diff/setup.py

  • Committer: Package Import Robot
  • Author(s): Julian Taylor
  • Date: 2013-02-24 19:23:15 UTC
  • mfrom: (2.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20130224192315-9xkzrza97h674d07
Tags: 2.2.0.1-1
* New upstream release
* relicense debian packaging to LGPL-3
* update watch file to use github directly
  thanks to Bart Martens for the file
* add autopkgtests
* drop obsolete DM-Upload-Allowed
* bump standard to 3.9.4, no changes required

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
 
3
 
 
4
 
#-----------------------------------------------------------------------------
5
 
#  Copyright (c) 2012 Brian Granger, Min Ragan-Kelley
6
 
#
7
 
#  This file is part of pyzmq
8
 
#
9
 
#  Distributed under the terms of the New BSD License.  The full license is in
10
 
#  the file COPYING.BSD, distributed as part of this software.
11
 
#
12
 
#  The `configure` subcommand is copied and adaped from h5py
13
 
#  h5py source used under the New BSD license
14
 
#
15
 
#  h5py: <http://code.google.com/p/h5py/>
16
 
#-----------------------------------------------------------------------------
17
 
 
18
 
#-----------------------------------------------------------------------------
19
 
# Imports
20
 
#-----------------------------------------------------------------------------
21
 
from __future__ import with_statement
22
 
 
23
 
import copy
24
 
import os
25
 
import re
26
 
import shutil
27
 
import sys
28
 
from traceback import print_exc
29
 
 
30
 
from distutils.core import setup, Command
31
 
from distutils.ccompiler import get_default_compiler
32
 
from distutils.extension import Extension
33
 
from distutils.errors import CompileError, LinkError
34
 
from distutils.command.build import build
35
 
from distutils.command.build_ext import build_ext
36
 
from distutils.command.sdist import sdist
37
 
 
38
 
from unittest import TextTestRunner, TestLoader
39
 
from glob import glob
40
 
from os.path import splitext, basename, join as pjoin
41
 
 
42
 
from subprocess import Popen, PIPE
43
 
import logging
44
 
 
45
 
try:
46
 
    from configparser import ConfigParser
47
 
except:
48
 
    from ConfigParser import ConfigParser
49
 
 
50
 
try:
51
 
    import nose
52
 
except ImportError:
53
 
    nose = None
54
 
 
55
 
# local script imports:
56
 
from buildutils import (discover_settings, v_str, localpath, savepickle, loadpickle, detect_zmq,
57
 
                        warn, fatal, copy_and_patch_libzmq)
58
 
 
59
 
#-----------------------------------------------------------------------------
60
 
# Flags
61
 
#-----------------------------------------------------------------------------
62
 
# ignore unused-function and strict-aliasing warnings, of which there
63
 
# will be many from the Cython generated code:
64
 
# note that this is only for gcc-style compilers
65
 
if get_default_compiler() in ('unix', 'mingw32'):
66
 
    ignore_common_warnings=True
67
 
else:
68
 
    ignore_common_warnings=False
69
 
 
70
 
# the minimum zeromq version this will work against:
71
 
min_zmq = (2,1,4)
72
 
 
73
 
# set dylib ext:
74
 
if sys.platform.startswith('win'):
75
 
    lib_ext = '.dll'
76
 
elif sys.platform == 'darwin':
77
 
    lib_ext = '.dylib'
78
 
else:
79
 
    lib_ext = '.so'
80
 
 
81
 
# whether any kind of bdist is happening
82
 
doing_bdist = any(arg.startswith('bdist') for arg in sys.argv[1:])
83
 
 
84
 
#-----------------------------------------------------------------------------
85
 
# Configuration (adapted from h5py: http://h5py.googlecode.com)
86
 
#-----------------------------------------------------------------------------
87
 
 
88
 
 
89
 
ZMQ = discover_settings()
90
 
 
91
 
if ZMQ is not None and not os.path.exists(ZMQ):
92
 
    warn("ZMQ directory \"%s\" does not appear to exist" % ZMQ)
93
 
 
94
 
# bundle_libzmq flag for whether libzmq will be included in pyzmq:
95
 
if sys.platform.startswith('win'):
96
 
    bundle_libzmq = True
97
 
elif ZMQ is not None:
98
 
    bundle_libzmq = doing_bdist
99
 
else:
100
 
    bundle_libzmq = False
101
 
 
102
 
# --- compiler settings -------------------------------------------------
103
 
 
104
 
def settings_from_prefix(zmq=None):
105
 
    """load appropriate library/include settings from ZMQ prefix"""
106
 
    if sys.platform.startswith('win'):
107
 
        settings = {
108
 
            'libraries'     : ['libzmq'],
109
 
            'include_dirs'  : [],
110
 
            'library_dirs'  : [],
111
 
        }
112
 
        if zmq is not None:
113
 
            settings['include_dirs'] += [pjoin(zmq, 'include')]
114
 
            settings['library_dirs'] += [pjoin(zmq, 'lib')]
115
 
    else:
116
 
        settings = {
117
 
           'libraries'      : ['zmq'],
118
 
           'include_dirs'   : [],
119
 
           'library_dirs'   : [],
120
 
        }
121
 
    
122
 
        # add pthread on freebsd
123
 
        if sys.platform.startswith('freebsd'):
124
 
            settings['libraries'].append('pthread')
125
 
    
126
 
        if zmq is not None:
127
 
            settings['include_dirs'] += [pjoin(zmq, 'include')]
128
 
            settings['library_dirs'] += [pjoin(zmq, 'lib')]
129
 
        elif sys.platform == 'darwin' and os.path.isdir('/opt/local/lib'):
130
 
            # allow macports default
131
 
            settings['include_dirs'] += ['/opt/local/include']
132
 
            settings['library_dirs'] += ['/opt/local/lib']
133
 
    
134
 
        if bundle_libzmq:
135
 
            # bdist should link against bundled libzmq
136
 
            settings['library_dirs'] = ['zmq']
137
 
            if sys.platform == 'darwin':
138
 
                pass
139
 
                # unused rpath args for OSX:
140
 
                # settings['extra_link_args'] = ['-Wl,-rpath','-Wl,$ORIGIN/..']
141
 
            else:
142
 
                settings['runtime_library_dirs'] = ['$ORIGIN/..']
143
 
        elif sys.platform != 'darwin':
144
 
            settings['runtime_library_dirs'] = [os.path.abspath(x) for x in settings['library_dirs']]
145
 
 
146
 
    # suppress common warnings
147
 
 
148
 
    extra_flags = []
149
 
    if ignore_common_warnings:
150
 
        for warning in ('unused-function', 'strict-aliasing'):
151
 
            extra_flags.append('-Wno-'+warning)
152
 
 
153
 
    settings['extra_compile_args'] = extra_flags
154
 
    
155
 
    # include internal directories
156
 
    settings['include_dirs'] += [pjoin('zmq', sub) for sub in ('utils','core','devices')]
157
 
 
158
 
    return settings
159
 
 
160
 
COMPILER_SETTINGS = settings_from_prefix(ZMQ)
161
 
 
162
 
 
163
 
#-----------------------------------------------------------------------------
164
 
# Extra commands
165
 
#-----------------------------------------------------------------------------
166
 
 
167
 
class Configure(Command):
168
 
    """Configure command adapted from h5py"""
169
 
 
170
 
    description = "Discover ZMQ version and features"
171
 
 
172
 
    # DON'T REMOVE: distutils demands these be here even if they do nothing.
173
 
    user_options = []
174
 
    boolean_options = []
175
 
    def initialize_options(self):
176
 
        self.zmq = ZMQ
177
 
        self.settings = copy.copy(COMPILER_SETTINGS)
178
 
    
179
 
    def finalize_options(self):
180
 
        pass
181
 
 
182
 
    tempdir = 'detect'
183
 
 
184
 
    def create_tempdir(self):
185
 
        self.erase_tempdir()
186
 
        os.mkdir(self.tempdir)
187
 
        if sys.platform.startswith('win'):
188
 
            # fetch libzmq.dll into local dir
189
 
            local_dll = pjoin(self.tempdir, 'libzmq.dll')
190
 
            if ZMQ is None and not os.path.exists(local_dll):
191
 
                fatal("ZMQ directory must be specified on Windows via setup.cfg or 'python setup.py configure --zmq=/path/to/zeromq2'")
192
 
            
193
 
            try:
194
 
                shutil.copy(pjoin(ZMQ, 'lib', 'libzmq.dll'), local_dll)
195
 
            except Exception:
196
 
                if not os.path.exists(local_dll):
197
 
                    warn("Could not copy libzmq into zmq/, which is usually necessary on Windows."
198
 
                    "Please specify zmq prefix via configure --zmq=/path/to/zmq or copy "
199
 
                    "libzmq into zmq/ manually.")
200
 
            
201
 
 
202
 
    def erase_tempdir(self):
203
 
        try:
204
 
            shutil.rmtree(self.tempdir)
205
 
        except Exception:
206
 
            pass
207
 
 
208
 
    def getcached(self):
209
 
        return loadpickle('configure.pickle')
210
 
 
211
 
    def check_zmq_version(self):
212
 
        zmq = self.zmq
213
 
        if zmq is not None and not os.path.isdir(zmq):
214
 
            fatal("Custom zmq directory \"%s\" does not exist" % zmq)
215
 
 
216
 
        config = self.getcached()
217
 
        if config is None or config['options'] != self.settings:
218
 
            self.run()
219
 
            config = self.config
220
 
        else:
221
 
            self.config = config
222
 
 
223
 
        vers = config['vers']
224
 
        vs = v_str(vers)
225
 
        if vers < min_zmq:
226
 
            fatal("Detected ZMQ version: %s, but depend on zmq >= %s"%(
227
 
                    vs, v_str(min_zmq))
228
 
                    +'\n       Using ZMQ=%s'%(zmq or 'unspecified'))
229
 
        pyzmq_version = extract_version().strip('abcdefghijklmnopqrstuvwxyz')
230
 
 
231
 
        if vs < pyzmq_version:
232
 
            warn("Detected ZMQ version: %s, but pyzmq targets zmq %s."%(
233
 
                    vs, pyzmq_version))
234
 
            warn("libzmq features and fixes introduced after %s will be unavailable."%vs)
235
 
            print('*'*42)
236
 
        elif vs >= '3.0':
237
 
            warn("Detected ZMQ version: %s. pyzmq's support for libzmq-dev is experimental."%vs)
238
 
            print('*'*42)
239
 
 
240
 
        if sys.platform.startswith('win'):
241
 
            # fetch libzmq.dll into local dir
242
 
            local_dll = localpath('zmq','libzmq.dll')
243
 
            if zmq is None and not os.path.exists(local_dll):
244
 
                fatal("ZMQ directory must be specified on Windows via setup.cfg or 'python setup.py configure --zmq=/path/to/zeromq2'")
245
 
            try:
246
 
                shutil.copy(pjoin(zmq, 'lib', 'libzmq.dll'), local_dll)
247
 
            except Exception:
248
 
                if not os.path.exists(local_dll):
249
 
                    warn("Could not copy libzmq into zmq/, which is usually necessary on Windows."
250
 
                    "Please specify zmq prefix via configure --zmq=/path/to/zmq or copy "
251
 
                    "libzmq into zmq/ manually.")
252
 
 
253
 
    def run(self):
254
 
        self.create_tempdir()
255
 
        settings = self.settings
256
 
        if bundle_libzmq and not sys.platform.startswith('win'):
257
 
            # rpath slightly differently here, because libzmq not in .. but ../zmq:
258
 
            settings['library_dirs'] = ['zmq']
259
 
            if sys.platform == 'darwin':
260
 
                pass
261
 
                # unused rpath args for OSX:
262
 
                # settings['extra_link_args'] = ['-Wl,-rpath','-Wl,$ORIGIN/../zmq']
263
 
            else:
264
 
                settings['runtime_library_dirs'] = ['$ORIGIN/../zmq']
265
 
        try:
266
 
            print ("*"*42)
267
 
            print ("Configure: Autodetecting ZMQ settings...")
268
 
            print ("    Custom ZMQ dir:       %s" % (self.zmq,))
269
 
            config = detect_zmq(self.tempdir, **settings)
270
 
        except Exception:
271
 
            # if zmq unspecified on *ix, try again with explicit /usr/local
272
 
            if self.zmq is None and not sys.platform.startswith('win'):
273
 
                self.erase_tempdir()
274
 
                print ("Failed with default libzmq, trying again with /usr/local")
275
 
                self.zmq = '/usr/local'
276
 
                self.settings = settings_from_prefix(self.zmq)
277
 
                
278
 
                self.run()
279
 
                # if we get here the second run succeeded, so we need to update compiler
280
 
                # settings for the extensions with /usr/local prefix
281
 
                for ext in self.distribution.ext_modules:
282
 
                    for key,value in self.settings.iteritems():
283
 
                        setattr(ext, key, value)
284
 
                return
285
 
            
286
 
            etype, evalue, tb = sys.exc_info()
287
 
            # print the error as distutils would if we let it raise:
288
 
            print ("error: %s" % evalue)
289
 
            if etype is CompileError:
290
 
                action = 'compile'
291
 
            elif etype is LinkError:
292
 
                action = 'link'
293
 
            else:
294
 
                action = 'build or run'
295
 
            
296
 
            fatal("""
297
 
    Failed to %s ZMQ test program.  Please check to make sure:
298
 
 
299
 
    * You have a C compiler installed
300
 
    * A development version of Python is installed (including header files)
301
 
    * A development version of ZMQ >= %s is installed (including header files)
302
 
    * If ZMQ is not in a default location, supply the argument --zmq=<path>
303
 
    * If you did recently install ZMQ to a default location, 
304
 
      try rebuilding the ld cache with `sudo ldconfig`
305
 
      or specify zmq's location with `--zmq=/usr/local`
306
 
    """%(action, v_str(min_zmq)))
307
 
            
308
 
        else:
309
 
            savepickle('configure.pickle', config)
310
 
            print ("    ZMQ version detected: %s" % v_str(config['vers']))
311
 
        finally:
312
 
            print ("*"*42)
313
 
            self.erase_tempdir()
314
 
        self.config = config
315
 
 
316
 
class TestCommand(Command):
317
 
    """Custom distutils command to run the test suite."""
318
 
 
319
 
    user_options = [ ]
320
 
 
321
 
    def initialize_options(self):
322
 
        self._dir = os.getcwd()
323
 
 
324
 
    def finalize_options(self):
325
 
        pass
326
 
    
327
 
    def run_nose(self):
328
 
        """Run the test suite with nose."""
329
 
        return nose.core.TestProgram(argv=["", '-vv', pjoin(self._dir, 'zmq', 'tests')])
330
 
    
331
 
    def run_unittest(self):
332
 
        """Finds all the tests modules in zmq/tests/ and runs them."""
333
 
        testfiles = [ ]
334
 
        for t in glob(pjoin(self._dir, 'zmq', 'tests', '*.py')):
335
 
            name = splitext(basename(t))[0]
336
 
            if name.startswith('test_'):
337
 
                testfiles.append('.'.join(
338
 
                    ['zmq.tests', name])
339
 
                )
340
 
        tests = TestLoader().loadTestsFromNames(testfiles)
341
 
        t = TextTestRunner(verbosity = 2)
342
 
        t.run(tests)
343
 
    
344
 
    def run(self):
345
 
        """Run the test suite, with nose, or unittest if nose is unavailable"""
346
 
        # crude check for inplace build:
347
 
        try:
348
 
            import zmq
349
 
        except ImportError:
350
 
            print_exc()
351
 
            fatal('\n       '.join(["Could not import zmq!",
352
 
            "You must build pyzmq with 'python setup.py build_ext --inplace' for 'python setup.py test' to work.",
353
 
            "If you did build pyzmq in-place, then this is a real error."]))
354
 
            sys.exit(1)
355
 
        
356
 
        if nose is None:
357
 
            print ("nose unavailable, falling back on unittest. Skipped tests will appear as ERRORs.")
358
 
            return self.run_unittest()
359
 
        else:
360
 
            return self.run_nose()
361
 
 
362
 
class GitRevisionCommand(Command):
363
 
    """find the current git revision and add it to zmq.core.verion.__revision__"""
364
 
    
365
 
    user_options = [ ]
366
 
    
367
 
    def initialize_options(self):
368
 
        self.version_py = pjoin('zmq','core','version.py')
369
 
    
370
 
    def run(self):
371
 
        try:
372
 
            p = Popen('git log -1'.split(), stdin=PIPE, stdout=PIPE, stderr=PIPE)
373
 
        except IOError:
374
 
            print ("No git found, skipping git revision")
375
 
            return
376
 
        
377
 
        if p.wait():
378
 
            print ("checking git branch failed")
379
 
            print (p.stderr.read())
380
 
            return
381
 
        
382
 
        line = p.stdout.readline().decode().strip()
383
 
        if not line.startswith('commit'):
384
 
            print ("bad commit line: %r"%line)
385
 
            return
386
 
        
387
 
        rev = line.split()[-1]
388
 
        
389
 
        # now that we have the git revision, we can apply it to version.py
390
 
        with open(self.version_py) as f:
391
 
            lines = f.readlines()
392
 
        
393
 
        for i,line in enumerate(lines):
394
 
            if line.startswith('__revision__'):
395
 
                lines[i] = "__revision__ = '%s'\n"%rev
396
 
                break
397
 
        with open(self.version_py, 'w') as f:
398
 
            f.writelines(lines)
399
 
    
400
 
    def finalize_options(self):
401
 
        pass
402
 
 
403
 
class CleanCommand(Command):
404
 
    """Custom distutils command to clean the .so and .pyc files."""
405
 
 
406
 
    user_options = [ ]
407
 
 
408
 
    def initialize_options(self):
409
 
        self._clean_me = []
410
 
        self._clean_trees = []
411
 
        for root, dirs, files in list(os.walk('zmq')):
412
 
            for f in files:
413
 
                if os.path.splitext(f)[-1] in ('.pyc', '.so', '.o', '.pyd'):
414
 
                    self._clean_me.append(pjoin(root, f))
415
 
            for d in dirs:
416
 
                if d == '__pycache__':
417
 
                    self._clean_trees.append(pjoin(root, d))
418
 
        
419
 
        for d in ('build',):
420
 
            if os.path.exists(d):
421
 
                self._clean_trees.append(d)
422
 
 
423
 
        bundled = glob(pjoin('zmq', 'libzmq*'))
424
 
        self._clean_me.extend(bundled)
425
 
        
426
 
 
427
 
 
428
 
    def finalize_options(self):
429
 
        pass
430
 
 
431
 
    def run(self):
432
 
        for clean_me in self._clean_me:
433
 
            try:
434
 
                os.unlink(clean_me)
435
 
            except Exception:
436
 
                pass
437
 
        for clean_tree in self._clean_trees:
438
 
            try:
439
 
                shutil.rmtree(clean_tree)
440
 
            except Exception:
441
 
                pass
442
 
 
443
 
 
444
 
class CheckSDist(sdist):
445
 
    """Custom sdist that ensures Cython has compiled all pyx files to c."""
446
 
 
447
 
    def initialize_options(self):
448
 
        sdist.initialize_options(self)
449
 
        self._pyxfiles = []
450
 
        for root, dirs, files in os.walk('zmq'):
451
 
            for f in files:
452
 
                if f.endswith('.pyx'):
453
 
                    self._pyxfiles.append(pjoin(root, f))
454
 
    def run(self):
455
 
        if 'cython' in cmdclass:
456
 
            self.run_command('cython')
457
 
        else:
458
 
            for pyxfile in self._pyxfiles:
459
 
                cfile = pyxfile[:-3]+'c'
460
 
                msg = "C-source file '%s' not found."%(cfile)+\
461
 
                " Run 'setup.py cython' before sdist."
462
 
                assert os.path.isfile(cfile), msg
463
 
        sdist.run(self)
464
 
 
465
 
class CopyingBuild(build):
466
 
    """subclass of build that copies libzmq if doing bdist."""
467
 
    
468
 
    def run(self):
469
 
        if bundle_libzmq and not sys.platform.startswith('win'):
470
 
            # always rebuild before bdist, because linking may be wrong:
471
 
            self.run_command('clean')
472
 
            copy_and_patch_libzmq(ZMQ, 'libzmq'+lib_ext)
473
 
        build.run(self)
474
 
 
475
 
class CheckingBuildExt(build_ext):
476
 
    """Subclass build_ext to get clearer report if Cython is neccessary."""
477
 
    
478
 
    def check_cython_extensions(self, extensions):
479
 
        for ext in extensions:
480
 
          for src in ext.sources:
481
 
            if not os.path.exists(src):
482
 
                fatal("""Cython-generated file '%s' not found.
483
 
                Cython is required to compile pyzmq from a development branch.
484
 
                Please install Cython or download a release package of pyzmq.
485
 
                """%src)
486
 
    
487
 
    def build_extensions(self):
488
 
        self.check_cython_extensions(self.extensions)
489
 
        self.check_extensions_list(self.extensions)
490
 
        
491
 
        for ext in self.extensions:
492
 
            self.build_extension(ext)
493
 
    
494
 
    def run(self):
495
 
        # check version, to prevent confusing undefined constant errors
496
 
        configure = self.distribution.get_command_obj('configure')
497
 
        configure.check_zmq_version()
498
 
        build_ext.run(self)
499
 
    
500
 
 
501
 
#-----------------------------------------------------------------------------
502
 
# Extensions
503
 
#-----------------------------------------------------------------------------
504
 
 
505
 
cmdclass = {'test':TestCommand, 'clean':CleanCommand, 'revision':GitRevisionCommand,
506
 
            'configure': Configure, 'build': CopyingBuild}
507
 
 
508
 
def pxd(subdir, name):
509
 
    return os.path.abspath(pjoin('zmq', subdir, name+'.pxd'))
510
 
 
511
 
def pyx(subdir, name):
512
 
    return os.path.abspath(pjoin('zmq', subdir, name+'.pyx'))
513
 
 
514
 
def dotc(subdir, name):
515
 
    return os.path.abspath(pjoin('zmq', subdir, name+'.c'))
516
 
 
517
 
libzmq = pxd('core', 'libzmq')
518
 
buffers = pxd('utils', 'buffers')
519
 
message = pxd('core', 'message')
520
 
context = pxd('core', 'context')
521
 
socket = pxd('core', 'socket')
522
 
monqueue = pxd('devices', 'monitoredqueue')
523
 
 
524
 
submodules = dict(
525
 
    core = {'constants': [libzmq],
526
 
            'error':[libzmq],
527
 
            '_poll':[libzmq, socket, context],
528
 
            'stopwatch':[libzmq, pxd('core','stopwatch')],
529
 
            'context':[context, libzmq],
530
 
            'message':[libzmq, buffers, message],
531
 
            'socket':[context, message, socket, libzmq, buffers],
532
 
            'device':[libzmq, socket, context],
533
 
            '_version':[libzmq],
534
 
    },
535
 
    devices = {
536
 
            'monitoredqueue':[buffers, libzmq, monqueue, socket, context],
537
 
    },
538
 
    utils = {
539
 
            'initthreads':[libzmq],
540
 
            'rebuffer':[buffers],
541
 
    },
542
 
)
543
 
 
544
 
try:
545
 
    from Cython.Distutils import build_ext
546
 
    cython=True
547
 
except ImportError:
548
 
    cython=False
549
 
    suffix = '.c'
550
 
    cmdclass['build_ext'] = CheckingBuildExt
551
 
else:
552
 
    
553
 
    suffix = '.pyx'
554
 
    
555
 
    class CythonCommand(build_ext):
556
 
        """Custom distutils command subclassed from Cython.Distutils.build_ext
557
 
        to compile pyx->c, and stop there. All this does is override the 
558
 
        C-compile method build_extension() with a no-op."""
559
 
        def build_extension(self, ext):
560
 
            pass
561
 
    
562
 
    class zbuild_ext(build_ext):
563
 
        def run(self):
564
 
            configure = self.distribution.get_command_obj('configure')
565
 
            configure.check_zmq_version()
566
 
            return build_ext.run(self)
567
 
    
568
 
    cmdclass['cython'] = CythonCommand
569
 
    cmdclass['build_ext'] =  zbuild_ext
570
 
    cmdclass['sdist'] =  CheckSDist
571
 
 
572
 
extensions = []
573
 
for submod, packages in submodules.items():
574
 
    for pkg in sorted(packages):
575
 
        sources = [pjoin('zmq', submod, pkg+suffix)]
576
 
        if suffix == '.pyx':
577
 
            sources.extend(packages[pkg])
578
 
        ext = Extension(
579
 
            'zmq.%s.%s'%(submod, pkg),
580
 
            sources = sources,
581
 
            **COMPILER_SETTINGS
582
 
        )
583
 
        extensions.append(ext)
584
 
 
585
 
#
586
 
package_data = {'zmq':['*.pxd'],
587
 
                'zmq.core':['*.pxd'],
588
 
                'zmq.devices':['*.pxd'],
589
 
                'zmq.utils':['*.pxd', '*.h'],
590
 
}
591
 
 
592
 
if bundle_libzmq:
593
 
    package_data['zmq'].append('libzmq'+lib_ext)
594
 
 
595
 
def extract_version():
596
 
    """extract pyzmq version from core/version.py, so it's not multiply defined"""
597
 
    with open(pjoin('zmq', 'core', 'version.py')) as f:
598
 
        line = f.readline()
599
 
        while not line.startswith("__version__"):
600
 
            line = f.readline()
601
 
    exec(line, globals())
602
 
    if 'bdist_msi' in sys.argv:
603
 
        # msi has strict version requirements, which requires that
604
 
        # we strip any dev suffix
605
 
        return re.match(r'\d+(\.\d+)+', __version__).group()
606
 
    else:
607
 
        return __version__
608
 
 
609
 
def find_packages():
610
 
    """adapted from IPython's setupbase.find_packages()"""
611
 
    packages = []
612
 
    for dir,subdirs,files in os.walk('zmq'):
613
 
        package = dir.replace(os.path.sep, '.')
614
 
        if '__init__.py' not in files:
615
 
            # not a package
616
 
            continue
617
 
        packages.append(package)
618
 
    return packages
619
 
 
620
 
#-----------------------------------------------------------------------------
621
 
# Main setup
622
 
#-----------------------------------------------------------------------------
623
 
 
624
 
long_desc = \
625
 
"""
626
 
PyZMQ is a lightweight and super-fast messaging library built on top of
627
 
the ZeroMQ library (http://www.zeromq.org). 
628
 
"""
629
 
 
630
 
setup(
631
 
    name = "pyzmq",
632
 
    version = extract_version(),
633
 
    packages = find_packages(),
634
 
    ext_modules = extensions,
635
 
    package_data = package_data,
636
 
    author = "Brian E. Granger, Min Ragan-Kelley",
637
 
    author_email = "zeromq-dev@lists.zeromq.org",
638
 
    url = 'http://github.com/zeromq/pyzmq',
639
 
    download_url = 'http://github.com/zeromq/pyzmq/downloads',
640
 
    description = "Python bindings for 0MQ.",
641
 
    long_description = long_desc, 
642
 
    license = "LGPL+BSD",
643
 
    cmdclass = cmdclass,
644
 
    classifiers = [
645
 
        'Development Status :: 5 - Production/Stable',
646
 
        'Intended Audience :: Developers',
647
 
        'Intended Audience :: Financial and Insurance Industry',
648
 
        'Intended Audience :: Science/Research',
649
 
        'Intended Audience :: System Administrators',
650
 
        'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
651
 
        'License :: OSI Approved :: BSD License',
652
 
        'Operating System :: MacOS :: MacOS X',
653
 
        'Operating System :: Microsoft :: Windows',
654
 
        'Operating System :: POSIX',
655
 
        'Topic :: System :: Networking',
656
 
        'Programming Language :: Python :: 2',
657
 
        'Programming Language :: Python :: 2.6',
658
 
        'Programming Language :: Python :: 2.7',
659
 
        'Programming Language :: Python :: 3',
660
 
        'Programming Language :: Python :: 3.0',
661
 
        'Programming Language :: Python :: 3.1',
662
 
        'Programming Language :: Python :: 3.2',
663
 
    ]
664
 
)
665