Merge branch 'master' into returncode

This commit is contained in:
Gertjan van den Burg
2019-11-05 17:09:17 +00:00
15 changed files with 361 additions and 175 deletions
+9 -3
View File
@@ -12,7 +12,7 @@ matrix:
# Linux Python 3
- sudo: required
language: python
python: 3.4
python: 3.5
services: docker
env: PYTHON=python
@@ -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
+73 -59
View File
@@ -12,15 +12,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
- 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)
@@ -29,12 +29,12 @@ 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 | ✅ | ✅ | |
| Travis CI | ✅ | ✅ | |
| AppVeyor | | | ✅ |
| CircleCI | ✅ | ✅ | |
@@ -56,7 +56,7 @@ Usage
jobs:
- job: linux
pool: {vmImage: 'Ubuntu-16.04'}
steps:
steps:
- task: UsePythonVersion@0
- bash: |
python -m pip install --upgrade pip
@@ -66,7 +66,7 @@ jobs:
inputs: {pathtoPublish: 'wheelhouse'}
- job: macos
pool: {vmImage: 'macOS-10.13'}
steps:
steps:
- task: UsePythonVersion@0
- bash: |
python -m pip install --upgrade pip
@@ -76,15 +76,8 @@ jobs:
inputs: {pathtoPublish: 'wheelhouse'}
- 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
- script: choco install vcpython27 -f -y
displayName: Install Visual C++ for Python 2.7
- bash: |
@@ -101,13 +94,14 @@ jobs:
<summary><b>Travis CI</b>
<img width="16" src="https://unpkg.com/simple-icons@latest/icons/apple.svg" />
<img width="16" src="https://unpkg.com/simple-icons@latest/icons/linux.svg" />
<img width="16" src="https://unpkg.com/simple-icons@latest/icons/windows.svg" />
</summary>
- To build Linux and Mac wheels on Travis CI, create a `.travis.yml` file in your repo.
```
```yaml
language: python
matrix:
include:
- sudo: required
@@ -123,6 +117,18 @@ jobs:
- 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.
Then setup a deployment method by following the [Travis CI deployment docs](https://docs.travis-ci.com/user/deployment/), or see [Delivering to PyPI](#delivering-to-pypi) below.
</details>
@@ -132,7 +138,7 @@ jobs:
<img width="16" src="https://unpkg.com/simple-icons@latest/icons/apple.svg" />
<img width="16" src="https://unpkg.com/simple-icons@latest/icons/linux.svg" />
</summary>
- To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo,
```
@@ -198,14 +204,14 @@ jobs:
- path: "wheelhouse\\*.whl"
name: Wheels
```
AppVeyor will store the built wheels for you - you can access them from the project console. Alternatively, you may want to store them in the same place as the Travis CI build. See [AppVeyor deployment docs](https://www.appveyor.com/docs/deployment/) for more info, or see [Delivering to PyPI](#delivering-to-pypi) below.
</details>
- Commit those files, enable building of your repo on Travis CI and AppVeyor, and push.
All being well, you should get wheels delivered to you in a few minutes.
All being well, you should get wheels delivered to you in a few minutes.
> ⚠️ Got an error? Check the [checklist](#it-didnt-work) below.
@@ -221,8 +227,8 @@ All being well, you should get wheels delivered to you in a few minutes.
| **Build parameters** | `CIBW_BUILD_VERBOSITY` | Increase or decrease the output of `pip wheel` |
| **Build environment** | `CIBW_ENVIRONMENT` | Set environment variables needed during the build |
| | `CIBW_BEFORE_BUILD` | Execute a shell command preparing each wheel's build |
| | `CIBW_MANYLINUX1_X86_64_IMAGE` | Specify an alternative manylinx1 x86_64 docker image |
| | `CIBW_MANYLINUX1_I686_IMAGE` | Specify an alternative manylinux1 i686 docker image |
| | `CIBW_MANYLINUX_X86_64_IMAGE` | Specify an alternative manylinux x86_64 docker image |
| | `CIBW_MANYLINUX_I686_IMAGE` | Specify an alternative manylinux i686 docker image |
| **Tests** | `CIBW_TEST_COMMAND` | Execute a shell command to test all built wheels |
| | `CIBW_TEST_REQUIRES` | Install Python dependencies before running the tests |
| | `CIBW_TEST_EXTRAS` | Install Python dependencies before running the tests using ``extras_require``|
@@ -231,10 +237,10 @@ A more detailed description of the options, the allowed values, and some example
### Linux builds on Docker
Linux wheels are built in the [`manylinux1` 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 [below](#options) 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 [below](#options) 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 [below](#options) for more details.
Options
@@ -244,7 +250,7 @@ Options
usage: cibuildwheel [-h] [--platform {auto,linux,macos,windows}]
[--output-dir OUTPUT_DIR] [--print-build-identifiers]
[project_dir]
Build wheels for all the platforms.
positional arguments:
@@ -291,27 +297,30 @@ For `linux` you need Docker running, on Mac or Linux. For `macos`, you need a Ma
Optional.
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 `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 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`
Python tags look like `cp27` `cp35` `cp36` `cp37` `cp38`
Platform tags look like `macosx_10_6_intel` `manylinux1_x86_64` `manylinux1_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`)
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:
- 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 *-manylinux1_i686`
- Only build on Python 3 and skip 32-bit builds: `CIBW_BUILD`:`cp3?-*` and `CIBW_SKIP`:`*-win32 *-manylinux_i686`
***
@@ -338,10 +347,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`
@@ -361,25 +370,30 @@ 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`
***
| Environment variables: `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE`
| Environment variables: `CIBW_MANYLINUX_X86_64_IMAGE` and `CIBW_MANYLINUX_I686_IMAGE`
| ---
Optional.
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.
Example: `dockcross/manylinux-x64`
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`
***
@@ -391,7 +405,7 @@ Optional.
Shell command to run tests after the build. The wheel will be installed automatically and available for import from the tests. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`.
On Linux and Mac, the command runs in a shell, so you can write things like `cmd1 && cmd2`.
On Linux and Mac, the command runs in a shell, so you can write things like `cmd1 && cmd2`.
Example: `nosetests {project}/tests`
@@ -407,7 +421,7 @@ Optional.
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:
@@ -458,13 +472,13 @@ After you've built your wheels, you'll probably want to deliver them to PyPI.
On your development machine, do the following...
```bash
# Clear out your 'dist' folder.
# Clear out your 'dist' folder.
rm -rf dist
# Make a source distribution
python setup.py sdist
# 🏃🏻
# Go and download your wheel files from wherever you put them. Put
# Go and download your wheel files from wherever you put them. Put
# them all into the 'dist' folder.
# Upload using 'twine' (you may need to 'pip install twine')
@@ -496,7 +510,7 @@ If your wheel didn't compile, check the list below for some debugging tips.
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)
@@ -514,7 +528,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.
@@ -546,7 +560,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
@@ -686,7 +700,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
@@ -728,7 +742,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)
+5 -12
View File
@@ -1,7 +1,7 @@
jobs:
- job: linux
pool: {vmImage: 'Ubuntu-16.04'}
steps:
pool: {vmImage: 'Ubuntu-18.04'}
steps:
- task: UsePythonVersion@0
- bash: |
python -m pip install -r requirements-dev.txt
@@ -9,7 +9,7 @@ jobs:
- job: macos
pool: {vmImage: 'macOS-10.13'}
steps:
steps:
- task: UsePythonVersion@0
- bash: |
python -m pip install -r requirements-dev.txt
@@ -17,15 +17,8 @@ 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}}
steps:
- task: UsePythonVersion@0
- script: choco install vcpython27 -f -y
displayName: Install Visual C++ for Python 2.7
- bash: |
+33 -3
View File
@@ -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('''
_ _ _ _ _ _ _
+28 -23
View File
@@ -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='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='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
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,11 +79,11 @@ 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)
if [ ! -z {test_command} ]; then
# Set up a virtual environment to install and test from, to make sure
@@ -100,7 +100,12 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
echo "Running tests using `which python`"
# Install the wheel we just built
pip install "$delocated_wheel"{test_extras}
# 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
@@ -122,8 +127,8 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
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),
+5 -5
View File
@@ -14,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='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='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.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'),
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'])
@@ -152,7 +152,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef
# 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=virtualenv_env, shell=True)
# clean up
shutil.rmtree(venv_dir)
+66 -47
View File
@@ -1,67 +1,78 @@
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
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)
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):
python_name = "python" if configuration.version[0] == '3' else "python2"
if configuration.arch == "32":
python_name = python_name + "x86"
return [python_name, "-Version", configuration.version, "-OutputDirectory", "C:/python"]
def get_python_configurations(build_selector):
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path'])
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier'])
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.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
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
# 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:
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)
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:
shell = simple_shell
else:
run_with_env = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'appveyor_run_with_env.cmd'))
@@ -77,10 +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')
python_configurations = get_python_configurations(build_selector)
# 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)
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'))
@@ -107,8 +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
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)
+5 -1
View File
@@ -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)
+15 -1
View File
@@ -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'))
+3 -3
View File
@@ -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)
+7 -4
View File
@@ -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)
+7
View File
@@ -0,0 +1,7 @@
from setuptools import setup, Extension
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
+57
View File
@@ -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)
}
+27 -14
View File
@@ -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):
@@ -25,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)
@@ -50,45 +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}-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}-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_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 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]