"""A simply script to scrape zmq.h for the zeromq version. This is similar to the version.sh script in a zeromq source dir, but it searches for an installed header, rather than in the current dir. """ # Copyright (c) PyZMQ Developers # Distributed under the terms of the Modified BSD License. from __future__ import with_statement import os import sys import re import traceback from warnings import warn try: from configparser import ConfigParser except: from ConfigParser import ConfigParser pjoin = os.path.join MAJOR_PAT='^#define +ZMQ_VERSION_MAJOR +[0-9]+$' MINOR_PAT='^#define +ZMQ_VERSION_MINOR +[0-9]+$' PATCH_PAT='^#define +ZMQ_VERSION_PATCH +[0-9]+$' def include_dirs_from_path(): """Check the exec path for include dirs.""" include_dirs = [] for p in os.environ['PATH'].split(os.path.pathsep): if p.endswith('/'): p = p[:-1] if p.endswith('bin'): include_dirs.append(p[:-3]+'include') return include_dirs def default_include_dirs(): """Default to just /usr/local/include:/usr/include""" return ['/usr/local/include', '/usr/include'] def find_zmq_version(): """check setup.cfg, then /usr/local/include, then /usr/include for zmq.h. Then scrape zmq.h for the version tuple. Returns ------- ((major,minor,patch), "/path/to/zmq.h")""" include_dirs = [] if os.path.exists('setup.cfg'): cfg = ConfigParser() cfg.read('setup.cfg') if 'build_ext' in cfg.sections(): items = cfg.items('build_ext') for name,val in items: if name == 'include_dirs': include_dirs = val.split(os.path.pathsep) if not include_dirs: include_dirs = default_include_dirs() for include in include_dirs: zmq_h = pjoin(include, 'zmq.h') if os.path.isfile(zmq_h): with open(zmq_h) as f: contents = f.read() else: continue line = re.findall(MAJOR_PAT, contents, re.MULTILINE)[0] major = int(re.findall('[0-9]+',line)[0]) line = re.findall(MINOR_PAT, contents, re.MULTILINE)[0] minor = int(re.findall('[0-9]+',line)[0]) line = re.findall(PATCH_PAT, contents, re.MULTILINE)[0] patch = int(re.findall('[0-9]+',line)[0]) return ((major,minor,patch), zmq_h) raise IOError("Couldn't find zmq.h") def ver_str(version): """version tuple as string""" return '.'.join(map(str, version)) def check_zmq_version(min_version): """Check that zmq.h has an appropriate version.""" sv = ver_str(min_version) try: found, zmq_h = find_zmq_version() sf = ver_str(found) if found < min_version: print ("This pyzmq requires zeromq >= %s"%sv) print ("but it appears you are building against %s"%zmq_h) print ("which has zeromq %s"%sf) sys.exit(1) except IOError: msg = '\n'.join(["Couldn't find zmq.h to check for version compatibility.", "If you see 'undeclared identifier' errors, your ZeroMQ is likely too old.", "This pyzmq requires zeromq >= %s"%sv]) warn(msg) except IndexError: msg = '\n'.join(["Couldn't find ZMQ_VERSION macros in zmq.h to check for version compatibility.", "This probably means that you have ZeroMQ <= 2.0.9", "If you see 'undeclared identifier' errors, your ZeroMQ is likely too old.", "This pyzmq requires zeromq >= %s"%sv]) warn(msg) except Exception: traceback.print_exc() msg = '\n'.join(["Unexpected Error checking for zmq version.", "If you see 'undeclared identifier' errors, your ZeroMQ is likely too old.", "This pyzmq requires zeromq >= %s"%sv]) warn(msg) if __name__ == '__main__': v,h = find_zmq_version() print (h) print (ver_str(v))