diff --git a/.travis.yml b/.travis.yml index a4cb2b79..8ddfbf0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ matrix: # Linux Python 3 - sudo: required language: python - python: 3.4 + python: 3.5 services: docker env: PYTHON=python diff --git a/README.md b/README.md index ea6b1128..22811bc8 100644 --- a/README.md +++ b/README.md @@ -15,17 +15,15 @@ Python wheels are great. Building them across **Mac, Linux, Windows**, on **mult What does it do? ---------------- -| | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit | -|---|---|---|---|---|---| -| Python 2.7 | ✅ | ✅ | ✅ | ✅² | ✅² | -| Python 3.4 | ✅ | ✅ | ✅ | ✅¹²| ✅¹²| -| Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ | -| Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ | -| Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ | +| | macOS 10.6+ intel | macOS 10.9+ x86_64 | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit | +|---|---|---|---|---|---|---| +| Python 2.7 | ✅ | | ✅ | ✅ | ✅¹ | ✅¹ | +| Python 3.5 | ✅ | | ✅ | ✅ | ✅ | ✅ | +| Python 3.6 | ✅ | | ✅ | ✅ | ✅ | ✅ | +| Python 3.7 | ✅ | | ✅ | ✅ | ✅ | ✅ | +| Python 3.8 | | ✅ | ✅ | ✅ | ✅ | ✅ | -> ¹ Not supported on Azure Pipelines -> -> ² Not supported on Travis +> ¹ 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) @@ -91,7 +89,7 @@ For more information, including how to build on Appveyor, Azure, CircleCI, check Working examples ---------------- -Here are some repos that use cibuildwheel. +Here are some repos that use cibuildwheel. - [pyinstrument_cext](https://github.com/joerick/pyinstrument_cext) - [websockets](https://github.com/aaugustin/websockets) @@ -109,7 +107,7 @@ Here are some repos that use cibuildwheel. Legal note ---------- -Since `cibuildwheel` runs the wheel through delocate or auditwheel, it might automatically bundle dynamically linked libraries from the build machine. +Since `cibuildwheel` runs the wheel through delocate or auditwheel, it might automatically bundle dynamically linked libraries from the build machine. It helps ensure that the library can run without any dependencies outside of the pip toolchain. @@ -141,7 +139,7 @@ _26 May 2019_ - ✨ Add support for building on Azure pipelines! This lets you build all Linux, Mac and Windows wheels on one service, so it promises to be the - easiest to set up! Check out the quickstart in the docs, or + easiest to set up! Check out the quickstart in the docs, or [cibuildwheel-azure-example](https://github.com/joerick/cibuildwheel-azure-example) for an example project. (#126, #132) - 🛠 Internal change - the end-to-end test projects format was updated, so we @@ -281,7 +279,7 @@ _11 June 2017_ _13 April 2017_ -- ✨ Added `CIBW_SKIP` option, letting users explicitly skip a build +- ✨ Added `CIBW_SKIP` option, letting users explicitly skip a build - ✨ Added `CIBW_BEFORE_BUILD` option, letting users run a shell command before the build starts ### 0.1.3 @@ -306,7 +304,7 @@ Maintainers Credits ------- -`cibuildwheel` stands on the shoulders of giants. +`cibuildwheel` stands on the shoulders of giants. - ⭐️ @matthew-brett for [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild) and [matthew-brett/delocate](http://github.com/matthew-brett/delocate) - @PyPA for the manylinux Docker images [pypa/manylinux](https://github.com/pypa/manylinux) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5a9e501c..72ff2b85 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,31 +1,30 @@ jobs: - job: linux - pool: {vmImage: 'Ubuntu-16.04'} - steps: + pool: {vmImage: 'Ubuntu-18.04'} + steps: - task: UsePythonVersion@0 + inputs: + versionSpec: '3.8' - bash: | python -m pip install -r requirements-dev.txt python ./bin/run_tests.py - job: macos pool: {vmImage: 'macOS-10.13'} - steps: + steps: - task: UsePythonVersion@0 + inputs: + versionSpec: '3.8' - bash: | python -m pip install -r requirements-dev.txt python ./bin/run_tests.py - job: windows pool: {vmImage: 'vs2017-win2016'} - steps: - - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.6', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.6', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.7', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.7', architecture: x64}} + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.8' - script: choco install vcpython27 -f -y displayName: Install Visual C++ for Python 2.7 - bash: | diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 233f1f02..ad666f45 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -14,16 +14,16 @@ def get_python_configurations(build_selector): python_configurations = [ 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='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'), 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'), + PythonConfiguration(identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'), ] # skip builds as required diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 7378f142..25bf78a7 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -15,10 +15,10 @@ 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.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.5/python-3.7.5-macosx10.6.pkg'), + PythonConfiguration(version='3.8', identifier='cp38-macosx_10_9_x86_64', url='https://www.python.org/ftp/python/3.8.0/python-3.8.0-macosx10.9.pkg'), ] # skip builds as required @@ -58,7 +58,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef # install call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/']) # patch open ssl - if config.version in ('3.4', '3.5'): + if config.version == '3.5': call(['curl', '-fsSLo', '/tmp/python-patch.tar.gz', 'https://github.com/mayeut/patch-macos-python-openssl/releases/download/v1.0.2t/patch-macos-python-%s-openssl-v1.0.2t.tar.gz' % config.version]) call(['sudo', 'tar', '-C', '/Library/Frameworks/Python.framework/Versions/%s/' % config.version, '-xmf', '/tmp/python-patch.tar.gz']) diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index da929bcc..d37d7509 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -8,89 +8,71 @@ try: except ImportError: from pipes import quote as shlex_quote +try: + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen + 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: - # We can't hard-code the paths because on Azure, we don't know which - # bugfix release of Python we are getting so we need to check which - # ones exist. We just use the first one that is found since there should - # only be one. - path_pattern = 'C:\\hostedtoolcache\\windows\\Python\\{version}\\{arch}'.format( - version=config.version.replace('x', '*'), - arch='x86' if config.arch == '32' else 'x64' - ) - try: - 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] - return 'C:\\Python{major}{minor}{arch}'.format( - major=major, - minor=minor, - arch = '-x64' if config.arch == '64' else '' - ) + nuget_args = get_nuget_args(config) + return os.path.join(nuget_args[-1], nuget_args[0] + "." + config.version, "tools") 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"] + return [python_name, "-Version", configuration.version, "-OutputDirectory", "C:/python"] def get_python_configurations(build_selector): - PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path', "nuget_version"]) + PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier']) python_configurations = [ - 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") + PythonConfiguration(version='2.7.17', arch="32", identifier='cp27-win32'), + PythonConfiguration(version='2.7.17', arch="64", identifier='cp27-win_amd64'), + PythonConfiguration(version='3.5.4', arch="32", identifier='cp35-win32'), + PythonConfiguration(version='3.5.4', arch="64", identifier='cp35-win_amd64'), + PythonConfiguration(version='3.6.8', arch="32", identifier='cp36-win32'), + PythonConfiguration(version='3.6.8', arch="64", identifier='cp36-win_amd64'), + PythonConfiguration(version='3.7.5', arch="32", identifier='cp37-win32'), + PythonConfiguration(version='3.7.5', arch="64", identifier='cp37-win_amd64'), + PythonConfiguration(version='3.8.0', arch="32", identifier='cp38-win32'), + PythonConfiguration(version='3.8.0', arch="64", identifier='cp38-win_amd64'), ] - 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'] + python_configurations = [c for c in python_configurations if not c.version.startswith('2.7.')] # skip builds as required python_configurations = [c for c in python_configurations if build_selector(c.identifier)] - + return python_configurations def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment): + def simple_shell(args, env=None, cwd=None): + print('+ ' + ' '.join(args)) + args = ['cmd', '/E:ON', '/V:ON', '/C'] + args + return subprocess.check_call(' '.join(args), env=env, cwd=cwd) + def download(url, dest): + print('+ Download ' + url + ' to ' + dest) + response = urlopen(url) + try: + with open(dest, 'wb') as file: + file.write(response.read()) + finally: + response.close() 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 - return subprocess.check_call(' '.join(args), env=env, cwd=cwd) + shell = simple_shell else: run_with_env = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'appveyor_run_with_env.cmd')) @@ -106,21 +88,19 @@ 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') - 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]) + # install nuget as best way to provide python + nuget = 'C:\\nuget.exe' + download('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', nuget) + # get pip fo this installation which not have. + get_pip_script = 'C:\\get-pip.py' + download('https://bootstrap.pypa.io/get-pip.py', get_pip_script) 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 ]) + simple_shell([nuget, "install"] + get_nuget_args(config)) + if not os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe')): + simple_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')) @@ -147,12 +127,7 @@ 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 - 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(['python', '-m', 'pip', 'install', '--upgrade', 'pip'], env=env) shell(['pip', 'install', '--upgrade', 'setuptools'], env=env) shell(['pip', 'install', 'wheel'], env=env) diff --git a/docs/options.md b/docs/options.md index 6e95755a..7f377fe8 100644 --- a/docs/options.md +++ b/docs/options.md @@ -59,15 +59,15 @@ 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-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. +Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux_x86_64` or `cp35-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 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` +Python tags look like `cp27` `cp34` `cp35` `cp36` `cp37` `cp38` -Platform tags look like `macosx_10_6_intel` `manylinux_x86_64` `manylinux_i686` `win32` `win_amd64` +Platform tags look like `macosx_10_6_intel` `macosx_10_9_x86_64` `manylinux_x86_64` `manylinux_i686` `win32` `win_amd64` You can also use shell-style globbing syntax (as per `fnmatch`). @@ -77,10 +77,11 @@ Examples: - Only build on Python 3.6: `CIBW_BUILD=cp36-*` - Skip building on Python 2.7 on the Mac: `CIBW_SKIP=cp27-macosx_10_6_intel` +- Skip building on Python 3.8 on the Mac: `CIBW_SKIP=cp38-macosx_10_9_x86_64` - Skip building on Python 2.7 on all platforms: `CIBW_SKIP=cp27-*` - Skip Python 2.7 on Windows: `CIBW_SKIP=cp27-win*` - 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 2.7 and Python 3.5: `CIBW_SKIP=cp27-* 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 *-manylinux_i686` @@ -95,10 +96,10 @@ You must set this variable to pass variables to Linux builds (since they execute You can use `$PATH` syntax to insert other variables, or the `$(pwd)` syntax to insert the output of other shell commands. -Example: `CFLAGS="-g -Wall" CXXFLAGS="-Wall"` -Example: `PATH=$PATH:/usr/local/bin` -Example: `BUILD_TIME="$(date)"` -Example: `PIP_EXTRA_INDEX_URL="https://pypi.myorg.com/simple"` +Example: `CFLAGS="-g -Wall" CXXFLAGS="-Wall"`\ +Example: `PATH=$PATH:/usr/local/bin`\ +Example: `BUILD_TIME="$(date)"`\ +Example: `PIP_EXTRA_INDEX_URL="https://pypi.myorg.com/simple"` Platform-specific variants also available: `CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX` @@ -114,11 +115,11 @@ If dependencies are required to build your wheel (for example if you include a h The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. `{project}` can be used as a placeholder for the absolute path to the project's root. -Example: `pip install .` -Example: `pip install pybind11` +Example: `pip install .`\ +Example: `pip install pybind11`\ Example: `yum install -y libffi-dev && pip install .` -Platform-specific variants also available: +Platform-specific variants also available:\ `CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX` ### CIBW_MANYLINUX_X86_64_IMAGE, CIBW_MANYLINUX_I686_IMAGE {: #manylinux-image} @@ -132,8 +133,8 @@ Beware to specify a valid Docker image that can be used in the same way as the o 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: `manylinux1`\ +Example: `dockcross/manylinux-x64`\ Example: `dockcross/manylinux-x86` ## Testing @@ -155,7 +156,7 @@ Platform-specific variants also available: Space-separated list of dependencies required for running the tests. -Example: `pytest` +Example: `pytest`\ Example: `nose==1.3.7 moto==0.4.31` Platform-specific variants also available: diff --git a/docs/setup.md b/docs/setup.md index 4cf1c538..7a231588 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -28,14 +28,7 @@ jobs: - job: windows pool: {vmImage: 'vs2017-win2016'} steps: - - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.6', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.6', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.7', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.7', architecture: x64}} + - task: UsePythonVersion@0 - script: choco install vcpython27 -f -y displayName: Install Visual C++ for Python 2.7 - bash: | @@ -73,7 +66,7 @@ script: - cibuildwheel --output-dir wheelhouse ``` -To build on Windows too, add this matrix entry: +To build on Windows too, add this matrix entry: ```yaml - os: windows language: shell @@ -90,7 +83,7 @@ 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/). ## CircleCI [linux/mac] - + To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo, > .circleci/config.yml diff --git a/setup.py b/setup.py index 5f715538..9236eb9b 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,8 @@ setup( package_data={ 'cibuildwheel': ['resources/*'], }, + # Supported python versions + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', keywords='ci wheel packaging pypi travis appveyor macos linux windows', classifiers=[ 'Intended Audience :: Developers', diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py index 98333fd2..764874a2 100644 --- a/test/04_build_skip/cibuildwheel_test.py +++ b/test/04_build_skip/cibuildwheel_test.py @@ -7,11 +7,11 @@ def test(): # build the wheels utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_BUILD': 'cp3?-*', - 'CIBW_SKIP': 'cp34-*', + 'CIBW_SKIP': 'cp37-*', }) - # check that we got the right wheels. There should be no 2.7 or 3.4. + # check that we got the right wheels. There should be no 2.7 or 3.7. expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') - if ('-cp3' in w) and ('-cp34' not in w)] + if ('-cp3' in w) and ('-cp37' not in w)] actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/shared/utils.py b/test/shared/utils.py index 78f09050..d4e9c9c6 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -26,14 +26,14 @@ def cibuildwheel_get_build_identifiers(project_path, env=None): def cibuildwheel_run(project_path, env=None, add_env=None): ''' - Runs cibuildwheel as a subprocess, building the project at project_path. - + Runs cibuildwheel as a subprocess, building the project at project_path. + Uses the current Python interpreter. Configure settings using env. ''' if env is None: env = os.environ.copy() - + if add_env is not None: env.update(add_env) @@ -51,60 +51,57 @@ def expected_wheels(package_name, package_version): templates = [ '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux1_x86_64.whl', '{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}-cp38-cp38-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}-cp38-cp38-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}-cp38-cp38-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', + '{package_name}-{package_version}-cp38-cp38-manylinux2010_i686.whl', ] elif platform == 'windows': templates = [ '{package_name}-{package_version}-cp27-cp27m-win32.whl', - '{package_name}-{package_version}-cp34-cp34m-win32.whl', '{package_name}-{package_version}-cp35-cp35m-win32.whl', '{package_name}-{package_version}-cp36-cp36m-win32.whl', '{package_name}-{package_version}-cp37-cp37m-win32.whl', + '{package_name}-{package_version}-cp38-cp38-win32.whl', '{package_name}-{package_version}-cp27-cp27m-win_amd64.whl', - '{package_name}-{package_version}-cp34-cp34m-win_amd64.whl', '{package_name}-{package_version}-cp35-cp35m-win_amd64.whl', '{package_name}-{package_version}-cp36-cp36m-win_amd64.whl', '{package_name}-{package_version}-cp37-cp37m-win_amd64.whl', + '{package_name}-{package_version}-cp38-cp38-win_amd64.whl', ] elif platform == 'macos': templates = [ '{package_name}-{package_version}-cp27-cp27m-macosx_10_6_intel.whl', - '{package_name}-{package_version}-cp34-cp34m-macosx_10_6_intel.whl', '{package_name}-{package_version}-cp35-cp35m-macosx_10_6_intel.whl', '{package_name}-{package_version}-cp36-cp36m-macosx_10_6_intel.whl', '{package_name}-{package_version}-cp37-cp37m-macosx_10_6_intel.whl', + '{package_name}-{package_version}-cp38-cp38-macosx_10_9_x86_64.whl', ] else: raise Exception('unsupported platform') - - 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] - + # Python 2.7 isn't supported on Travis. + templates = [t for t in templates if '-cp27-' not in t] + return [filename.format(package_name=package_name, package_version=package_version) for filename in templates] diff --git a/unit_test/environment_test.py b/unit_test/environment_test.py index 0f0f385e..1bc95374 100644 --- a/unit_test/environment_test.py +++ b/unit_test/environment_test.py @@ -1,3 +1,4 @@ +import os from cibuildwheel.environment import parse_environment @@ -37,12 +38,15 @@ def test_inheritance(): def test_shell_eval(): environment_recipe = parse_environment('VAR="$(echo "a test" string)"') + env_copy = os.environ.copy() + env_copy.pop('VAR', None) + environment_dict = environment_recipe.as_dictionary( - prev_environment={} + prev_environment=env_copy ) environment_cmds = environment_recipe.as_shell_commands() - assert environment_dict == {'VAR': 'a test string'} + assert environment_dict['VAR'] == 'a test string' assert environment_cmds == ['export VAR="$(echo "a test" string)"'] def test_shell_eval_and_env():