From d92c687e84d9dc3ba40df42efeadd9876ebd3e52 Mon Sep 17 00:00:00 2001 From: Scott Gigante Date: Sat, 22 Dec 2018 19:55:57 -0500 Subject: [PATCH] deploy bdist_wheel --- .appveyor.yml | 24 +++++++++ .pypirc | 7 +++ .travis.yml | 114 ++++++++++++++++++++++++++++++--------- python_bindings/setup.py | 33 +++++++++--- 4 files changed, 144 insertions(+), 34 deletions(-) create mode 100644 .pypirc diff --git a/.appveyor.yml b/.appveyor.yml index 16afc1c..531402a 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -2,12 +2,19 @@ version: '{build}' image: Visual Studio 2015 platform: - x64 +- x86 environment: global: DISTUTILS_USE_SDK: 1 MSSdk: 1 matrix: - PYTHON: 27 + - PYTHON: 35 + - PYTHON: 36 + - PYTHON: 37 + pypipassword: + # https://ci.appveyor.com/tools/encrypt + secure: GRzEKTz0q+eRwEFvm1Vdrg== install: - cmd: '"%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" %PLATFORM%' - cmd: git config core.symlinks true @@ -26,9 +33,26 @@ install: conda update -q conda conda install -q conda-build } +- cmd: python --version build_script: - ps: cd python_bindings - cmd: | pip install -e . test_script: - cmd: python setup.py test + +deploy_script: +- ps: | + if ($env:APPVEYOR_REPO_BRANCH -ne "master" -or $env:APPVEYOR_REPO_TAG -ne "true") { return } + # Specify account details for PyPI + echo "Deploying..." + mv .pypirc $env:USERPROFILE\\.pypirc + # Workaround required to ensure setup.py finds the .pypirc under Windows + $env:HOME=$env:USERPROFILE + # Install wheel-building support + pip install --user wheel twine + # Build wheel and upload + python setup.py sdist bdist_wheel + twine upload -r pypi -p $env:pypipassword --skip-existing dist/* + echo "Deployment complete" + diff --git a/.pypirc b/.pypirc new file mode 100644 index 0000000..b1b6ac3 --- /dev/null +++ b/.pypirc @@ -0,0 +1,7 @@ +[distutils] +index-servers = + pypi + +[pypi] +repository=https://upload.pypi.org/legacy/ +username=searchivarius diff --git a/.travis.yml b/.travis.yml index 338a276..824040d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,47 +1,91 @@ language: cpp +sudo: required + +addons: + apt: + packages: &core_build + - g++-4.9 + - libblas-dev + - liblapack-dev + - gfortran + - cmake + - libboost-all-dev + - libgsl0-dev + - libeigen3-dev + matrix: fast_finish: true include: - os: linux + dist: trusty env: PYTHON=2.7 + addons: + apt: + update: true + sources: + - ubuntu-toolchain-r-test + - deadsnakes + packages: + - *core_build + - python2.7-dev - os: linux - env: PYTHON=3 + env: PYTHON=3.5 + dist: trusty + addons: + apt: + update: true + sources: + - ubuntu-toolchain-r-test + - deadsnakes + packages: + - *core_build + - python3.5-dev + - os: linux + env: PYTHON=3.6 + dist: xenial + addons: + apt: + update: true + sources: + - ubuntu-toolchain-r-test + - deadsnakes + packages: + - *core_build + - python3.6-dev + - os: linux + env: PYTHON=3.7 + dist: xenial + addons: + apt: + update: true + sources: + - ubuntu-toolchain-r-test + - deadsnakes + packages: + - *core_build + - python3.7-dev + - os: osx + env: PYTHON=27 + osx_image: xcode9.3 + - os: osx + env: PYTHON=35 + osx_image: xcode9.3 - os: osx - env: PYTHON=3 + env: PYTHON=36 osx_image: xcode9.3 - python: 3.7.0 - os: osx - env: PYTHON=2 + env: PYTHON=37 osx_image: xcode9.3 - python: 2.7.14 allow_failures: - os: osx -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.8 - - libblas-dev - - liblapack-dev - - gfortran - - cmake - - python3-dev - - libboost-all-dev - - libgsl0-dev - - libeigen3-dev - before_install: - | PIP=pip PY=python if [ "$TRAVIS_OS_NAME" = "linux" ]; then - export CXX=g++-4.8 CC=gcc-4.8; - pip install --user --upgrade pip virtualenv - virtualenv -p python$PYTHON venv - source venv/bin/activate + export CXX=g++-4.9 CC=gcc-4.9; fi if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then @@ -51,11 +95,15 @@ before_install: PY=python2 if [ "${PYTHON:0:1}" = "3" ]; then brew upgrade python - brew install python3 + brew install sashkab/python/python$PYTHON PIP=pip3 PY=python3 fi fi + $PIP install --user virtualenv + virtualenv -p $PY venv + source venv/bin/activate + $PIP install --upgrade pip install: - | @@ -65,7 +113,9 @@ install: cmake similarity_search fi make -j 4 - travis_wait travis_retry $PIP install -r python_bindings/requirements.txt scipy six flake8 + $PY -m pip install --upgrade pip + travis_wait travis_retry $PIP install scipy six flake8 + travis_wait travis_retry $PIP install -r python_bindings/requirements.txt travis_retry cd python_bindings && $PY setup.py build install && cd .. script: @@ -80,6 +130,18 @@ script: cd .. fi +deploy: + provider: pypi + user: searchivarius + # https://docs.travis-ci.com/user/environment-variables/#defining-variables-in-repository-settings + password: ${PYPI_PASSWORD} + distributions: sdist bdist_wheel + skip_existing: true + skip_cleanup: true + on: + tags: true + branch: master + cache: - apt - directories: diff --git a/python_bindings/setup.py b/python_bindings/setup.py index 1a16797..4def3f2 100755 --- a/python_bindings/setup.py +++ b/python_bindings/setup.py @@ -23,7 +23,8 @@ if os.path.exists(library_file): extra_objects.append(library_file) else: - # Otherwise build all the files here directly (excluding extras which need eigen/boost) + # Otherwise build all the files here directly (excluding extras which need + # eigen/boost) exclude_files = set("""bbtree.cc lsh.cc lsh_multiprobe.cc lsh_space.cc falconn.cc nndes.cc space_sqfd.cc dummy_app.cc main.cc""".split()) @@ -38,11 +39,27 @@ if sys.platform.startswith('linux'): extra_objects.append(lshkit) libraries.extend(['gsl', 'gslcblas', 'boost_program_options']) + +class get_pybind_include(object): + """Helper class to determine the pybind11 include path + The purpose of this class is to postpone importing pybind11 + until it is actually installed, so that the ``get_include()`` + method can be invoked. """ + + def __init__(self, user=False): + self.user = user + + def __str__(self): + import pybind11 + return pybind11.get_include(self.user) + ext_modules = [ Extension( 'nmslib', source_files, - include_dirs=[os.path.join(libdir, "include")], + include_dirs=[os.path.join(libdir, "include"), + get_pybind_include(), + get_pybind_include(user=True)], libraries=libraries, language='c++', extra_objects=extra_objects, @@ -102,25 +119,25 @@ class BuildExt(build_ext): ct = self.compiler.compiler_type opts = self.c_opts.get(ct, []) if ct == 'unix': - opts.append('-DVERSION_INFO="%s"' % self.distribution.get_version()) + opts.append('-DVERSION_INFO="%s"' % + self.distribution.get_version()) opts.append(cpp_flag(self.compiler)) if has_flag(self.compiler, '-fvisibility=hidden'): opts.append('-fvisibility=hidden') elif ct == 'msvc': - opts.append('/DVERSION_INFO=\\"%s\\"' % self.distribution.get_version()) + opts.append('/DVERSION_INFO=\\"%s\\"' % + self.distribution.get_version()) # extend include dirs here (don't assume numpy/pybind11 are installed when first run, since # pip could have installed them as part of executing this script - import pybind11 import numpy as np for ext in self.extensions: ext.extra_compile_args.extend(opts) ext.extra_link_args.extend(self.link_opts.get(ct, [])) ext.include_dirs.extend([ # Path to pybind11 headers - pybind11.get_include(), - pybind11.get_include(True), - + get_pybind_include(), + get_pybind_include(user=True), # Path to numpy headers np.get_include() ])