Updating to capnproto v0.8.0
- Includes some test stabilization - Fixes manylinux2010 build issues (linker flag order due to old gcc) - More rigorous python setup.py clean - Requires capnproto v0.8.0 or greater - Including system libcapnp include path for import (e.g. import stream_capnp) - Bundle libcapnp .capnp files when not using system libcapnp - Removing more distutils usage. Now using pkg-config to determine the system version of libcapnp (mainly for Linux, but should work on macOS with brew) - Removed dead code Resolves issues #215 #216 #217 Lots of fixes for Issue #218 (all sorts of retry methods needed for GitHub Actions)
This commit is contained in:
@@ -5,9 +5,5 @@ Largely adapted from h5py
|
||||
# flake8: noqa F401 F403
|
||||
|
||||
from .msg import *
|
||||
from .config import *
|
||||
from .detect import *
|
||||
from .bundle import *
|
||||
from .misc import *
|
||||
from .patch import *
|
||||
from .build import *
|
||||
|
||||
@@ -22,7 +22,9 @@ def build_libcapnp(bundle_dir, build_dir):
|
||||
os.mkdir(tmp_dir)
|
||||
|
||||
cxxflags = os.environ.get('CXXFLAGS', None)
|
||||
ldflags = os.environ.get('LDFLAGS', None)
|
||||
os.environ['CXXFLAGS'] = (cxxflags or '') + ' -O2 -DNDEBUG'
|
||||
os.environ['LDFLAGS'] = (ldflags or '')
|
||||
|
||||
# Enable ninja for compilation if available
|
||||
build_type = []
|
||||
@@ -77,5 +79,9 @@ def build_libcapnp(bundle_dir, build_dir):
|
||||
del os.environ['CXXFLAGS']
|
||||
else:
|
||||
os.environ['CXXFLAGS'] = cxxflags
|
||||
if ldflags is None:
|
||||
del os.environ['LDFLAGS']
|
||||
else:
|
||||
os.environ['LDFLAGS'] = ldflags
|
||||
if returncode != 0:
|
||||
raise RuntimeError('capnproto compilation failed: {}'.format(returncode))
|
||||
|
||||
@@ -27,7 +27,7 @@ pjoin = os.path.join
|
||||
#
|
||||
|
||||
|
||||
bundled_version = (0, 7, 0)
|
||||
bundled_version = (0, 8, 0)
|
||||
libcapnp_name = "capnproto-c++-%i.%i.%i.tar.gz" % (bundled_version)
|
||||
libcapnp_url = "https://capnproto.org/" + libcapnp_name
|
||||
|
||||
@@ -92,14 +92,3 @@ def fetch_libcapnp(savedir, url=None):
|
||||
else:
|
||||
cpp_dir = os.path.join(with_version, 'c++')
|
||||
shutil.move(cpp_dir, dest)
|
||||
|
||||
# XXX (HaaTa): There's a bug in capnproto-0.7.0 on CentOS 6 (or any glibc older than 2.16)
|
||||
# This patches the issue
|
||||
with fileinput.FileInput(os.path.join(dest, 'src', 'kj', 'table.c++'), inplace=True, backup='.bak') as f:
|
||||
for line in f:
|
||||
print(
|
||||
line.replace(
|
||||
'__APPLE__ || __BIONIC__', '__APPLE__ || __BIONIC__ || (defined(__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ < 16))'
|
||||
),
|
||||
end=''
|
||||
)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
"""Config functions"""
|
||||
#
|
||||
# Copyright (C) PyZMQ Developers
|
||||
#
|
||||
# This file is part of pyzmq, copied and adapted from h5py.
|
||||
# h5py source used under the New BSD license
|
||||
#
|
||||
# h5py: <http://code.google.com/p/h5py/>
|
||||
#
|
||||
# Distributed under the terms of the New BSD License. The full license is in
|
||||
# the file COPYING.BSD, distributed as part of this software.
|
||||
#
|
||||
|
||||
#
|
||||
# Utility functions (adapted from h5py: http://h5py.googlecode.com)
|
||||
#
|
||||
|
||||
|
||||
def v_str(v_tuple):
|
||||
"""turn (2,0,1) into '2.0.1'."""
|
||||
return ".".join(str(x) for x in v_tuple)
|
||||
@@ -1,154 +0,0 @@
|
||||
"""Detect zmq version"""
|
||||
#
|
||||
# Copyright (C) PyZMQ Developers
|
||||
#
|
||||
# This file is part of pyzmq, copied and adapted from h5py.
|
||||
# h5py source used under the New BSD license
|
||||
#
|
||||
# h5py: <http://code.google.com/p/h5py/>
|
||||
#
|
||||
# Distributed under the terms of the New BSD License. The full license is in
|
||||
# the file COPYING.BSD, distributed as part of this software.
|
||||
#
|
||||
#
|
||||
# Adapted for use in pycapnp from pyzmq. See https://github.com/zeromq/pyzmq
|
||||
# for original project.
|
||||
|
||||
import shutil
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
import platform
|
||||
from distutils import ccompiler
|
||||
from distutils.ccompiler import get_default_compiler
|
||||
import tempfile
|
||||
|
||||
from .misc import get_compiler, get_output_error
|
||||
from .patch import patch_lib_paths
|
||||
|
||||
pjoin = os.path.join
|
||||
|
||||
#
|
||||
# Utility functions (adapted from h5py: http://h5py.googlecode.com)
|
||||
#
|
||||
|
||||
|
||||
def test_compilation(cfile, compiler=None, **compiler_attrs):
|
||||
"""Test simple compilation with given settings"""
|
||||
cc = get_compiler(compiler, **compiler_attrs)
|
||||
|
||||
efile, _ = os.path.splitext(cfile)
|
||||
|
||||
cpreargs = lpreargs = []
|
||||
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']
|
||||
if sys.platform == 'sunos5':
|
||||
if platform.architecture()[0] == '32bit':
|
||||
lpreargs = ['-m32']
|
||||
else:
|
||||
lpreargs = ['-m64']
|
||||
extra_compile_args = compiler_attrs.get('extra_compile_args', [])
|
||||
if os.name != 'nt':
|
||||
extra_compile_args += ['--std=c++14']
|
||||
extra_link_args = compiler_attrs.get('extra_link_args', [])
|
||||
if cc.compiler_type == 'msvc':
|
||||
extra_link_args += ['/MANIFEST']
|
||||
|
||||
objs = cc.compile([cfile], extra_preargs=cpreargs, extra_postargs=extra_compile_args)
|
||||
cc.link_executable(objs, efile, extra_preargs=lpreargs, extra_postargs=extra_link_args)
|
||||
return efile
|
||||
|
||||
|
||||
def detect_version(basedir, compiler=None, **compiler_attrs):
|
||||
"""Compile, link & execute a test program, in empty directory `basedir`.
|
||||
|
||||
The C compiler will be updated with any keywords given via setattr.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
basedir : path
|
||||
The location where the test program will be compiled and run
|
||||
compiler : str
|
||||
The distutils compiler key (e.g. 'unix', 'msvc', or 'mingw32')
|
||||
**compiler_attrs : dict
|
||||
Any extra compiler attributes, which will be set via ``setattr(cc)``.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
||||
A dict of properties for zmq compilation, with the following two keys:
|
||||
|
||||
vers : tuple
|
||||
The ZMQ version as a tuple of ints, e.g. (2,2,0)
|
||||
settings : dict
|
||||
The compiler options used to compile the test function, e.g. `include_dirs`,
|
||||
`library_dirs`, `libs`, etc.
|
||||
"""
|
||||
if compiler is None:
|
||||
compiler = get_default_compiler()
|
||||
cfile = pjoin(basedir, 'vers.cpp')
|
||||
shutil.copy(pjoin(os.path.dirname(__file__), 'vers.cpp'), cfile)
|
||||
|
||||
# check if we need to link against Realtime Extensions library
|
||||
if sys.platform.startswith('linux'):
|
||||
cc = ccompiler.new_compiler(compiler=compiler)
|
||||
cc.output_dir = basedir
|
||||
if not cc.has_function('timer_create'):
|
||||
if 'libraries' not in compiler_attrs:
|
||||
compiler_attrs['libraries'] = []
|
||||
compiler_attrs['libraries'].append('rt')
|
||||
|
||||
cc = get_compiler(compiler=compiler, **compiler_attrs)
|
||||
efile = test_compilation(cfile, compiler=cc)
|
||||
patch_lib_paths(efile, cc.library_dirs)
|
||||
|
||||
rc, so, se = get_output_error([efile])
|
||||
if rc:
|
||||
msg = "Error running version detection script:\n%s\n%s" % (so, se)
|
||||
logging.error(msg)
|
||||
raise IOError(msg)
|
||||
|
||||
handlers = {'vers': lambda val: tuple(int(v) for v in val.split('.'))}
|
||||
|
||||
props = {}
|
||||
for line in (x for x in so.split('\n') if x):
|
||||
key, val = line.split(':')
|
||||
props[key] = handlers[key](val)
|
||||
|
||||
return props
|
||||
|
||||
|
||||
def test_build(**compiler_attrs):
|
||||
"""do a test build of libcapnp"""
|
||||
tmp_dir = tempfile.mkdtemp()
|
||||
|
||||
# line()
|
||||
# info("Configure: Autodetecting Cap'n Proto settings...")
|
||||
# info(" Custom Cap'n Proto dir: %s" % prefix)
|
||||
try:
|
||||
detected = detect_version(tmp_dir, None, **compiler_attrs)
|
||||
finally:
|
||||
erase_dir(tmp_dir)
|
||||
|
||||
# info(" Cap'n Proto version detected: %s" % v_str(detected['vers']))
|
||||
|
||||
return detected
|
||||
|
||||
|
||||
def erase_dir(path):
|
||||
"""Erase directory"""
|
||||
try:
|
||||
shutil.rmtree(path)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -1,64 +0,0 @@
|
||||
"""misc build utility functions"""
|
||||
|
||||
# Copyright (c) PyZMQ Developers
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import os
|
||||
import logging
|
||||
from distutils import ccompiler
|
||||
from distutils.sysconfig import customize_compiler
|
||||
from pipes import quote
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
pjoin = os.path.join
|
||||
|
||||
|
||||
def customize_mingw(cc):
|
||||
"""customize mingw"""
|
||||
# strip -mno-cygwin from mingw32 (Python Issue #12641)
|
||||
for cmd in [cc.compiler, cc.compiler_cxx, cc.compiler_so, cc.linker_exe, cc.linker_so]:
|
||||
if '-mno-cygwin' in cmd:
|
||||
cmd.remove('-mno-cygwin')
|
||||
|
||||
# remove problematic msvcr90
|
||||
if 'msvcr90' in cc.dll_libraries:
|
||||
cc.dll_libraries.remove('msvcr90')
|
||||
|
||||
|
||||
def customize_msvc(cc):
|
||||
pass
|
||||
|
||||
|
||||
def get_compiler(compiler, **compiler_attrs):
|
||||
"""get and customize a compiler"""
|
||||
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)
|
||||
elif cc.compiler_type == 'msvc':
|
||||
customize_msvc(cc)
|
||||
else:
|
||||
cc = compiler
|
||||
|
||||
for name, val in compiler_attrs.items():
|
||||
setattr(cc, name, val)
|
||||
|
||||
return cc
|
||||
|
||||
|
||||
def get_output_error(cmd):
|
||||
"""Return the exit status, stdout, stderr of a command"""
|
||||
if not isinstance(cmd, list):
|
||||
cmd = [cmd]
|
||||
logging.debug("Running: %s", ' '.join(map(quote, cmd)))
|
||||
try:
|
||||
result = Popen(cmd, stdout=PIPE, stderr=PIPE)
|
||||
except IOError as e:
|
||||
return -1, '', 'Failed to run %r: %r' % (cmd, e)
|
||||
so, se = result.communicate()
|
||||
# unicode:
|
||||
so = so.decode('utf8', 'replace')
|
||||
se = se.decode('utf8', 'replace')
|
||||
|
||||
return result.returncode, so, se
|
||||
@@ -1,67 +0,0 @@
|
||||
"""utils for patching libraries"""
|
||||
|
||||
# Copyright (c) PyZMQ Developers.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
|
||||
from .misc import get_output_error
|
||||
|
||||
pjoin = os.path.join
|
||||
|
||||
# LIB_PAT from delocate
|
||||
LIB_PAT = re.compile(
|
||||
r"\s*(.*) \(compatibility version (\d+\.\d+\.\d+), current version (\d+\.\d+\.\d+)\)"
|
||||
)
|
||||
|
||||
|
||||
def _get_libs(fname):
|
||||
rc, so, se = get_output_error(['otool', '-L', fname])
|
||||
if rc:
|
||||
logging.error("otool -L %s failed: %r", fname, se)
|
||||
return
|
||||
for line in so.splitlines()[1:]:
|
||||
m = LIB_PAT.match(line)
|
||||
if m:
|
||||
yield m.group(1)
|
||||
|
||||
|
||||
def _find_library(lib, path):
|
||||
"""Find a library"""
|
||||
for d in path[::-1]:
|
||||
real_lib = os.path.join(d, lib)
|
||||
if os.path.exists(real_lib):
|
||||
return real_lib
|
||||
return None
|
||||
|
||||
|
||||
def _install_name_change(fname, lib, real_lib):
|
||||
rc, so, se = get_output_error(['install_name_tool', '-change', lib, real_lib, fname])
|
||||
if rc:
|
||||
logging.error("Couldn't update load path: %s", se)
|
||||
|
||||
|
||||
def patch_lib_paths(fname, library_dirs):
|
||||
"""Load any weakly-defined libraries from their real location
|
||||
|
||||
(only on OS X)
|
||||
|
||||
- Find libraries with `otool -L`
|
||||
- Update with `install_name_tool -change`
|
||||
"""
|
||||
if sys.platform != 'darwin':
|
||||
return
|
||||
|
||||
libs = _get_libs(fname)
|
||||
for lib in libs:
|
||||
if not lib.startswith(('@', '/')):
|
||||
real_lib = _find_library(lib, library_dirs)
|
||||
if real_lib:
|
||||
_install_name_change(fname, lib, real_lib)
|
||||
|
||||
|
||||
__all__ = ['patch_lib_paths']
|
||||
@@ -1,9 +0,0 @@
|
||||
// check libcapnp version
|
||||
|
||||
#include <stdio.h>
|
||||
#include "capnp/common.h"
|
||||
|
||||
int main(int argc, char **argv){
|
||||
fprintf(stdout, "vers: %d.%d.%d\n", CAPNP_VERSION_MAJOR, CAPNP_VERSION_MINOR, CAPNP_VERSION_MICRO);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user