From 9dfa3949211c010370c8e56fa1f815aeac3a76f0 Mon Sep 17 00:00:00 2001 From: Wiktor Niesiobedzki Date: Sun, 6 May 2018 22:33:57 +0200 Subject: [PATCH] Binary wheels Use manylinux docker image to generate manylinux wheels for all Python versions available on manylinux. Manylinux wheel includes boost_python library, so there is no need to install any other libraries in the system. For macOS - generate standard wheel that will depend on current HomeBrew boost_python library. --- .travis.yml | 130 ++++++++++++++++++++++++-------------- travis/build_macos.sh | 13 ++++ travis/build_manylinux.sh | 50 +++++++++++++++ travis/test_docker.sh | 88 ++++++++++++++++++++++++++ travis/test_manylinux.sh | 9 +++ 5 files changed, 244 insertions(+), 46 deletions(-) create mode 100755 travis/build_macos.sh create mode 100755 travis/build_manylinux.sh create mode 100755 travis/test_docker.sh create mode 100755 travis/test_manylinux.sh diff --git a/.travis.yml b/.travis.yml index c4951dcc..8d2d4d2f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,65 +6,103 @@ language: cpp -sudo: false -dist: trusty - matrix: include: - - os: linux + - sudo: required + services: + - docker + env: DOCKER_IMAGE=quay.io/pypa/manylinux1_x86_64 DOCKER_TESTS=yes + - sudo: required + services: + - docker + env: DOCKER_IMAGE=quay.io/pypa/manylinux1_i686 + PRE_CMD=linux32 + - os: osx + osx_image: xcode8.3 + compiler: clang + env: USE_PYTHON_VERSION=2 PYTHON_SUFFIX= + - os: osx + osx_image: xcode8.3 compiler: clang - env: USE_PYTHON_VERSION=2 - - os: linux + env: USE_PYTHON_VERSION=3 PYTHON_SUFFIX=3 + - os: osx + osx_image: xcode7.3 compiler: clang - env: USE_PYTHON_VERSION=3 - - os: linux - compiler: gcc - env: USE_PYTHON_VERSION=2 - - os: linux - compiler: gcc - env: USE_PYTHON_VERSION=3 + env: USE_PYTHON_VERSION=2 PYTHON_SUFFIX= + - os: osx + osx_image: xcode7.3 + compiler: clang + env: USE_PYTHON_VERSION=3 PYTHON_SUFFIX=3 # http://docs.travis-ci.com/user/apt/ -addons: - apt: - sources: - - boost-latest - packages: - - g++-4.8 - - gcc-4.8 - - libboost-python1.55-dev - - libboost1.55-dev - - libsparsehash-dev - - python-dev - - python-nose - - python-mock - - python3 - - python3-dev - - python3-nose - - python3-setuptools + install: - - git clone --quiet --depth 1 https://github.com/osmcode/libosmium.git ../libosmium - - git clone --quiet --depth 1 https://github.com/mapbox/protozero.git ../protozero - - if [ "$TRAVIS_OS_NAME" = 'osx' ]; then - brew update; - brew install python$PYTHON_SUFFIX google-sparsehash; - brew install boost-python $BOOST_PYTHON_OPTION; - pip$PYTHON_SUFFIX install -q nose mock; + - git clone --quiet --depth 1 https://github.com/osmcode/libosmium.git libosmium + - git clone --quiet --depth 1 https://github.com/mapbox/protozero.git protozero + - if [ "${TRAVIS_OS_NAME}" = 'osx' ]; then + brew update && + brew install google-sparsehash && + brew install boost-python$PYTHON_SUFFIX ; fi script: - - if [ "${CXX}" = 'g++' ]; then - CXX=g++-4.8; - CC=gcc-4.8; + - if [ "${TRAVIS_OS_NAME}" = 'osx' ]; then + export PYTHON="python${USE_PYTHON_VERSION}" ; + travis/build_macos.sh ; + else + docker run --rm -v `pwd`:/io $DOCKER_IMAGE $PRE_CMD /io/travis/build_manylinux.sh ; fi - if [ "$TRAVIS_OS_NAME" = 'osx' ]; then - PYTHON=python${USE_PYTHON_VERSION}; + $PYTHON -m virtualenv venv_runtime && + venv_runtime/bin/pip install osmium --no-index -f ./dist && + venv_runtime/bin/pip install nose mock && + venv_runtime/bin/python -c 'import osmium; print("import osmium successful")' && + (cd test && ../venv_runtime/bin/python run_tests.py ) else - PYTHON=/usr/bin/python${USE_PYTHON_VERSION}; + docker run --rm -v `pwd`:/io:ro $DOCKER_IMAGE $PRE_CMD /io/travis/test_manylinux.sh ; fi - - $PYTHON --version - - $PYTHON setup.py build - - cd test - - $PYTHON run_tests.py + - if [ "x$DOCKER_TESTS" = "xyes" ]; then travis/test_docker.sh debian 2 && echo Tests Debian 2 OK ; fi + - if [ "x$DOCKER_TESTS" = "xyes" ]; then travis/test_docker.sh debian 3 && echo Tests Debian 3 OK ; fi + - if [ "x$DOCKER_TESTS" = "xyes" ]; then travis/test_docker.sh ubuntu 2 && echo Tests Ubuntu 2 OK ; fi + - if [ "x$DOCKER_TESTS" = "xyes" ]; then travis/test_docker.sh ubuntu 3 && echo Tests Ubuntu 3 OK ; fi + - if [ "x$DOCKER_TESTS" = "xyes" ]; then travis/test_docker.sh centos 2 && echo Tests Centos 2 OK ; fi + - if [ "x$DOCKER_TESTS" = "xyes" ]; then travis/test_docker.sh centos 3 && echo Tests Centos 3 OK ; fi + - if [ "x$DOCKER_TESTS" = "xyes" ]; then travis/test_docker.sh archlinux 2 && echo Tests ArchLinux 2 OK ; fi + - if [ "x$DOCKER_TESTS" = "xyes" ]; then travis/test_docker.sh archlinux 3 && echo Tests ArchLinux 3 OK ; fi + +deploy: + provider: s3 + skip_cleanup: true + acl: public_read + region: eu-west-1 + local_dir: dist + access_key_id: ${AWS_ACCESS_KEY_ID} + secret_access_key: ${AWS_SECRET} + bucket: pyosmium + on: + all_branches: true + +deploy: + provider: releases + api-key: ${GITHUB_ACCESS_KEY} + file_glob: true + file: dist/*whl + draft: true + prerelease: false + on: + tags: true + condition: ${TRAVIS_TAG:0:1} = "v" + skip_cleanup: true +deploy: + provider: releases + api-key: ${GITHUB_ACCESS_KEY} + file_glob: true + file: dist/*whl + draft: true + prerelease: true + on: + tags: fasle + branch: travis_wheel + skip_cleanup: true diff --git a/travis/build_macos.sh b/travis/build_macos.sh new file mode 100755 index 00000000..9b2a705a --- /dev/null +++ b/travis/build_macos.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -e -x + +$PYTHON --version +$PYTHON -m pip install virtualenv +$PYTHON -m virtualenv venv_build + +export LIBOSMIUM_PREFIX=./libosmium +export PROTOZERO_PREFIX=./protozero + +venv_build/bin/python -m pip install -q nose mock wheel setuptools auditwheel +venv_build/bin/pip wheel . -w dist/ +rm -rf build diff --git a/travis/build_manylinux.sh b/travis/build_manylinux.sh new file mode 100755 index 00000000..775756b8 --- /dev/null +++ b/travis/build_manylinux.sh @@ -0,0 +1,50 @@ +#!/bin/bash +set -e -x + +yum install -y sparsehash-devel bzip2-devel zlib-devel + +mkdir -p boost +RETURN_PWD="$(pwd)" +cd boost +export BOOST_PREFIX="$(pwd)" +curl -L https://dl.bintray.com/boostorg/release/1.67.0/source/boost_1_67_0.tar.bz2 | tar xfj - +cd boost_1_67_0/ +BOOST_ROOT="$(pwd)" +cd tools/build +sh bootstrap.sh +./b2 install --prefix="${BOOST_PREFIX}" + +for PYBIN in /opt/python/*/bin ; do + cd "${BOOST_ROOT}" + cat << EOF > tools/build/src/site-config.jam + using gcc ; + using python : : $(ls ${PYBIN}/python* | head -n 1 ) : $(${PYBIN}/python -c 'from sysconfig import get_paths; print(get_paths()["include"])') ; +EOF + echo "Using following BOOST configuration:" + cat tools/build/src/site-config.jam + + echo "Using PYTHON_VERSION: ${PYBIN}" + rm -rf ${BOOST_PREFIX}/build + "${BOOST_PREFIX}"/bin/b2 --with-python --toolset=gcc --prefix="${BOOST_PREFIX}" --build-dir="${BOOST_PREFIX}"/build stage + + "${BOOST_PREFIX}"/bin/b2 --with-python --toolset=gcc --prefix="${BOOST_PREFIX}" --build-dir="${BOOST_PREFIX}"/build install > /dev/null + # Add boost path to loader and linker + export LD_LIBRARY_PATH="${BOOST_PREFIX}/lib:${LD_LIBRARY_PATH}" + export LIBRARY_PATH="${BOOST_PREFIX}/lib" + + # update ldconfig cache, so find_library will find it + ldconfig ${BOOST_PREFIX}/lib + export LIBOSMIUM_PREFIX=/io/libosmium + export PROTOZERO_PREFIX=/io/protozero + cd /io + rm -rf /io/build + rm -rf wheelhouse + "${PYBIN}/python" setup.py build + "${PYBIN}/pip" wheel /io/ -w wheelhouse/ + for whl in wheelhouse/*.whl; do + auditwheel repair "$whl" -w /io/dist/ + done + rm -rf /io/build + rm -rf wheelhouse +done + diff --git a/travis/test_docker.sh b/travis/test_docker.sh new file mode 100755 index 00000000..ed94ea8d --- /dev/null +++ b/travis/test_docker.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +set -e -v + +PACKAGE_INSTALL="apt-get update ; apt-get install -y python python-virtualenv" +DOCKER_IMAGE=debian +SHEEL=/bin/bash + +OS=${1} +PYTHON_VERSION=${2} + +case ${PYTHON_VERSION} in +"2") + PYTHON=python + ;; +"3") + PYTHON=python3 + ;; +*) + exit "Uknown python version: ${PYTHON_VERSION}" + ;; +esac + +case ${OS} in +"debian") + if [ ${PYTHON_VERSION} = "2" ] ; then + PACKAGE_INSTALL="apt-get update && apt-get install -y python python-virtualenv" + else + PACKAGE_INSTALL="apt-get update && apt-get install -y python3 python3-virtualenv" + fi + DOCKER_IMAGE=${OS} + ;; +"ubuntu") + if [ ${PYTHON_VERSION} = "2" ] ; then + PACKAGE_INSTALL="apt-get update && apt-get install -y python python-virtualenv" + else + PACKAGE_INSTALL="apt-get update && apt-get install -y python3 python3-virtualenv" + fi + DOCKER_IMAGE=${OS} + ;; +"centos") + if [ ${PYTHON_VERSION} = "2" ] ; then + PACKAGE_INSTALL="yum install -y epel-release && yum install -y python2 python2-virtualenv" + else + PACKAGE_INSTALL="yum install -y epel-release && yum install -y python34 python34-virtualenv" + fi + DOCKER_IMAGE=${OS} + ;; +"archlinux") + if [ ${PYTHON_VERSION} = "2" ] ; then + PACKAGE_INSTALL="pacman -Sy --noconfirm python2 python2-virtualenv" + PYTHON=python2 + else + PACKAGE_INSTALL="pacman -Sy --noconfirm python3 python-virtualenv" + PYTHON=python + fi + DOCKER_IMAGE="base/archlinux" + ;; +"alpine") + if [ ${PYTHON_VERSION} = "2" ] ; then + PACKAGE_INSTALL="apk update && apk add python2 py2-virtualenv" + else + PACKAGE_INSTALL="apk update && apk add python3 py3-virtualenv" + fi + DOCKER_IMAGE=${OS} + PYTHON=python + SHELL=/bin/ash + ;; + +*) + exit "Uknown OS: ${OS}" + ;; +esac + +rm -rf build +VENV_PYTHON=/venv/bin/python +VENV_PIP=/venv/bin/pip +cat << EOF | docker run --rm -i -v `pwd`:/io:ro $DOCKER_IMAGE $SHELL +set -e -v +${PACKAGE_INSTALL} && +${PYTHON} -m virtualenv --python=python${PYTHON_VERSION} /venv && +${VENV_PIP} install -U setuptools nose mock && +${VENV_PYTHON} -c "from setuptools.pep425tags import is_manylinux1_compatible, get_supported ; print('Manylinux compatibility: ' + str(is_manylinux1_compatible())+ '\n' + 'Supported latforms: ' + ','.join((str(x) for x in get_supported())))" && +${VENV_PIP} install osmium --no-index -f /io/dist && +cd /io/test && +${VENV_PYTHON} -m nose && +${VENV_PYTHON} -c "import osmium" +EOF diff --git a/travis/test_manylinux.sh b/travis/test_manylinux.sh new file mode 100755 index 00000000..244a61db --- /dev/null +++ b/travis/test_manylinux.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -e -x + +for PYBIN in /opt/python/*/bin ; do + "${PYBIN}/pip" install nose mock + "${PYBIN}/pip" install osmium --no-index -f /io/dist + "${PYBIN}/python" -c "import osmium" + "${PYBIN}/python" /io/test/run_tests.py || "${PYBIN}/python2" /io/test/run_tests.py || "${PYBIN}/python3" /io/test/run_tests.py +done