Merge remote-tracking branch 'origin/master' into docs
Manually merged updates to README.md across to docs # Conflicts: # README.md
This commit is contained in:
+8
-2
@@ -23,9 +23,15 @@ matrix:
|
||||
# macOS Python 3
|
||||
- os: osx
|
||||
env: PYTHON=python3
|
||||
|
||||
- os: windows
|
||||
language: shell
|
||||
before_install:
|
||||
- brew update
|
||||
- brew outdated python || brew upgrade python
|
||||
- choco install python3 --version 3.6.8 --no-progress -y
|
||||
install:
|
||||
- C:\\Python36\\python -m pip install -r requirements-dev.txt
|
||||
script:
|
||||
- C:\\Python36\\python ./bin/run_tests.py
|
||||
|
||||
install: $PYTHON -m pip install -r requirements-dev.txt
|
||||
|
||||
|
||||
@@ -17,13 +17,15 @@ What does it do?
|
||||
|
||||
| | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit |
|
||||
|---|---|---|---|---|---|
|
||||
| Python 2.7 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Python 3.4 | ✅ | ✅ | ✅ | ✅* | ✅* |
|
||||
| Python 2.7 | ✅ | ✅ | ✅ | ✅² | ✅² |
|
||||
| Python 3.4 | ✅ | ✅ | ✅ | ✅¹²| ✅¹²|
|
||||
| Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
> \* Not supported on Azure Pipelines
|
||||
> ¹ Not supported on Azure Pipelines
|
||||
>
|
||||
> ² Not supported on Travis
|
||||
|
||||
- Builds manylinux, macOS and Windows (32 and 64bit) wheels using Azure Pipelines, Travis CI, AppVeyor, and CircleCI
|
||||
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
|
||||
@@ -32,7 +34,14 @@ What does it do?
|
||||
Usage
|
||||
-----
|
||||
|
||||
`cibuildwheel` currently works **Travis CI** and **CircleCI** to build Linux and Mac wheels, and **AppVeyor** to build Windows wheels. **Azure Pipelines** supports all three.
|
||||
`cibuildwheel` currently works on **Travis CI** and **Azure Pipelines** to build wheels for all three supported platforms (Linux, macOS, Windows). On **CircleCI** Linux and macOS wheels can be built, and on **AppVeyor** Windows is supported.
|
||||
|
||||
| | Linux | macOS | Windows |
|
||||
|-----------------|-------|-------|---------|
|
||||
| Azure Pipelines | ✅ | ✅ | ✅ |
|
||||
| Travis CI | ✅ | ✅ | ✅ |
|
||||
| AppVeyor | | | ✅ |
|
||||
| CircleCI | ✅ | ✅ | |
|
||||
|
||||
`cibuildwheel` is not intended to run on your development machine. Because it uses system Python from Python.org it will try to install packages globally - not what you expect from a build tool! Instead, isolated CI services like Travis CI, CircleCI, Azure Pipelines and AppVeyor are ideal.
|
||||
|
||||
|
||||
@@ -54,6 +54,8 @@ def main():
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
detect_obsolete_options()
|
||||
|
||||
if args.platform != 'auto':
|
||||
platform = args.platform
|
||||
else:
|
||||
@@ -63,6 +65,8 @@ def main():
|
||||
platform = 'linux'
|
||||
elif os.environ.get('TRAVIS_OS_NAME') == 'osx':
|
||||
platform = 'macos'
|
||||
elif os.environ.get('TRAVIS_OS_NAME') == 'windows':
|
||||
platform = 'windows'
|
||||
elif 'APPVEYOR' in os.environ:
|
||||
platform = 'windows'
|
||||
elif 'BITRISE_BUILD_NUMBER' in os.environ:
|
||||
@@ -141,11 +145,17 @@ def main():
|
||||
)
|
||||
|
||||
if platform == 'linux':
|
||||
manylinux1_x86_64_image = os.environ.get('CIBW_MANYLINUX1_X86_64_IMAGE', None)
|
||||
manylinux1_i686_image = os.environ.get('CIBW_MANYLINUX1_I686_IMAGE', None)
|
||||
manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', 'manylinux2010')
|
||||
manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', 'manylinux2010')
|
||||
|
||||
default_manylinux_images_x86_64 = {'manylinux1': 'quay.io/pypa/manylinux1_x86_64',
|
||||
'manylinux2010': 'quay.io/pypa/manylinux2010_x86_64'}
|
||||
default_manylinux_images_i686 = {'manylinux1': 'quay.io/pypa/manylinux1_i686',
|
||||
'manylinux2010': 'quay.io/pypa/manylinux2010_i686'}
|
||||
|
||||
build_options.update(
|
||||
manylinux1_images={'x86_64': manylinux1_x86_64_image, 'i686': manylinux1_i686_image},
|
||||
manylinux_images={'x86_64': default_manylinux_images_x86_64.get(manylinux_x86_64_image) or manylinux_x86_64_image,
|
||||
'i686': default_manylinux_images_i686.get(manylinux_i686_image) or manylinux_i686_image},
|
||||
)
|
||||
elif platform == 'macos':
|
||||
pass
|
||||
@@ -170,6 +180,26 @@ def main():
|
||||
raise Exception('Unsupported platform')
|
||||
|
||||
|
||||
def detect_obsolete_options():
|
||||
# Check the old 'MANYLINUX1_*_IMAGE' options
|
||||
for (deprecated, alternative) in [('CIBW_MANYLINUX1_X86_64_IMAGE', 'CIBW_MANYLINUX_X86_64_IMAGE'),
|
||||
('CIBW_MANYLINUX1_I686_IMAGE', 'CIBW_MANYLINUX_I686_IMAGE')]:
|
||||
if deprecated in os.environ:
|
||||
print("'{}' has been deprecated, and will be removed in a future release. Use the option '{}' instead.".format(deprecated, alternative))
|
||||
if alternative not in os.environ:
|
||||
print("Using value of option '{}' as replacement for '{}'".format(deprecated, alternative))
|
||||
os.environ[alternative] = os.environ[deprecated]
|
||||
else:
|
||||
print("Option '{}' is not empty. Please unset '{}'".format(alternative, deprecated))
|
||||
exit(2)
|
||||
|
||||
# Check for 'manylinux1' in the 'CIBW_BUILD' and 'CIBW_SKIP' options
|
||||
for deprecated in ['CIBW_BUILD', 'CIBW_SKIP']:
|
||||
if deprecated in os.environ and 'manylinux1' in os.environ[deprecated]:
|
||||
print("Build identifiers with 'manylinux1' been deprecated. Replacing all occurences of 'manylinux1' by 'manylinux' in the option '{}'".format(deprecated))
|
||||
os.environ[deprecated] = os.environ[deprecated].replace('manylinux1', 'manylinux')
|
||||
|
||||
|
||||
def print_preamble(platform, build_options):
|
||||
print(textwrap.dedent('''
|
||||
_ _ _ _ _ _ _
|
||||
|
||||
+56
-34
@@ -12,25 +12,25 @@ except ImportError:
|
||||
def get_python_configurations(build_selector):
|
||||
PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path'])
|
||||
python_configurations = [
|
||||
PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27mu'),
|
||||
PythonConfiguration(identifier='cp34-manylinux1_x86_64', path='/opt/python/cp34-cp34m'),
|
||||
PythonConfiguration(identifier='cp35-manylinux1_x86_64', path='/opt/python/cp35-cp35m'),
|
||||
PythonConfiguration(identifier='cp36-manylinux1_x86_64', path='/opt/python/cp36-cp36m'),
|
||||
PythonConfiguration(identifier='cp37-manylinux1_x86_64', path='/opt/python/cp37-cp37m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux1_i686', path='/opt/python/cp27-cp27m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux1_i686', path='/opt/python/cp27-cp27mu'),
|
||||
PythonConfiguration(identifier='cp34-manylinux1_i686', path='/opt/python/cp34-cp34m'),
|
||||
PythonConfiguration(identifier='cp35-manylinux1_i686', path='/opt/python/cp35-cp35m'),
|
||||
PythonConfiguration(identifier='cp36-manylinux1_i686', path='/opt/python/cp36-cp36m'),
|
||||
PythonConfiguration(identifier='cp37-manylinux1_i686', path='/opt/python/cp37-cp37m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'),
|
||||
PythonConfiguration(identifier='cp34-manylinux_x86_64', path='/opt/python/cp34-cp34m'),
|
||||
PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'),
|
||||
PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'),
|
||||
PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'),
|
||||
PythonConfiguration(identifier='cp34-manylinux_i686', path='/opt/python/cp34-cp34m'),
|
||||
PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'),
|
||||
PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'),
|
||||
PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'),
|
||||
]
|
||||
|
||||
# skip builds as required
|
||||
return [c for c in python_configurations if build_selector(c.identifier)]
|
||||
|
||||
|
||||
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment, manylinux1_images):
|
||||
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment, manylinux_images):
|
||||
try:
|
||||
subprocess.check_call(['docker', '--version'])
|
||||
except:
|
||||
@@ -42,8 +42,8 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
|
||||
|
||||
python_configurations = get_python_configurations(build_selector)
|
||||
platforms = [
|
||||
('manylinux1_x86_64', manylinux1_images.get('x86_64') or 'quay.io/pypa/manylinux1_x86_64'),
|
||||
('manylinux1_i686', manylinux1_images.get('i686') or 'quay.io/pypa/manylinux1_i686'),
|
||||
('manylinux_x86_64', manylinux_images['x86_64']),
|
||||
('manylinux_i686', manylinux_images['i686']),
|
||||
]
|
||||
|
||||
for platform_tag, docker_image in platforms:
|
||||
@@ -62,9 +62,9 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
|
||||
for PYBIN in {pybin_paths}; do
|
||||
# Setup
|
||||
rm -rf /tmp/built_wheel
|
||||
rm -rf /tmp/delocated_wheel
|
||||
rm -rf /tmp/delocated_wheels
|
||||
mkdir /tmp/built_wheel
|
||||
mkdir /tmp/delocated_wheel
|
||||
mkdir /tmp/delocated_wheels
|
||||
|
||||
if [ ! -z {before_build} ]; then
|
||||
PATH="$PYBIN:$PATH" sh -c {before_build}
|
||||
@@ -79,30 +79,52 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
|
||||
# the first element
|
||||
if [[ "$built_wheel" == *none-any.whl ]]; then
|
||||
# pure python wheel - just copy
|
||||
mv "$built_wheel" /tmp/delocated_wheel
|
||||
mv "$built_wheel" /tmp/delocated_wheels
|
||||
else
|
||||
auditwheel repair "$built_wheel" -w /tmp/delocated_wheel
|
||||
auditwheel repair "$built_wheel" -w /tmp/delocated_wheels
|
||||
fi
|
||||
delocated_wheel=(/tmp/delocated_wheel/*.whl)
|
||||
delocated_wheels=(/tmp/delocated_wheels/*.whl)
|
||||
|
||||
# Install the wheel we just built
|
||||
"$PYBIN/pip" install "$delocated_wheel"{test_extras}
|
||||
|
||||
# Install any requirements to run the tests
|
||||
if [ ! -z "{test_requires}" ]; then
|
||||
"$PYBIN/pip" install {test_requires}
|
||||
fi
|
||||
|
||||
# Run the tests from a different directory
|
||||
if [ ! -z {test_command} ]; then
|
||||
pushd $HOME
|
||||
PATH="$PYBIN:$PATH" sh -c {test_command}
|
||||
popd
|
||||
# Set up a virtual environment to install and test from, to make sure
|
||||
# there are no dependencies that were pulled in at build time.
|
||||
"$PYBIN/pip" install virtualenv
|
||||
venv_dir=`mktemp -d`/venv
|
||||
"$PYBIN/python" -m virtualenv "$venv_dir"
|
||||
|
||||
# run the tests in a subshell to keep that `activate`
|
||||
# script from polluting the env
|
||||
(
|
||||
source "$venv_dir/bin/activate"
|
||||
|
||||
echo "Running tests using `which python`"
|
||||
|
||||
# Install the wheel we just built
|
||||
# Note: If auditwheel produced two wheels, it's because the earlier produced wheel
|
||||
# conforms to multiple manylinux standards. These multiple versions of the wheel are
|
||||
# functionally the same, differing only in name, wheel metadata, and possibly include
|
||||
# different external shared libraries. so it doesn't matter which one we run the tests on.
|
||||
# Let's just pick the first one.
|
||||
pip install "${{delocated_wheels[0]}}"{test_extras}
|
||||
|
||||
# Install any requirements to run the tests
|
||||
if [ ! -z "{test_requires}" ]; then
|
||||
pip install {test_requires}
|
||||
fi
|
||||
|
||||
# Run the tests from a different directory
|
||||
pushd $HOME
|
||||
sh -c {test_command}
|
||||
popd
|
||||
)
|
||||
|
||||
# clean up
|
||||
rm -rf "$venv_dir"
|
||||
fi
|
||||
|
||||
# we're all done here; move it to output
|
||||
mv "$delocated_wheel" /output
|
||||
chown {uid}:{gid} "/output/$(basename "$delocated_wheel")"
|
||||
mv "${{delocated_wheels[@]}}" /output
|
||||
for delocated_wheel in "${{delocated_wheels[@]}}"; do chown {uid}:{gid} "/output/$(basename "$delocated_wheel")"; done
|
||||
done
|
||||
'''.format(
|
||||
pybin_paths=' '.join(c.path+'/bin' for c in platform_configs),
|
||||
|
||||
+32
-9
@@ -1,4 +1,5 @@
|
||||
from __future__ import print_function
|
||||
import tempfile
|
||||
import os, subprocess, shlex, sys, shutil
|
||||
from collections import namedtuple
|
||||
from glob import glob
|
||||
@@ -13,11 +14,11 @@ from .util import prepare_command, get_build_verbosity_extra_flags
|
||||
def get_python_configurations(build_selector):
|
||||
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'url'])
|
||||
python_configurations = [
|
||||
PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.16/python-2.7.16-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.17/python-2.7.17-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.4', identifier='cp34-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.4.4/python-3.4.4-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.5', identifier='cp35-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.6', identifier='cp36-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.4/python-3.7.4-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.5/python-3.7.5-macosx10.6.pkg'),
|
||||
]
|
||||
|
||||
# skip builds as required
|
||||
@@ -120,18 +121,40 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
|
||||
call(['delocate-wheel', '-w', '/tmp/delocated_wheel', built_wheel], env=env)
|
||||
delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0]
|
||||
|
||||
# install the wheel
|
||||
call(['pip', 'install', delocated_wheel + test_extras], env=env)
|
||||
|
||||
# test the wheel
|
||||
if test_requires:
|
||||
call(['pip', 'install'] + test_requires, env=env)
|
||||
if test_command:
|
||||
# set up a virtual environment to install and test from, to make sure
|
||||
# there are no dependencies that were pulled in at build time.
|
||||
call(['pip', 'install', 'virtualenv'], env=env)
|
||||
venv_dir = tempfile.mkdtemp()
|
||||
call(['python', '-m', 'virtualenv', venv_dir], env=env)
|
||||
|
||||
virtualenv_env = env.copy()
|
||||
virtualenv_env['PATH'] = os.pathsep.join([
|
||||
os.path.join(venv_dir, 'bin'),
|
||||
virtualenv_env['PATH'],
|
||||
])
|
||||
# Fix some weird issue with the shebang of installed scripts
|
||||
# See https://github.com/theacodes/nox/issues/44 and https://github.com/pypa/virtualenv/issues/620
|
||||
virtualenv_env.pop('__PYVENV_LAUNCHER__', None)
|
||||
|
||||
# check that we are using the Python from the virtual environment
|
||||
call(['which', 'python'], env=virtualenv_env)
|
||||
|
||||
# install the wheel
|
||||
call(['pip', 'install', delocated_wheel + test_extras], env=virtualenv_env)
|
||||
|
||||
# test the wheel
|
||||
if test_requires:
|
||||
call(['pip', 'install'] + test_requires, env=virtualenv_env)
|
||||
|
||||
# run the tests from $HOME, with an absolute path in the command
|
||||
# (this ensures that Python runs the tests against the installed wheel
|
||||
# and not the repo code)
|
||||
test_command_prepared = prepare_command(test_command, project=abs_project_dir)
|
||||
call(test_command_prepared, cwd=os.environ['HOME'], env=env, shell=True)
|
||||
call(test_command_prepared, cwd=os.environ['HOME'], env=virtualenv_env, shell=True)
|
||||
|
||||
# clean up
|
||||
shutil.rmtree(venv_dir)
|
||||
|
||||
# we're all done here; move it to output (overwrite existing)
|
||||
dst = os.path.join(output_dir, os.path.basename(delocated_wheel))
|
||||
|
||||
+87
-24
@@ -1,12 +1,18 @@
|
||||
from __future__ import print_function
|
||||
import os, tempfile, subprocess, shutil
|
||||
import os, tempfile, subprocess, shutil, sys
|
||||
from collections import namedtuple
|
||||
from glob import glob
|
||||
|
||||
try:
|
||||
from shlex import quote as shlex_quote
|
||||
except ImportError:
|
||||
from pipes import quote as shlex_quote
|
||||
|
||||
from .util import prepare_command, get_build_verbosity_extra_flags
|
||||
|
||||
|
||||
IS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache')
|
||||
IS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows'
|
||||
|
||||
def get_python_path(config):
|
||||
if IS_RUNNING_ON_AZURE:
|
||||
@@ -22,6 +28,12 @@ def get_python_path(config):
|
||||
return glob(path_pattern)[0]
|
||||
except IndexError:
|
||||
raise Exception('Could not find a Python install at ' + path_pattern)
|
||||
elif IS_RUNNING_ON_TRAVIS:
|
||||
if config.version == "3.4.x":
|
||||
return config.path
|
||||
else:
|
||||
nuget_args = get_nuget_args(config)
|
||||
return os.path.join(nuget_args[-1], nuget_args[0] + "." + config.nuget_version, "tools")
|
||||
else:
|
||||
# Assume we're running on AppVeyor
|
||||
major, minor = config.version.split('.')[:2]
|
||||
@@ -32,32 +44,49 @@ def get_python_path(config):
|
||||
)
|
||||
|
||||
|
||||
def get_nuget_args(configuration):
|
||||
if configuration.nuget_version is None:
|
||||
return None
|
||||
python_name = "python" if configuration.version[0] == '3' else "python2"
|
||||
if configuration.arch == "32":
|
||||
python_name = python_name + "x86"
|
||||
return [python_name, "-Version", configuration.nuget_version, "-OutputDirectory", "C:/python"]
|
||||
|
||||
def get_python_configurations(build_selector):
|
||||
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path'])
|
||||
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path', "nuget_version"])
|
||||
python_configurations = [
|
||||
PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\Python27'),
|
||||
PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\Python27-x64'),
|
||||
PythonConfiguration(version='3.4.x', arch="32", identifier='cp34-win32', path='C:\Python34'),
|
||||
PythonConfiguration(version='3.4.x', arch="64", identifier='cp34-win_amd64', path='C:\Python34-x64'),
|
||||
PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\Python35'),
|
||||
PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\Python35-x64'),
|
||||
PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\Python36'),
|
||||
PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\Python36-x64'),
|
||||
PythonConfiguration(version='3.7.x', arch="32", identifier='cp37-win32', path='C:\Python37'),
|
||||
PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\Python37-x64'),
|
||||
PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\\Python27', nuget_version="2.7.16"),
|
||||
PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\\Python27-x64', nuget_version="2.7.16"),
|
||||
PythonConfiguration(version='3.4.x', arch="32", identifier='cp34-win32', path='C:\\Python34', nuget_version=None),
|
||||
PythonConfiguration(version='3.4.x', arch="64", identifier='cp34-win_amd64', path='C:\\Python34-x64', nuget_version=None),
|
||||
PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\\Python35', nuget_version="3.5.4"),
|
||||
PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\\Python35-x64', nuget_version="3.5.4"),
|
||||
PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\\Python36', nuget_version="3.6.8"),
|
||||
PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\\Python36-x64', nuget_version="3.6.8"),
|
||||
PythonConfiguration(version='3.7.x', arch="32", identifier='cp37-win32', path='C:\\Python37', nuget_version="3.7.4"),
|
||||
PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\\Python37-x64', nuget_version="3.7.4")
|
||||
]
|
||||
|
||||
if IS_RUNNING_ON_AZURE:
|
||||
# Python 3.4 isn't supported on Azure.
|
||||
# See https://github.com/Microsoft/azure-pipelines-tasks/issues/9674
|
||||
python_configurations = [c for c in python_configurations if c.version != '3.4.x']
|
||||
|
||||
if IS_RUNNING_ON_TRAVIS:
|
||||
# cannot install VCForPython27.msi which is needed for compiling C software
|
||||
# try with (and similar): msiexec /i VCForPython27.msi ALLUSERS=1 ACCEPT=YES /passive
|
||||
# no easy and stable way fo installing python 3.4
|
||||
python_configurations = [c for c in python_configurations if c.version != '2.7.x' and c.version != '3.4.x']
|
||||
|
||||
# skip builds as required
|
||||
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
|
||||
|
||||
return python_configurations
|
||||
|
||||
# skip builds as required
|
||||
return [c for c in python_configurations if build_selector(c.identifier)]
|
||||
|
||||
|
||||
def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment):
|
||||
if IS_RUNNING_ON_AZURE:
|
||||
if IS_RUNNING_ON_AZURE or IS_RUNNING_ON_TRAVIS:
|
||||
def shell(args, env=None, cwd=None):
|
||||
print('+ ' + ' '.join(args))
|
||||
args = ['cmd', '/E:ON', '/V:ON', '/C'] + args
|
||||
@@ -77,10 +106,21 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
|
||||
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
|
||||
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
|
||||
|
||||
python_configurations = get_python_configurations(build_selector)
|
||||
if IS_RUNNING_ON_TRAVIS:
|
||||
# instal nuget as best way for provide python
|
||||
shell(["choco", "install", "nuget.commandline"])
|
||||
# get pip fo this installation which not have.
|
||||
get_pip_url = 'https://bootstrap.pypa.io/get-pip.py'
|
||||
get_pip_script = 'C:\\get-pip.py'
|
||||
shell(['curl', '-L', '-o', get_pip_script, get_pip_url])
|
||||
|
||||
python_configurations = get_python_configurations(build_selector)
|
||||
for config in python_configurations:
|
||||
config_python_path = get_python_path(config)
|
||||
if IS_RUNNING_ON_TRAVIS and config.nuget_version is not None and not os.path.exists(config_python_path):
|
||||
shell(["nuget", "install"] + get_nuget_args(config))
|
||||
if not os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe')):
|
||||
shell([os.path.join(config_python_path, 'python.exe'), get_pip_script ])
|
||||
|
||||
# check python & pip exist for this configuration
|
||||
assert os.path.exists(os.path.join(config_python_path, 'python.exe'))
|
||||
@@ -107,8 +147,12 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
|
||||
shell(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)\"'], env=env)
|
||||
|
||||
# prepare the Python environment
|
||||
shell(['python', '-m', 'pip', 'install', '--upgrade', 'pip'],
|
||||
if config.version == "3.4.x":
|
||||
shell(['python', '-m', 'pip', 'install', 'pip==19.1.1'],
|
||||
env=env)
|
||||
else:
|
||||
shell(['python', '-m', 'pip', 'install', '--upgrade', 'pip'],
|
||||
env=env)
|
||||
shell(['pip', 'install', '--upgrade', 'setuptools'], env=env)
|
||||
shell(['pip', 'install', 'wheel'], env=env)
|
||||
|
||||
@@ -121,18 +165,37 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
|
||||
shell(['pip', 'wheel', abs_project_dir, '-w', built_wheel_dir, '--no-deps'] + get_build_verbosity_extra_flags(build_verbosity), env=env)
|
||||
built_wheel = glob(built_wheel_dir+'/*.whl')[0]
|
||||
|
||||
# install the wheel
|
||||
shell(['pip', 'install', built_wheel + test_extras], env=env)
|
||||
|
||||
# test the wheel
|
||||
if test_requires:
|
||||
shell(['pip', 'install'] + test_requires, env=env)
|
||||
if test_command:
|
||||
# set up a virtual environment to install and test from, to make sure
|
||||
# there are no dependencies that were pulled in at build time.
|
||||
shell(['pip', 'install', 'virtualenv'], env=env)
|
||||
venv_dir = tempfile.mkdtemp()
|
||||
shell(['python', '-m', 'virtualenv', venv_dir], env=env)
|
||||
|
||||
virtualenv_env = env.copy()
|
||||
virtualenv_env['PATH'] = os.pathsep.join([
|
||||
os.path.join(venv_dir, 'Scripts'),
|
||||
virtualenv_env['PATH'],
|
||||
])
|
||||
|
||||
# check that we are using the Python from the virtual environment
|
||||
shell(['which', 'python'], env=virtualenv_env)
|
||||
|
||||
# install the wheel
|
||||
shell(['pip', 'install', built_wheel + test_extras], env=virtualenv_env)
|
||||
|
||||
# test the wheel
|
||||
if test_requires:
|
||||
shell(['pip', 'install'] + test_requires, env=virtualenv_env)
|
||||
|
||||
# run the tests from c:\, with an absolute path in the command
|
||||
# (this ensures that Python runs the tests against the installed wheel
|
||||
# and not the repo code)
|
||||
test_command_prepared = prepare_command(test_command, project=abs_project_dir)
|
||||
shell([test_command_prepared], cwd='c:\\', env=env)
|
||||
shell([test_command_prepared], cwd='c:\\', env=virtualenv_env)
|
||||
|
||||
# clean up
|
||||
shutil.rmtree(venv_dir)
|
||||
|
||||
# we're all done here; move it to output (remove if already exists)
|
||||
dst = os.path.join(output_dir, os.path.basename(built_wheel))
|
||||
|
||||
+2
-2
@@ -16,13 +16,13 @@ If your wheel didn't compile, check the list below for some debugging tips.
|
||||
|
||||
### Linux builds on Docker
|
||||
|
||||
Linux wheels are built in the [`manylinux` docker images](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 513](https://www.python.org/dev/peps/pep-0513/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
|
||||
Linux wheels are built in the [`manylinux` docker images](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 571](https://www.python.org/dev/peps/pep-0571/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
|
||||
|
||||
- Programs and libraries cannot be installed on the Travis CI Ubuntu host with `apt-get`, but can be installed inside of the Docker image using `yum` or manually. The same goes for environment variables that are potentially needed to customize the wheel building. `cibuildwheel` supports this by providing the `CIBW_ENVIRONMENT` and `CIBW_BEFORE_BUILD` options to setup the build environment inside the running Docker image. See [the options docs](options.md#build-environment) for details on these options.
|
||||
|
||||
- The project directory is mounted in the running Docker instance as `/project`, the output directory for the wheels as `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system. Note that this is not available on CircleCI due to their Docker policies.
|
||||
|
||||
- Alternative dockers images can be specified with the `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE` options to allow for a custom, preconfigured build environment for the Linux builds. See [options](options.md#manylinux-image) for more details.
|
||||
- Alternative dockers images can be specified with the `CIBW_MANYLINUX_X86_64_IMAGE` and `CIBW_MANYLINUX_I686_IMAGE` options to allow for a custom, preconfigured build environment for the Linux builds. See [options](options.md#manylinux-image) for more details.
|
||||
|
||||
### Building packages with optional C extensions
|
||||
|
||||
|
||||
+16
-9
@@ -59,17 +59,19 @@ For `linux` you need Docker running, on Mac or Linux. For `macos`, you need a Ma
|
||||
|
||||
> Choose the Python versions to build
|
||||
|
||||
Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux1_x86_64` or `cp34-macosx_10_6_intel` - you can list specific ones to build and `cibuildwheel` will only build those, and/or list ones to skip and `cibuildwheel` won't try to build them.
|
||||
Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux_x86_64` or `cp34-macosx_10_6_intel` - you can list specific ones to build and `cibuildwheel` will only build those, and/or list ones to skip and `cibuildwheel` won't try to build them.
|
||||
|
||||
When both options are specified, both conditions are applied and only builds with a tag that matches `CIBW_BUILD` and does not match `CIBW_SKIP` will be built.
|
||||
|
||||
The format is `python_tag-platform_tag`. The tags are as defined in [PEP 0425](https://www.python.org/dev/peps/pep-0425/#details).
|
||||
The format is `python_tag-platform_tag`. The tags are similar but not identical to the ones defined in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details).
|
||||
|
||||
Python tags look like `cp27` `cp34` `cp35` `cp36` `cp37`
|
||||
|
||||
Platform tags look like `macosx_10_6_intel` `manylinux1_x86_64` `manylinux1_i686` `win32` `win_amd64`
|
||||
Platform tags look like `macosx_10_6_intel` `manylinux_x86_64` `manylinux_i686` `win32` `win_amd64`
|
||||
|
||||
You can also use shell-style globbing syntax (as per `fnmatch`)
|
||||
You can also use shell-style globbing syntax (as per `fnmatch`).
|
||||
|
||||
The list of supported and currently selected build identifiers can be retrieved by passing the `--print-build-identifiers` flag to `cibuildwheel`.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -80,7 +82,7 @@ Examples:
|
||||
- Skip Python 2.7 on 32-bit Windows: `CIBW_SKIP=cp27-win32`
|
||||
- Skip Python 3.4 and Python 3.5: `CIBW_SKIP=cp34-* cp35-*`
|
||||
- Skip Python 3.6 on Linux: `CIBW_SKIP=cp36-manylinux*`
|
||||
- Only build on Python 3 and skip 32-bit builds: `CIBW_BUILD=cp3?-*` and `CIBW_SKIP=*-win32 *-manylinux1_i686`
|
||||
- Only build on Python 3 and skip 32-bit builds: `CIBW_BUILD=cp3?-*` and `CIBW_SKIP=*-win32 *-manylinux_i686`
|
||||
|
||||
## Build environment
|
||||
|
||||
@@ -119,13 +121,18 @@ Example: `yum install -y libffi-dev && pip install .`
|
||||
Platform-specific variants also available:
|
||||
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX`
|
||||
|
||||
### CIBW_MANYLINUX1_X86_64_IMAGE, CIBW_MANYLINUX1_I686_IMAGE {: #manylinux-image}
|
||||
> Specify alternative manylinux1 x86_64 docker images
|
||||
### CIBW_MANYLINUX_X86_64_IMAGE, CIBW_MANYLINUX_I686_IMAGE {: #manylinux-image}
|
||||
> Specify alternative manylinux docker images
|
||||
|
||||
An alternative docker image to be used for building [`manylinux1`](https://github.com/pypa/manylinux) wheels. `cibuildwheel` will then pull these instead of the official images, [`quay.io/pypa/manylinux1_x86_64`](https://quay.io/pypa/manylinux1_i686) and [`quay.io/pypa/manylinux1_i686`](https://quay.io/pypa/manylinux1_i686).
|
||||
An alternative Docker image to be used for building [`manylinux`](https://github.com/pypa/manylinux) wheels. `cibuildwheel` will then pull these instead of the default images, [`quay.io/pypa/manylinux2010_x86_64`](https://quay.io/pypa/manylinux2010_x86_64) and [`quay.io/pypa/manylinux2010_i686`](https://quay.io/pypa/manylinux2010_i686).
|
||||
|
||||
Beware to specify a valid docker image that can be used the same as the official, default docker images: all necessary Python and pip versions need to be present in `/opt/python/`, and the `auditwheel` tool needs to be present for `cibuildwheel` to work. Apart from that, the architecture and relevant shared system libraries need to be manylinux1-compatible in order to produce valid `manylinux1` wheels (see https://github.com/pypa/manylinux and [PEP 513](https://www.python.org/dev/peps/pep-0513/) for more details).
|
||||
The value of this option can either be set to `manylinux1` or `manylinux2010` to use the [official `manylinux` images](https://github.com/pypa/manylinux), or any other valid Docker image name.
|
||||
|
||||
Beware to specify a valid Docker image that can be used in the same way as the official, default Docker images: all necessary Python and pip versions need to be present in `/opt/python/`, and the `auditwheel` tool needs to be present for `cibuildwheel` to work. Apart from that, the architecture and relevant shared system libraries need to be manylinux1- or manylinux2010-compatible in order to produce valid `manylinux1`/`manylinux2010` wheels (see https://github.com/pypa/manylinux, [PEP 513](https://www.python.org/dev/peps/pep-0513/), and [PEP 571](https://www.python.org/dev/peps/pep-0571/) for more details).
|
||||
|
||||
Note that `auditwheel` detects the version of the `manylinux` standard in the Docker image through the `AUDITWHEEL_PLAT` environment variable, as `cibuildwheel` has no way of detecting the correct `--plat` command line argument to pass to `auditwheel` for a custom image. If a Docker image does not correctly set this `AUDITWHEEL_PLAT` environment variable, the `CIBW_ENVIRONMENT` option can be used to do so (e.g., `CIBW_ENVIRONMENT="manylinux2010_$(uname -m)"`).
|
||||
|
||||
Example: `manylinux1`
|
||||
Example: `dockcross/manylinux-x64`
|
||||
Example: `dockcross/manylinux-x86`
|
||||
|
||||
|
||||
@@ -73,6 +73,18 @@ script:
|
||||
- cibuildwheel --output-dir wheelhouse
|
||||
```
|
||||
|
||||
To build on Windows too, add this matrix entry:
|
||||
```yaml
|
||||
- os: windows
|
||||
language: shell
|
||||
before_install:
|
||||
- choco install python3 --version 3.6.8 --no-progress -y
|
||||
env:
|
||||
- PATH=/c/Python36:/c/Python36/Scripts:$PATH
|
||||
```
|
||||
|
||||
Note that building Windows Python 2.7 wheels on Travis is unsupported.
|
||||
|
||||
Commit this file, enable building of your repo on Travis CI, and push.
|
||||
|
||||
Then setup a deployment method by following the [Travis CI deployment docs](https://docs.travis-ci.com/user/deployment/), or see [Delivering to PyPI](deliver-to-pypi.md). For more info on `.travis.yml`, check out the [docs](https://docs.travis-ci.com/).
|
||||
|
||||
@@ -17,6 +17,10 @@ def test():
|
||||
def test_build_identifiers():
|
||||
# check that the number of expected wheels matches the number of build
|
||||
# identifiers
|
||||
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||
# after adding CIBW_MANYLINUX_IMAGE to support manylinux2010, there
|
||||
# can be multiple wheels for each wheel, though, so we need to limit
|
||||
# the expected wheels
|
||||
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
|
||||
if not '-manylinux' in w or '-manylinux1' in w]
|
||||
build_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir)
|
||||
assert len(expected_wheels) == len(build_identifiers)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import os, subprocess
|
||||
import pytest
|
||||
import utils
|
||||
|
||||
def test():
|
||||
@@ -35,3 +36,16 @@ def test_extras_require():
|
||||
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||
actual_wheels = os.listdir('wheelhouse')
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
|
||||
def test_failing_test():
|
||||
'''Ensure a failing test causes cibuildwheel to error out and exit'''
|
||||
project_dir = os.path.dirname(__file__)
|
||||
|
||||
with pytest.raises(subprocess.CalledProcessError):
|
||||
utils.cibuildwheel_run(project_dir, add_env={
|
||||
'CIBW_TEST_COMMAND': 'false',
|
||||
})
|
||||
|
||||
assert len(os.listdir('wheelhouse'))
|
||||
|
||||
|
||||
@@ -5,14 +5,17 @@ def test():
|
||||
project_dir = os.path.dirname(__file__)
|
||||
|
||||
if utils.platform != 'linux':
|
||||
pytest.skip('the docker test is only relevant to the linux build')
|
||||
pytest.skip('the test is only relevant to the linux build')
|
||||
|
||||
utils.cibuildwheel_run(project_dir, add_env={
|
||||
'CIBW_MANYLINUX1_X86_64_IMAGE': 'dockcross/manylinux-x64',
|
||||
'CIBW_MANYLINUX1_I686_IMAGE': 'dockcross/manylinux-x86',
|
||||
'CIBW_MANYLINUX_X86_64_IMAGE': 'dockcross/manylinux2010-x64',
|
||||
'CIBW_MANYLINUX_I686_IMAGE': 'dockcross/manylinux1-x86',
|
||||
'CIBW_BEFORE_BUILD': '/opt/python/cp36-cp36m/bin/pip install -U auditwheel', # Currently necessary on dockcross images to get auditwheel 2.1 supporting AUDITWHEEL_PLAT
|
||||
'CIBW_ENVIRONMENT': 'AUDITWHEEL_PLAT=`if [ $(uname -i) == "x86_64" ]; then echo "manylinux2010_x86_64"; else echo "manylinux1_i686"; fi`',
|
||||
})
|
||||
|
||||
# also check that we got the right wheels built
|
||||
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
|
||||
if '-manylinux2010_i686' not in w]
|
||||
actual_wheels = os.listdir('wheelhouse')
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import os, pytest
|
||||
import utils
|
||||
|
||||
def test():
|
||||
project_dir = os.path.dirname(__file__)
|
||||
|
||||
if utils.platform != 'linux':
|
||||
pytest.skip('the docker test is only relevant to the linux build')
|
||||
|
||||
# build the wheels
|
||||
# CFLAGS environment veriable is ecessary to fail on 'malloc_info' (on manylinux1) during compilation/linking,
|
||||
# rather than when dynamically loading the Python
|
||||
utils.cibuildwheel_run(project_dir, add_env={
|
||||
'CIBW_ENVIRONMENT': 'CFLAGS="$CFLAGS -Werror=implicit-function-declaration"',
|
||||
})
|
||||
|
||||
# also check that we got the right wheels
|
||||
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
|
||||
if not '-manylinux' in w or '-manylinux2010' in w]
|
||||
actual_wheels = os.listdir('wheelhouse')
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
@@ -0,0 +1,7 @@
|
||||
from setuptools import setup, Extension
|
||||
|
||||
setup(
|
||||
name="spam",
|
||||
ext_modules=[Extension('spam', sources=['spam.c'])],
|
||||
version="0.1.0",
|
||||
)
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <Python.h>
|
||||
#if defined(__linux__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
spam_system(PyObject *self, PyObject *args)
|
||||
{
|
||||
const char *command;
|
||||
int sts = 0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s", &command))
|
||||
return NULL;
|
||||
|
||||
#if defined(__linux__)
|
||||
sts = malloc_info(0, stdout);
|
||||
#endif
|
||||
if (sts == 0) {
|
||||
sts = system(command);
|
||||
}
|
||||
return PyLong_FromLong(sts);
|
||||
}
|
||||
|
||||
/* Module initialization */
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
|
||||
#define MOD_DEF(m, name, doc, methods, module_state_size) \
|
||||
static struct PyModuleDef moduledef = { \
|
||||
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
|
||||
m = PyModule_Create(&moduledef);
|
||||
#define MOD_RETURN(m) return m;
|
||||
#else
|
||||
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
|
||||
#define MOD_DEF(m, name, doc, methods, module_state_size) \
|
||||
m = Py_InitModule3(name, methods, doc);
|
||||
#define MOD_RETURN(m) return;
|
||||
#endif
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
{"system", (PyCFunction)spam_system, METH_VARARGS,
|
||||
"Execute a shell command."},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
MOD_INIT(spam)
|
||||
{
|
||||
PyObject* m;
|
||||
|
||||
MOD_DEF(m,
|
||||
"spam",
|
||||
"Example module",
|
||||
module_methods,
|
||||
-1)
|
||||
|
||||
MOD_RETURN(m)
|
||||
}
|
||||
+18
-2
@@ -6,7 +6,8 @@ This file is added to the PYTHONPATH in the test runner at bin/run_test.py.
|
||||
|
||||
import subprocess, sys, os
|
||||
|
||||
IS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache')
|
||||
IS_WINDOWS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache')
|
||||
IS_WINDOWS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows'
|
||||
|
||||
|
||||
def cibuildwheel_get_build_identifiers(project_path, env=None):
|
||||
@@ -54,12 +55,24 @@ def expected_wheels(package_name, package_version):
|
||||
'{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp34-cp34m-manylinux2010_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp35-cp35m-manylinux2010_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl',
|
||||
'{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl',
|
||||
'{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl',
|
||||
'{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl',
|
||||
'{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl',
|
||||
'{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl',
|
||||
'{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl',
|
||||
'{package_name}-{package_version}-cp27-cp27m-manylinux2010_i686.whl',
|
||||
'{package_name}-{package_version}-cp27-cp27mu-manylinux2010_i686.whl',
|
||||
'{package_name}-{package_version}-cp34-cp34m-manylinux2010_i686.whl',
|
||||
'{package_name}-{package_version}-cp35-cp35m-manylinux2010_i686.whl',
|
||||
'{package_name}-{package_version}-cp36-cp36m-manylinux2010_i686.whl',
|
||||
'{package_name}-{package_version}-cp37-cp37m-manylinux2010_i686.whl',
|
||||
]
|
||||
elif platform == 'windows':
|
||||
templates = [
|
||||
@@ -85,9 +98,12 @@ def expected_wheels(package_name, package_version):
|
||||
else:
|
||||
raise Exception('unsupported platform')
|
||||
|
||||
if IS_RUNNING_ON_AZURE:
|
||||
if IS_WINDOWS_RUNNING_ON_AZURE:
|
||||
# Python 3.4 isn't supported on Azure.
|
||||
templates = [t for t in templates if '-cp34-' not in t]
|
||||
if IS_WINDOWS_RUNNING_ON_TRAVIS:
|
||||
# Python 2.7 and 3.4 isn't supported on Travis.
|
||||
templates = [t for t in templates if '-cp27-' not in t and '-cp34-' not in t]
|
||||
|
||||
return [filename.format(package_name=package_name, package_version=package_version)
|
||||
for filename in templates]
|
||||
|
||||
Reference in New Issue
Block a user