Permalink
Browse files

Merge pull request #312 from minrk/rebuild

progress towards more sensible build config

- [x] shouldn't suppress warnings where it won't work
- [x] manual overrides for a few things
- [x] allow skipping libzmq version check
- [x] cross compilation should work (#227)
- [x] it shouldn't clean in the middle anymore, messing up bdists

closes #227
closes #300
  • Loading branch information...
2 parents 8e7be77 + 4893d84 commit 2c84e6390d093a439ab7b86f24f8347afc6bc2b8 @minrk minrk committed Feb 3, 2013
View
@@ -114,6 +114,8 @@ def stage_platform_hpp(zmqroot):
platform_dir = pjoin(HERE, 'include_darwin')
elif sys.platform.startswith('freebsd'):
platform_dir = pjoin(HERE, 'include_freebsd')
+ elif sys.platform.startswith('linux-armv'):
+ platform_dir = pjoin(HERE, 'include_linux-armv')
else:
platform_dir = pjoin(HERE, 'include_linux')
else:
@@ -184,7 +186,7 @@ def copy_and_patch_libzmq(ZMQ, libzmq):
return
# copy libzmq into zmq for bdist
local = localpath('zmq',libzmq)
- if ZMQ is None and not os.path.exists(local):
+ if not ZMQ and not os.path.exists(local):
fatal("Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` "
"or copy libzmq into zmq/ manually prior to running bdist.")
try:
@@ -0,0 +1,8 @@
+#include <stdio.h>
+#include "sys/un.h"
+
+int main(int argc, char **argv) {
+ struct sockaddr_un *dummy;
+ printf("%lu\n", sizeof(dummy->sun_path) - 1);
+ return 0;
+}
View
@@ -30,15 +30,15 @@
def load_config(name):
"""Load config dict from JSON"""
- fname = pjoin('conf', name+'.json')
+ fname = pjoin('conf', name + '.json')
if not os.path.exists(fname):
- return None
+ return {}
try:
with open(fname) as f:
cfg = json.load(f)
except Exception as e:
warn("Couldn't load %s: %s" % (fname, e))
- cfg = None
+ cfg = {}
return cfg
@@ -60,52 +60,101 @@ def get_eargs():
settings = {}
- zmq = os.environ.get("ZMQ_DIR", '')
- if zmq != '':
- debug("Found environ var ZMQ_DIR=%s" % zmq)
- settings['zmq'] = zmq
+ zmq = os.environ.get("ZMQ_PREFIX", None)
+ if zmq is not None:
+ debug("Found environ var ZMQ_PREFIX=%s" % zmq)
+ settings['zmq_prefix'] = zmq
return settings
+def cfg2dict(cfg):
+ """turn a ConfigParser into a nested dict
+
+ because ConfigParser objects are dumb.
+ """
+ d = {}
+ for section in cfg.sections():
+ d[section] = dict(cfg.items(section))
+ return d
+
def get_cfg_args():
""" Look for options in setup.cfg """
- settings = {}
- zmq = ''
if not os.path.exists('setup.cfg'):
- return settings
+ return {}
cfg = ConfigParser()
cfg.read('setup.cfg')
- if 'build_ext' in cfg.sections() and \
- cfg.has_option('build_ext', 'include_dirs'):
- includes = cfg.get('build_ext', 'include_dirs')
- include = includes.split(os.pathsep)[0]
- if include.endswith('include') and os.path.isdir(include):
- zmq = include[:-8]
- if zmq != '':
- debug("Found ZMQ=%s in setup.cfg" % zmq)
- settings['zmq'] = zmq
-
- return settings
+ cfg = cfg2dict(cfg)
+
+ g = cfg.setdefault('global', {})
+ # boolean keys:
+ for key in ['libzmq_extension',
+ 'bundle_libzmq_dylib',
+ 'no_libzmq_extension',
+ 'have_sys_un_h',
+ 'skip_check_zmq',
+ ]:
+ if key in g:
+ g[key] = eval(g[key])
+
+ # globals go to top level
+ cfg.update(cfg.pop('global'))
+ return cfg
def get_cargs():
""" Look for global options in the command line """
settings = load_config('buildconf')
- if settings is None: settings = {}
for arg in sys.argv[:]:
if arg.find('--zmq=') == 0:
- zmq = arg.split('=')[-1]
- if zmq.lower() in ('default', 'auto', ''):
- settings.pop('zmq', None)
+ prefix = arg.split('=', 1)[-1]
+ if prefix.lower() in ('default', 'auto', ''):
+ settings['zmq_prefix'] = ''
+ settings['libzmq_extension'] = False
+ settings['no_libzmq_extension'] = False
+ elif prefix.lower() in ('bundled', 'extension'):
+ settings['zmq_prefix'] = ''
+ settings['libzmq_extension'] = True
+ settings['no_libzmq_extension'] = False
else:
- settings['zmq'] = zmq
+ settings['zmq_prefix'] = prefix
+ settings['libzmq_extension'] = False
+ settings['no_libzmq_extension'] = True
sys.argv.remove(arg)
save_config('buildconf', settings)
return settings
+def merge(into, d):
+ """merge two containers
+
+ into is updated, d has priority
+ """
+ if isinstance(into, dict):
+ for key in d.keys():
+ if key not in into:
+ into[key] = d[key]
+ else:
+ into[key] = merge(into[key], d[key])
+ return into
+ elif isinstance(into, list):
+ return into + d
+ else:
+ return d
+
def discover_settings():
""" Discover custom settings for ZMQ path"""
- settings = get_cfg_args() # lowest priority
- settings.update(get_eargs())
- settings.update(get_cargs()) # highest priority
- return settings.get('zmq')
+ settings = {
+ 'zmq_prefix': '',
+ 'libzmq_extension': False,
+ 'no_libzmq_extension': False,
+ 'skip_check_zmq': False,
+ 'build_ext': {},
+ 'bdist_egg': {},
+ }
+ if sys.platform.startswith('win'):
+ settings['have_sys_un_h'] = False
+
+ merge(settings, get_cfg_args()) # lowest priority
+ merge(settings, get_eargs())
+ merge(settings, get_cargs()) # highest priority
+
+ return settings
View
@@ -28,6 +28,58 @@
# Utility functions (adapted from h5py: http://h5py.googlecode.com)
#-----------------------------------------------------------------------------
+def test_compilation(cfile, compiler=None, **compiler_attrs):
+ """Test simple compilation with given settings"""
+ if compiler is None or isinstance(compiler, str):
+ cc = ccompiler.new_compiler(compiler=compiler)
+ customize_compiler(cc)
+ if cc.compiler_type == 'mingw32':
+ customize_mingw(cc)
+ else:
+ cc = compiler
+
+ for name, val in compiler_attrs.items():
+ setattr(cc, name, val)
+
+ efile, ext = os.path.splitext(cfile)
+
+ cpreargs = lpreargs = None
+ if sys.platform == 'darwin':
+ # use appropriate arch for compiler
+ if platform.architecture()[0]=='32bit':
+ if platform.processor() == 'powerpc':
+ cpu = 'ppc'
+ else:
+ cpu = 'i386'
+ cpreargs = ['-arch', cpu]
+ lpreargs = ['-arch', cpu, '-undefined', 'dynamic_lookup']
+ else:
+ # allow for missing UB arch, since it will still work:
+ lpreargs = ['-undefined', 'dynamic_lookup']
+ extra = compiler_attrs.get('extra_compile_args', None)
+
+ objs = cc.compile([cfile],extra_preargs=cpreargs, extra_postargs=extra)
+ cc.link_executable(objs, efile, extra_preargs=lpreargs)
+ return efile
+
+def compile_and_run(basedir, src, compiler=None, **compiler_attrs):
+ if not os.path.exists(basedir):
+ os.makedirs(basedir)
+ cfile = pjoin(basedir, os.path.basename(src))
+ shutil.copy(src, cfile)
+ try:
+ efile = test_compilation(cfile, compiler=compiler, **compiler_attrs)
+ result = Popen(efile, stdout=PIPE, stderr=PIPE)
+ so, se = result.communicate()
+ # for py3k:
+ so = so.decode()
+ se = se.decode()
+ finally:
+ shutil.rmtree(basedir)
+
+ return result.returncode, so, se
+
+
def detect_zmq(basedir, compiler=None, **compiler_attrs):
"""Compile, link & execute a test program, in empty directory `basedir`.
@@ -55,39 +107,11 @@ def detect_zmq(basedir, compiler=None, **compiler_attrs):
`library_dirs`, `libs`, etc.
"""
- if compiler is None or isinstance(compiler, str):
- cc = ccompiler.new_compiler(compiler=compiler)
- customize_compiler(cc)
- if cc.compiler_type == 'mingw32':
- customize_mingw(cc)
- else:
- cc = compiler
-
- for name, val in compiler_attrs.items():
- setattr(cc, name, val)
-
cfile = pjoin(basedir, 'vers.c')
- efile = pjoin(basedir, 'vers')
-
shutil.copy(pjoin(os.path.dirname(__file__), 'vers.c'), cfile)
-
- cpreargs = lpreargs = None
- if sys.platform == 'darwin':
- # use appropriate arch for compiler
- if platform.architecture()[0]=='32bit':
- if platform.processor() == 'powerpc':
- cpu = 'ppc'
- else:
- cpu = 'i386'
- cpreargs = ['-arch', cpu]
- lpreargs = ['-arch', cpu, '-undefined', 'dynamic_lookup']
- else:
- # allow for missing UB arch, since it will still work:
- lpreargs = ['-undefined', 'dynamic_lookup']
-
- objs = cc.compile([cfile],extra_preargs=cpreargs)
- cc.link_executable(objs, efile, extra_preargs=lpreargs)
-
+
+ efile = test_compilation(cfile, compiler=compiler, **compiler_attrs)
+
result = Popen(efile, stdout=PIPE, stderr=PIPE)
so, se = result.communicate()
# for py3k:
View
@@ -0,0 +1,5 @@
+// empty file, just to test compilation
+
+int main(int argc, char **argv){
+ return 0;
+}
Oops, something went wrong.

0 comments on commit 2c84e63

Please sign in to comment.