diff --git a/buildutils/build.py b/buildutils/build.py index f355d1c..7b54c7e 100644 --- a/buildutils/build.py +++ b/buildutils/build.py @@ -28,7 +28,7 @@ def build_libcapnp(bundle_dir, build_dir): if shutil.which('ninja'): build_type = ['-G', 'Ninja'] - # Determine python shell architecture + # Determine python shell architecture for Windows python_arch = 8 * struct.calcsize("P") build_arch = [] build_flags = [] diff --git a/buildutils/bundle.py b/buildutils/bundle.py index c9e83df..acc39ed 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -13,19 +13,10 @@ import os import shutil -import stat -import sys import tarfile -from subprocess import Popen, PIPE -try: - # py2 - from urllib2 import urlopen -except ImportError: - # py3 - from urllib.request import urlopen - -from .msg import fatal, info, warn +from urllib.request import urlopen +from .msg import info pjoin = os.path.join @@ -94,79 +85,3 @@ def fetch_libcapnp(savedir, url=None): cpp_dir = os.path.join(with_version, 'c++') shutil.move(cpp_dir, dest) - -def stage_platform_hpp(capnproot): - """stage platform.hpp into libcapnp sources - - Tries ./configure first (except on Windows), - then falls back on included platform.hpp previously generated. - """ - - platform_hpp = pjoin(capnproot, 'src', 'platform.hpp') - if os.path.exists(platform_hpp): - info("already have platform.hpp") - return - if os.name == 'nt': - # stage msvc platform header - platform_dir = pjoin(capnproot, 'builds', 'msvc') - else: - info("attempting ./configure to generate platform.hpp") - - p = Popen('./configure', cwd=capnproot, shell=True, - stdout=PIPE, stderr=PIPE, - ) - _, e = p.communicate() - if p.returncode: - warn("failed to configure libcapnp:\n%s" % e) - if sys.platform == 'darwin': - 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: - return - - info("staging platform.hpp from: %s" % platform_dir) - shutil.copy(pjoin(platform_dir, 'platform.hpp'), platform_hpp) - - -def copy_and_patch_libcapnp(capnp, libcapnp): - """copy libcapnp into source dir, and patch it if necessary. - - This command is necessary prior to running a bdist on Linux or OS X. - """ - if sys.platform.startswith('win'): - return - # copy libcapnp into capnp for bdist - local = localpath('capnp', libcapnp) - if not capnp and not os.path.exists(local): - fatal("Please specify capnp prefix via `setup.py configure --capnp=/path/to/capnp` " - "or copy libcapnp into capnp/ manually prior to running bdist.") - try: - # resolve real file through symlinks - lib = os.path.realpath(pjoin(capnp, 'lib', libcapnp)) - print ("copying %s -> %s" % (lib, local)) - shutil.copy(lib, local) - except Exception: - if not os.path.exists(local): - fatal("Could not copy libcapnp into capnp/, which is necessary for bdist. " - "Please specify capnp prefix via `setup.py configure --capnp=/path/to/capnp` " - "or copy libcapnp into capnp/ manually.") - - if sys.platform == 'darwin': - # chmod u+w on the lib, - # which can be user-read-only for some reason - mode = os.stat(local).st_mode - os.chmod(local, mode | stat.S_IWUSR) - # patch install_name on darwin, instead of using rpath - cmd = ['install_name_tool', '-id', '@loader_path/../%s' % libcapnp, local] - try: - p = Popen(cmd, stdout=PIPE, stderr=PIPE) - except OSError: - fatal("install_name_tool not found, cannot patch libcapnp for bundling.") - _, err = p.communicate() - if p.returncode: - fatal("Could not patch bundled libcapnp install_name: %s" % err, p.returncode) diff --git a/buildutils/config.py b/buildutils/config.py index 6701259..277b776 100644 --- a/buildutils/config.py +++ b/buildutils/config.py @@ -11,147 +11,10 @@ # the file COPYING.BSD, distributed as part of this software. # -import sys -import os -import json - -from .msg import debug, warn - -try: - from configparser import ConfigParser -except Exception: - from ConfigParser import ConfigParser - -pjoin = os.path.join - # # Utility functions (adapted from h5py: http://h5py.googlecode.com) # - -def load_config(name, base='conf'): - """Load config dict from JSON""" - fname = pjoin(base, name + '.json') - if not os.path.exists(fname): - return {} - try: - with open(fname) as f: - cfg = json.load(f) - except Exception as e: - warn("Couldn't load %s: %s" % (fname, e)) - cfg = {} - return cfg - - -def save_config(name, data, base='conf'): - """Save config dict to JSON""" - if not os.path.exists(base): - os.mkdir(base) - fname = pjoin(base, name + '.json') - with open(fname, 'w') as f: - json.dump(data, f, indent=2) - - def v_str(v_tuple): """turn (2,0,1) into '2.0.1'.""" return ".".join(str(x) for x in v_tuple) - -def get_eargs(): - """ Look for options in environment vars """ - - settings = {} - - 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 """ - - if not os.path.exists('setup.cfg'): - return {} - cfg = ConfigParser() - cfg.read('setup.cfg') - 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 config_from_prefix(prefix): - """Get config from zmq prefix""" - settings = {} - 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_prefix'] = prefix - settings['libzmq_extension'] = False - settings['no_libzmq_extension'] = True - 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 - if isinstance(into, list): - return into + d - return d - -def discover_settings(conf_base=None): - """ Discover custom settings for ZMQ path""" - 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 - - if conf_base: - # lowest priority - merge(settings, load_config('config', conf_base)) - merge(settings, get_cfg_args()) - merge(settings, get_eargs()) - - return settings diff --git a/buildutils/constants.py b/buildutils/constants.py deleted file mode 100644 index fa39722..0000000 --- a/buildutils/constants.py +++ /dev/null @@ -1,84 +0,0 @@ -""" -script for generating files that involve repetitive updates for zmq constants. - -Run this after updating utils/constant_names - -Currently generates the following files from templates: - -- constant_enums.pxi -- constants.pxi -- zmq_constants.h - -""" - -# Copyright (C) PyZMQ Developers -# Distributed under the terms of the Modified BSD License. - -import os -import sys - -from . import info -pjoin = os.path.join - -root = os.path.abspath(pjoin(os.path.dirname(__file__), os.path.pardir)) - -sys.path.insert(0, pjoin(root, 'zmq', 'utils')) -from constant_names import all_names, no_prefix # noqa: E402 - -ifndef_t = """#ifndef {0} - #define {0} (_PYZMQ_UNDEFINED) -#endif -""" - -def cython_enums(): - """generate `enum: ZMQ_CONST` block for constant_enums.pxi""" - lines = [] - for name in all_names: - if no_prefix(name): - lines.append('enum: ZMQ_{0} "{0}"'.format(name)) - else: - lines.append('enum: ZMQ_{0}'.format(name)) - - return dict(ZMQ_ENUMS='\n '.join(lines)) - -def ifndefs(): - """generate `#ifndef ZMQ_CONST` block for zmq_constants.h""" - lines = ['#define _PYZMQ_UNDEFINED (-9999)'] - for name in all_names: - if not no_prefix(name): - name = 'ZMQ_%s' % name - lines.append(ifndef_t.format(name)) - return dict(ZMQ_IFNDEFS='\n'.join(lines)) - -def constants_pyx(): - """generate CONST = ZMQ_CONST and __all__ for constants.pxi""" - all_lines = [] - assign_lines = [] - for name in all_names: - if name == "NULL": - # avoid conflict with NULL in Cython - assign_lines.append("globals()['NULL'] = ZMQ_NULL") - else: - assign_lines.append('{0} = ZMQ_{0}'.format(name)) - all_lines.append(' "{0}",'.format(name)) - return dict(ASSIGNMENTS='\n'.join(assign_lines), ALL='\n'.join(all_lines)) - -def generate_file(fname, ns_func, dest_dir="."): - """generate a constants file from its template""" - with open(pjoin(root, 'buildutils', 'templates', '%s' % fname), 'r') as f: - tpl = f.read() - out = tpl.format(**ns_func()) - dest = pjoin(dest_dir, fname) - info("generating %s from template" % dest) - with open(dest, 'w') as f: - f.write(out) - -def render_constants(): - """render generated constant files from templates""" - generate_file("constant_enums.pxi", cython_enums, pjoin(root, 'zmq', 'backend', 'cython')) - generate_file("constants.pxi", constants_pyx, pjoin(root, 'zmq', 'backend', 'cython')) - generate_file("zmq_constants.h", ifndefs, pjoin(root, 'zmq', 'utils')) - - -if __name__ == '__main__': - render_constants() diff --git a/buildutils/detect.py b/buildutils/detect.py index b9771f2..7d71345 100644 --- a/buildutils/detect.py +++ b/buildutils/detect.py @@ -21,7 +21,6 @@ import logging import platform from distutils import ccompiler from distutils.ccompiler import get_default_compiler -from subprocess import Popen, PIPE import tempfile from .misc import get_compiler, get_output_error @@ -68,26 +67,6 @@ def test_compilation(cfile, compiler=None, **compiler_attrs): cc.link_executable(objs, efile, extra_preargs=lpreargs, extra_postargs=extra_link_args) return efile -def compile_and_run(basedir, src, compiler=None, **compiler_attrs): - """Compile and run""" - if not os.path.exists(basedir): - os.makedirs(basedir) - cfile = pjoin(basedir, os.path.basename(src)) - shutil.copy(src, cfile) - try: - cc = get_compiler(compiler, **compiler_attrs) - efile = test_compilation(cfile, compiler=cc) - patch_lib_paths(efile, cc.library_dirs) - 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_version(basedir, compiler=None, **compiler_attrs): """Compile, link & execute a test program, in empty directory `basedir`. diff --git a/buildutils/setup_travis.sh b/buildutils/setup_travis.sh deleted file mode 100755 index 7a89a3e..0000000 --- a/buildutils/setup_travis.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -set -exo pipefail - -CAPNP_VERSION=0.5.2 - -sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test -sudo apt-get -qq update -sudo apt-get -qq install g++-4.8 libstdc++-4.8-dev -sudo update-alternatives --quiet --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8 --slave /usr/bin/gcov gcov /usr/bin/gcov-4.8 -sudo update-alternatives --quiet --set gcc /usr/bin/gcc-4.8 - -if ! [ -z "${BUILD_CAPNP}" ]; then - wget https://capnproto.org/capnproto-c++-${CAPNP_VERSION}.tar.gz && tar xzvf capnproto-c++-${CAPNP_VERSION}.tar.gz && cd capnproto-c++-${CAPNP_VERSION} && ./configure && make -j6 && sudo make install && sudo ldconfig && cd .. -fi