Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aeeac6725a | ||
|
|
41b4b092b1 | ||
|
|
28186bf142 | ||
|
|
4e10d9d897 | ||
|
|
2ab2d079ab | ||
|
|
5e529969ea | ||
|
|
b7a689e349 | ||
|
|
4f4fed06e0 | ||
|
|
45fcebf9d8 | ||
|
|
e67b3bc611 | ||
|
|
d8456a0ffa | ||
|
|
73681d9b24 | ||
|
|
02ed7b2262 | ||
|
|
ab86b8cd93 | ||
|
|
3a03df8ec9 | ||
|
|
0e78b2b1f5 | ||
|
|
5b14c8c0ec | ||
|
|
0627bd09d4 | ||
|
|
a5e64e216c | ||
|
|
23cf50614f | ||
|
|
1e08ff03b3 | ||
|
|
2216385c0b | ||
|
|
a1fc0cb117 | ||
|
|
430b71c767 | ||
|
|
14f14a24d3 | ||
|
|
b732026734 | ||
|
|
0d85db7111 | ||
|
|
477fc7e060 | ||
|
|
17566cdee7 | ||
|
|
49bc742add | ||
|
|
4cbb67fac1 | ||
|
|
2e3155decf | ||
|
|
719352b1d2 | ||
|
|
f7d93cc9e4 | ||
|
|
3f5572e956 | ||
|
|
bab8b6668e | ||
|
|
f29697d623 | ||
|
|
e87032c830 | ||
|
|
e360a04dc1 | ||
|
|
9050137d2b | ||
|
|
857aafbd3f | ||
|
|
0cd3e426bc | ||
|
|
8b632bcb6d | ||
|
|
364fc5220e | ||
|
|
0ed37f268a | ||
|
|
f410fbdd03 | ||
|
|
21fb27faf7 | ||
|
|
ac4b62ca07 | ||
|
|
3f7a4d753f | ||
|
|
95d2086ced | ||
|
|
52e8f41b5c | ||
|
|
1e2a2e7d4d | ||
|
|
6377854545 | ||
|
|
be57269d5d | ||
|
|
d5856884a3 | ||
|
|
c2d3dc3b0f | ||
|
|
9116217b60 | ||
|
|
a8f6684bfd | ||
|
|
6852d87d2e | ||
|
|
054c273997 | ||
|
|
652d094e46 | ||
|
|
1bfe6d45bd | ||
|
|
aefde9535b | ||
|
|
d46fb62e95 | ||
|
|
87a9d170b0 | ||
|
|
dcce949d3c | ||
|
|
1d3c59d804 | ||
|
|
0b791dbea5 | ||
|
|
44256e4aa5 | ||
|
|
243103762b | ||
|
|
b579cd5f2a | ||
|
|
8523b25a18 | ||
|
|
637a251b79 | ||
|
|
ac76af4f75 | ||
|
|
a6ff864010 | ||
|
|
79f044314b | ||
|
|
0c0e21aa83 | ||
|
|
f1bba58f86 | ||
|
|
56218d896c | ||
|
|
d79ca07bbb | ||
|
|
c6f4f01732 | ||
|
|
586b3c7197 | ||
|
|
0b4475ed07 | ||
|
|
38b3b0a3da | ||
|
|
5adfce9838 | ||
|
|
bc83839387 | ||
|
|
481b1cb060 | ||
|
|
ccfc3c3aa1 | ||
|
|
3d23cbf2a6 | ||
|
|
b9a296324d | ||
|
|
c4822ebdd6 | ||
|
|
2ca6500bba | ||
|
|
8dd71189b2 | ||
|
|
a448c02d7f | ||
|
|
696866bfe1 | ||
|
|
1faa2fe5df | ||
|
|
602acebcc8 | ||
|
|
c43f1b6e3d | ||
|
|
0d3e67b1f9 | ||
|
|
e3b565320c | ||
|
|
56973d34df | ||
|
|
66e9a1cc19 |
+8
-16
@@ -11,12 +11,10 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Prepare the environment.
|
name: Prepare the environment.
|
||||||
command: |
|
command: bash .circleci/prepare.sh
|
||||||
bash .circleci/prepare.sh
|
|
||||||
- run:
|
- run:
|
||||||
name: Test.
|
name: Test.
|
||||||
command: |
|
command: venv/bin/python ./bin/run_tests.py
|
||||||
venv/bin/python ./bin/run_tests.py
|
|
||||||
|
|
||||||
osx-python3:
|
osx-python3:
|
||||||
macos:
|
macos:
|
||||||
@@ -28,12 +26,10 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Prepare the environment.
|
name: Prepare the environment.
|
||||||
command: |
|
command: bash .circleci/prepare.sh
|
||||||
bash .circleci/prepare.sh
|
|
||||||
- run:
|
- run:
|
||||||
name: Test.
|
name: Test.
|
||||||
command: |
|
command: venv/bin/python ./bin/run_tests.py
|
||||||
venv/bin/python ./bin/run_tests.py
|
|
||||||
|
|
||||||
linux-python2:
|
linux-python2:
|
||||||
docker:
|
docker:
|
||||||
@@ -46,12 +42,10 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Prepare the environment.
|
name: Prepare the environment.
|
||||||
command: |
|
command: bash .circleci/prepare.sh
|
||||||
bash .circleci/prepare.sh
|
|
||||||
- run:
|
- run:
|
||||||
name: Test.
|
name: Test.
|
||||||
command: |
|
command: venv/bin/python ./bin/run_tests.py
|
||||||
venv/bin/python ./bin/run_tests.py
|
|
||||||
|
|
||||||
linux-python3:
|
linux-python3:
|
||||||
docker:
|
docker:
|
||||||
@@ -64,12 +58,10 @@ jobs:
|
|||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Prepare the environment.
|
name: Prepare the environment.
|
||||||
command: |
|
command: bash .circleci/prepare.sh
|
||||||
bash .circleci/prepare.sh
|
|
||||||
- run:
|
- run:
|
||||||
name: Test.
|
name: Test.
|
||||||
command: |
|
command: venv/bin/python ./bin/run_tests.py
|
||||||
venv/bin/python ./bin/run_tests.py
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
version: 2
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ cibuildwheel
|
|||||||
|
|
||||||
Python wheels are great. Building them across **Mac, Linux, Windows**, on **multiple versions of Python**, is not.
|
Python wheels are great. Building them across **Mac, Linux, Windows**, on **multiple versions of Python**, is not.
|
||||||
|
|
||||||
`cibuildwheel` is here to help. `cibuildwheel` runs on your CI server - currently it supports Travis CI, Appveyor, and CircleCI - and it builds and tests your wheels across all of your platforms.
|
`cibuildwheel` is here to help. `cibuildwheel` runs on your CI server - currently it supports Azure Pipelines, Travis CI, AppVeyor, and CircleCI - and it builds and tests your wheels across all of your platforms.
|
||||||
|
|
||||||
**`cibuildwheel` is in beta**. It's brand new - I'd love for you to try it and help make it better!
|
**`cibuildwheel` is in beta**. It's brand new - I'd love for you to try it and help make it better!
|
||||||
|
|
||||||
@@ -14,25 +14,95 @@ What does it do?
|
|||||||
|
|
||||||
| | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit |
|
| | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| Python 2.7 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| Python 2.7 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Python 3.4 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| Python 3.4 | ✅ | ✅ | ✅ | ✅* | ✅* |
|
||||||
| Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
| Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
|
||||||
- Builds manylinux, macOS and Windows (32 and 64bit) wheels using Travis CI, Appveyor, and CircleCI
|
> \* Not supported on Azure Pipelines
|
||||||
|
|
||||||
|
- 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)
|
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
|
||||||
- Runs the library test suite against the wheel-installed version of your library
|
- Runs the library test suite against the wheel-installed version of your library
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
|
|
||||||
`cibuildwheel` currently works on **Travis CI** and **CircleCI** to build Linux and Mac wheels, and **Appveyor** to build Windows wheels.
|
`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` is not intended to run on your development machine. It will try to install packages globally; this is no good. Travis CI, CircleCI, and Appveyor run their builds in isolated environments, so are ideal for this kind of script.
|
| | Linux | macOS | Windows |
|
||||||
|
|-----------------|-------|-------|---------|
|
||||||
|
| Azure Pipelines | ✅ | ✅ | ✅ |
|
||||||
|
| Travis CI | ✅ | ✅ | |
|
||||||
|
| AppVeyor | | | ✅ |
|
||||||
|
| CircleCI | ✅ | ✅ | |
|
||||||
|
|
||||||
|
`cibuildwheel` is not intended to run on your development machine. It will try to install packages globally; this is no good. Travis CI, CircleCI, and AppVeyor run their builds in isolated environments, so are ideal for this kind of script.
|
||||||
|
|
||||||
### Minimal setup
|
### Minimal setup
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Azure Pipelines</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/windows.svg" />
|
||||||
|
<img width="16" src="https://unpkg.com/simple-icons@latest/icons/linux.svg" />
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
- Using Azure pipelines, you can build all three platforms on the same service. Create a `azure-pipelines.yml` file in your repo.
|
||||||
|
|
||||||
|
**azure-pipelines.yml**
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
- job: linux
|
||||||
|
pool: {vmImage: 'Ubuntu-16.04'}
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
- bash: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install cibuildwheel==0.12.0
|
||||||
|
cibuildwheel --output-dir wheelhouse .
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
inputs: {pathtoPublish: 'wheelhouse'}
|
||||||
|
- job: macos
|
||||||
|
pool: {vmImage: 'macOS-10.13'}
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
- bash: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install cibuildwheel==0.12.0
|
||||||
|
cibuildwheel --output-dir wheelhouse .
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
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}}
|
||||||
|
- script: choco install vcpython27 -f -y
|
||||||
|
displayName: Install Visual C++ for Python 2.7
|
||||||
|
- bash: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install cibuildwheel==0.12.0
|
||||||
|
cibuildwheel --output-dir wheelhouse .
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
inputs: {pathtoPublish: 'wheelhouse'}
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<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" />
|
||||||
|
</summary>
|
||||||
|
|
||||||
- To build Linux and Mac wheels on Travis CI, create a `.travis.yml` file in your repo.
|
- To build Linux and Mac wheels on Travis CI, create a `.travis.yml` file in your repo.
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -49,12 +119,20 @@ Usage
|
|||||||
env: PIP=pip2
|
env: PIP=pip2
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- $PIP install cibuildwheel==0.10.0
|
- $PIP install cibuildwheel==0.12.0
|
||||||
- cibuildwheel --output-dir wheelhouse
|
- cibuildwheel --output-dir wheelhouse
|
||||||
```
|
```
|
||||||
|
|
||||||
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.
|
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>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>CircleCI</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" />
|
||||||
|
</summary>
|
||||||
|
|
||||||
- To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo,
|
- To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo,
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -102,20 +180,30 @@ Usage
|
|||||||
|
|
||||||
CircleCI will store the built wheels for you - you can access them from the project console.
|
CircleCI will store the built wheels for you - you can access them from the project console.
|
||||||
|
|
||||||
- To build Windows wheels on Appveyor, create an `appveyor.yml` file in your repo.
|
</details>
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>AppVeyor</b>
|
||||||
|
<img width="16" src="https://unpkg.com/simple-icons@latest/icons/windows.svg" />
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
- To build Windows wheels on AppVeyor, create an `appveyor.yml` file in your repo.
|
||||||
|
|
||||||
```
|
```
|
||||||
build_script:
|
build_script:
|
||||||
- pip install cibuildwheel==0.10.0
|
- pip install cibuildwheel==0.12.0
|
||||||
- cibuildwheel --output-dir wheelhouse
|
- cibuildwheel --output-dir wheelhouse
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: "wheelhouse\\*.whl"
|
- path: "wheelhouse\\*.whl"
|
||||||
name: Wheels
|
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.
|
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.
|
||||||
|
|
||||||
- Commit those files, enable building of your repo on Travis CI and Appveyor, and push.
|
</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.
|
||||||
|
|
||||||
@@ -137,6 +225,7 @@ All being well, you should get wheels delivered to you in a few minutes.
|
|||||||
| | `CIBW_MANYLINUX1_I686_IMAGE` | Specify an alternative manylinux1 i686 docker image |
|
| | `CIBW_MANYLINUX1_I686_IMAGE` | Specify an alternative manylinux1 i686 docker image |
|
||||||
| **Tests** | `CIBW_TEST_COMMAND` | Execute a shell command to test all built wheels |
|
| **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_REQUIRES` | Install Python dependencies before running the tests |
|
||||||
|
| | `CIBW_TEST_EXTRAS` | Install Python dependencies before running the tests using ``extras_require``|
|
||||||
|
|
||||||
A more detailed description of the options, the allowed values, and some examples can be found in the [Options](#options) section.
|
A more detailed description of the options, the allowed values, and some examples can be found in the [Options](#options) section.
|
||||||
|
|
||||||
@@ -152,9 +241,8 @@ Options
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
```
|
```
|
||||||
usage: cibuildwheel [-h]
|
usage: cibuildwheel [-h] [--platform {auto,linux,macos,windows}]
|
||||||
[--output-dir OUTPUT_DIR]
|
[--output-dir OUTPUT_DIR] [--print-build-identifiers]
|
||||||
[--platform PLATFORM]
|
|
||||||
[project_dir]
|
[project_dir]
|
||||||
|
|
||||||
Build wheels for all the platforms.
|
Build wheels for all the platforms.
|
||||||
@@ -174,7 +262,10 @@ optional arguments:
|
|||||||
you need to run in Windows, and it will build and test
|
you need to run in Windows, and it will build and test
|
||||||
for all versions of Python at C:\PythonXX[-x64].
|
for all versions of Python at C:\PythonXX[-x64].
|
||||||
--output-dir OUTPUT_DIR
|
--output-dir OUTPUT_DIR
|
||||||
Destination folder for the wheels.
|
Destination folder for the wheels.
|
||||||
|
--print-build-identifiers
|
||||||
|
Print the build identifiers matched by the current
|
||||||
|
invocation and exit.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -222,7 +313,7 @@ Examples:
|
|||||||
- Skip Python 3.6 on Linux: `CIBW_SKIP`:`cp36-manylinux*`
|
- 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 *-manylinux1_i686`
|
||||||
|
|
||||||
**
|
***
|
||||||
|
|
||||||
| Environment variable: `CIBW_BUILD_VERBOSITY`
|
| Environment variable: `CIBW_BUILD_VERBOSITY`
|
||||||
| ---
|
| ---
|
||||||
@@ -322,6 +413,25 @@ Example: `nose==1.3.7 moto==0.4.31`
|
|||||||
Platform-specific variants also available:
|
Platform-specific variants also available:
|
||||||
`CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX`
|
`CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX`
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
| Environment variable: `CIBW_TEST_EXTRAS`
|
||||||
|
| ---
|
||||||
|
|
||||||
|
Optional.
|
||||||
|
|
||||||
|
Comma-separated list of
|
||||||
|
[extras_require](https://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-extras-optional-features-with-their-own-dependencies)
|
||||||
|
options that should be included when installing the wheel prior to running the
|
||||||
|
tests. This can be used to avoid having to redefine test dependencies in
|
||||||
|
``CIBW_TEST_REQUIRES`` if they are already defined in ``setup.py`` or
|
||||||
|
``setup.cfg``.
|
||||||
|
|
||||||
|
Example: `test,qt` (will cause the wheel to be installed with ``pip install <wheel_file>[test,qt])
|
||||||
|
|
||||||
|
|
||||||
|
Platform-specific variants also available:
|
||||||
|
`CIBW_TEST_EXTRAS_MACOS` | `CIBW_TEST_EXTRAS_WINDOWS` | `CIBW_TEST_EXTRAS_LINUX`
|
||||||
|
|
||||||
### Example YML syntax
|
### Example YML syntax
|
||||||
|
|
||||||
@@ -381,6 +491,7 @@ If your wheel didn't compile, check the list below for some debugging tips.
|
|||||||
- A mistake in your config. To quickly test your config without doing a git push and waiting for your code to build on CI, you can run the Linux build in a Docker container. On Mac or Linux, with Docker running, try `cibuildwheel --platform linux`. You'll have to bring your config into the current environment first.
|
- A mistake in your config. To quickly test your config without doing a git push and waiting for your code to build on CI, you can run the Linux build in a Docker container. On Mac or Linux, with Docker running, try `cibuildwheel --platform linux`. You'll have to bring your config into the current environment first.
|
||||||
- Missing dependency. You might need to install something on the build machine. You can do this in `.travis.yml`, `appveyor.yml`, or `.circleci/config.yml`, with apt-get, brew or whatever Windows uses :P . Given how the Linux build works, we'll probably have to build something into `cibuildwheel`. Let's chat about that over in the issues!
|
- Missing dependency. You might need to install something on the build machine. You can do this in `.travis.yml`, `appveyor.yml`, or `.circleci/config.yml`, with apt-get, brew or whatever Windows uses :P . Given how the Linux build works, we'll probably have to build something into `cibuildwheel`. Let's chat about that over in the issues!
|
||||||
- Windows: missing C feature. The Windows C compiler doesn't support C language features invented after 1990, so you'll have to backport your C code to C90. For me, this mostly involved putting my variable declarations at the top of the function like an animal.
|
- Windows: missing C feature. The Windows C compiler doesn't support C language features invented after 1990, so you'll have to backport your C code to C90. For me, this mostly involved putting my variable declarations at the top of the function like an animal.
|
||||||
|
- MacOS: calling cibuildwheel from a python3 script and getting a `ModuleNotFoundError`? Due to a [bug](https://bugs.python.org/issue22490) in CPython, you'll need to [unset the `__PYVENV_LAUNCHER__` variable](https://github.com/joerick/cibuildwheel/issues/133#issuecomment-478288597) before activating a venv.
|
||||||
|
|
||||||
Working examples
|
Working examples
|
||||||
----------------
|
----------------
|
||||||
@@ -394,6 +505,9 @@ Here are some repos that use cibuildwheel.
|
|||||||
- [pybase64](https://github.com/mayeut/pybase64)
|
- [pybase64](https://github.com/mayeut/pybase64)
|
||||||
- [KDEpy](https://github.com/tommyod/KDEpy)
|
- [KDEpy](https://github.com/tommyod/KDEpy)
|
||||||
- [AutoPy](https://github.com/autopilot-rs/autopy)
|
- [AutoPy](https://github.com/autopilot-rs/autopy)
|
||||||
|
- [apriltags2-ethz](https://github.com/safijari/apriltags2_ethz)
|
||||||
|
- [TgCrypto](https://github.com/pyrogram/tgcrypto)
|
||||||
|
- [Twisted](https://github.com/twisted/twisted)
|
||||||
|
|
||||||
> Add repo here! Send a PR.
|
> Add repo here! Send a PR.
|
||||||
|
|
||||||
@@ -409,6 +523,43 @@ This is similar to static linking, so it might have some licence implications. C
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
### 0.11.1
|
||||||
|
|
||||||
|
_28 May 2019_
|
||||||
|
|
||||||
|
- 🐛 Fix missing file in the release tarball, that was causing problems with
|
||||||
|
Windows builds (#141)
|
||||||
|
|
||||||
|
### 0.11.0
|
||||||
|
|
||||||
|
_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
|
||||||
|
[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
|
||||||
|
can more precisely assert what should be produced for each one. (#136, #137).
|
||||||
|
|
||||||
|
### 0.10.2
|
||||||
|
|
||||||
|
_10 March 2019_
|
||||||
|
|
||||||
|
- 🛠 Revert temporary fix in macOS, that was working around a bug in pip 19 (#129)
|
||||||
|
- 🛠 Update Python to 2.7.16 on macOS
|
||||||
|
- 🛠 Update OpenSSL patch to 1.0.2r on macOS
|
||||||
|
|
||||||
|
### 0.10.1
|
||||||
|
|
||||||
|
_3 February 2019_
|
||||||
|
|
||||||
|
- 🐛 Fix build stalling on macOS (that was introduced in pip 19) (#122)
|
||||||
|
- 🐛 Fix "AttributeError: 'Popen' object has no attribute 'args'" on Python 2.7 for Linux builds (#108)
|
||||||
|
- 🛠 Update Python from 3.6.7, 3.7.1 to 3.6.8, 3.7.2 on macOS
|
||||||
|
- 🛠 Update openssl patch from 1.0.2p to 1.0.2q on macOS
|
||||||
|
- 🛠 Sorting build options dict items when printing preamble (#114)
|
||||||
|
|
||||||
### 0.10.0
|
### 0.10.0
|
||||||
|
|
||||||
_23 September 2018_
|
_23 September 2018_
|
||||||
@@ -500,7 +651,7 @@ _7 September 2017_
|
|||||||
_14 August 2017_
|
_14 August 2017_
|
||||||
|
|
||||||
- 🐛 Fixed a bug on Windows where subprocess' output was hidden (#23)
|
- 🐛 Fixed a bug on Windows where subprocess' output was hidden (#23)
|
||||||
- 🐛 Fixed a bug on Appveyor where logs would appear in the wrong order due to output buffering (#24, thanks @YannickJadoul!)
|
- 🐛 Fixed a bug on AppVeyor where logs would appear in the wrong order due to output buffering (#24, thanks @YannickJadoul!)
|
||||||
|
|
||||||
### 0.4.0
|
### 0.4.0
|
||||||
|
|
||||||
@@ -582,4 +733,6 @@ Massive props also to-
|
|||||||
See also
|
See also
|
||||||
--------
|
--------
|
||||||
|
|
||||||
|
If you'd like to keep wheel building separate from the package itself, check out [astrofrog/autowheel](https://github.com/astrofrog/autowheel). It builds packages using cibuildwheel from source distributions on PyPI.
|
||||||
|
|
||||||
If `cibuildwheel` is too limited for your needs, consider [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild). `multibuild` is a toolbox for building a wheel on various platforms. It can do a lot more than this project - it's used to build SciPy!
|
If `cibuildwheel` is too limited for your needs, consider [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild). `multibuild` is a toolbox for building a wheel on various platforms. It can do a lot more than this project - it's used to build SciPy!
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
jobs:
|
||||||
|
- job: linux
|
||||||
|
pool: {vmImage: 'Ubuntu-16.04'}
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
- bash: |
|
||||||
|
python -m pip install -r requirements-dev.txt
|
||||||
|
python ./bin/run_tests.py
|
||||||
|
|
||||||
|
- job: macos
|
||||||
|
pool: {vmImage: 'macOS-10.13'}
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
- 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}}
|
||||||
|
- script: choco install vcpython27 -f -y
|
||||||
|
displayName: Install Visual C++ for Python 2.7
|
||||||
|
- bash: |
|
||||||
|
python -m pip install -r requirements-dev.txt
|
||||||
|
python ./bin/run_tests.py
|
||||||
|
|
||||||
+18
-22
@@ -1,31 +1,29 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import os, sys, subprocess, shutil, json
|
import os, sys, subprocess, shutil
|
||||||
from glob import glob
|
|
||||||
|
project_root = os.path.dirname(os.path.dirname(__file__))
|
||||||
|
test_utils_dir = os.path.join(project_root, 'test', 'shared')
|
||||||
|
|
||||||
def single_run(test_project):
|
def single_run(test_project):
|
||||||
# load project settings into environment
|
# set up an environment that gives access to the test utils
|
||||||
env_file = os.path.join(test_project, 'environment.json')
|
|
||||||
project_env = {}
|
|
||||||
if os.path.exists(env_file):
|
|
||||||
with open(env_file) as f:
|
|
||||||
project_env = json.load(f)
|
|
||||||
|
|
||||||
# run the build
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
project_env = {str(k): str(v) for k, v in project_env.items()} # unicode not allowed in env
|
|
||||||
env.update(project_env)
|
|
||||||
print('Building %s with environment %s' % (test_project, project_env))
|
|
||||||
subprocess.check_call([sys.executable, '-m', 'cibuildwheel', test_project], env=env)
|
|
||||||
wheels = glob('wheelhouse/*.whl')
|
|
||||||
print('%s built successfully. %i wheels built.' % (test_project, len(wheels)))
|
|
||||||
|
|
||||||
# check some wheels were actually built
|
if 'PYTHONPATH' in env:
|
||||||
assert len(wheels) >= 3
|
env['PYTHONPATH'] += os.pathsep + test_utils_dir
|
||||||
|
else:
|
||||||
|
env['PYTHONPATH'] = test_utils_dir
|
||||||
|
|
||||||
|
# run the test
|
||||||
|
subprocess.check_call(
|
||||||
|
[sys.executable, '-m', 'pytest', '-vv', os.path.join(test_project, 'cibuildwheel_test.py')],
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
|
||||||
# clean up
|
# clean up
|
||||||
shutil.rmtree('wheelhouse')
|
if os.path.exists('wheelhouse'):
|
||||||
|
shutil.rmtree('wheelhouse')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
@@ -41,5 +39,3 @@ if __name__ == '__main__':
|
|||||||
exit(2)
|
exit(2)
|
||||||
|
|
||||||
single_run(project_path)
|
single_run(project_path)
|
||||||
|
|
||||||
print('Project built successfully.')
|
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import os, sys, subprocess, shutil, json
|
import os, sys, subprocess, shutil, json
|
||||||
@@ -14,7 +14,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
### run the integration tests
|
### run the integration tests
|
||||||
|
|
||||||
test_projects = glob('test/??_*')
|
test_projects = sorted(glob('test/??_*'))
|
||||||
|
|
||||||
if len(test_projects) == 0:
|
if len(test_projects) == 0:
|
||||||
print('No test projects found. Aborting.', file=sys.stderr)
|
print('No test projects found. Aborting.', file=sys.stderr)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = '0.10.0'
|
__version__ = '0.12.0'
|
||||||
|
|||||||
+40
-22
@@ -48,6 +48,10 @@ def main():
|
|||||||
help=('Path to the project that you want wheels for. Default: the current '
|
help=('Path to the project that you want wheels for. Default: the current '
|
||||||
'directory.'))
|
'directory.'))
|
||||||
|
|
||||||
|
parser.add_argument('--print-build-identifiers',
|
||||||
|
action='store_true',
|
||||||
|
help='Print the build identifiers matched by the current invocation and exit.')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.platform != 'auto':
|
if args.platform != 'auto':
|
||||||
@@ -68,10 +72,17 @@ def main():
|
|||||||
platform = 'linux'
|
platform = 'linux'
|
||||||
elif sys.platform.startswith('darwin'):
|
elif sys.platform.startswith('darwin'):
|
||||||
platform = 'macos'
|
platform = 'macos'
|
||||||
|
elif 'AZURE_HTTP_USER_AGENT' in os.environ:
|
||||||
|
if os.environ['AGENT_OS'] == 'Linux':
|
||||||
|
platform = 'linux'
|
||||||
|
elif os.environ['AGENT_OS'] == 'Darwin':
|
||||||
|
platform = 'macos'
|
||||||
|
elif os.environ['AGENT_OS'] == 'Windows_NT':
|
||||||
|
platform = 'windows'
|
||||||
|
|
||||||
if platform is None:
|
if platform is None:
|
||||||
print('cibuildwheel: Unable to detect platform. cibuildwheel should run on your CI server, '
|
print('cibuildwheel: Unable to detect platform. cibuildwheel should run on your CI server, '
|
||||||
'Travis CI, Appveyor, and CircleCI are supported. You can run on your development '
|
'Travis CI, AppVeyor, and CircleCI are supported. You can run on your development '
|
||||||
'machine using the --platform argument. Check --help output for more '
|
'machine using the --platform argument. Check --help output for more '
|
||||||
'information.',
|
'information.',
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
@@ -80,12 +91,16 @@ def main():
|
|||||||
output_dir = args.output_dir
|
output_dir = args.output_dir
|
||||||
test_command = get_option_from_environment('CIBW_TEST_COMMAND', platform=platform)
|
test_command = get_option_from_environment('CIBW_TEST_COMMAND', platform=platform)
|
||||||
test_requires = get_option_from_environment('CIBW_TEST_REQUIRES', platform=platform, default='').split()
|
test_requires = get_option_from_environment('CIBW_TEST_REQUIRES', platform=platform, default='').split()
|
||||||
|
test_extras = get_option_from_environment('CIBW_TEST_EXTRAS', platform=platform, default='')
|
||||||
project_dir = args.project_dir
|
project_dir = args.project_dir
|
||||||
before_build = get_option_from_environment('CIBW_BEFORE_BUILD', platform=platform)
|
before_build = get_option_from_environment('CIBW_BEFORE_BUILD', platform=platform)
|
||||||
build_verbosity = get_option_from_environment('CIBW_BUILD_VERBOSITY', platform=platform, default='')
|
build_verbosity = get_option_from_environment('CIBW_BUILD_VERBOSITY', platform=platform, default='')
|
||||||
build_config, skip_config = os.environ.get('CIBW_BUILD', '*'), os.environ.get('CIBW_SKIP', '')
|
build_config, skip_config = os.environ.get('CIBW_BUILD', '*'), os.environ.get('CIBW_SKIP', '')
|
||||||
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
|
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
|
||||||
|
|
||||||
|
if test_extras:
|
||||||
|
test_extras = '[{0}]'.format(test_extras)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
build_verbosity = min(3, max(-3, int(build_verbosity)))
|
build_verbosity = min(3, max(-3, int(build_verbosity)))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -105,33 +120,20 @@ def main():
|
|||||||
# This needs to be passed on to the docker container in linux.py
|
# This needs to be passed on to the docker container in linux.py
|
||||||
os.environ['CIBUILDWHEEL'] = '1'
|
os.environ['CIBUILDWHEEL'] = '1'
|
||||||
|
|
||||||
try:
|
if not os.path.exists(os.path.join(project_dir, 'setup.py')):
|
||||||
project_setup_py = os.path.join(project_dir, 'setup.py')
|
print('cibuildwheel: Could not find setup.py at root of project', file=sys.stderr)
|
||||||
name_output = subprocess.check_output([sys.executable, project_setup_py, '--name'],
|
|
||||||
universal_newlines=True)
|
|
||||||
# the last line of output is the name
|
|
||||||
package_name = name_output.strip().splitlines()[-1]
|
|
||||||
except subprocess.CalledProcessError as err:
|
|
||||||
if not os.path.exists(project_setup_py):
|
|
||||||
print('cibuildwheel: Could not find setup.py at root of project', file=sys.stderr)
|
|
||||||
exit(2)
|
|
||||||
else:
|
|
||||||
print(err.output)
|
|
||||||
print('cibuildwheel: Failed to get name of the package. Command was %s' % err.cmd,
|
|
||||||
file=sys.stderr)
|
|
||||||
exit(err.returncode)
|
|
||||||
|
|
||||||
if package_name == '' or package_name == 'UNKNOWN':
|
|
||||||
print('cibuildwheel: Invalid package name "%s". Check your setup.py' % package_name,
|
|
||||||
file=sys.stderr)
|
|
||||||
exit(2)
|
exit(2)
|
||||||
|
|
||||||
|
if args.print_build_identifiers:
|
||||||
|
print_build_identifiers(platform, build_selector)
|
||||||
|
exit(0)
|
||||||
|
|
||||||
build_options = dict(
|
build_options = dict(
|
||||||
project_dir=project_dir,
|
project_dir=project_dir,
|
||||||
package_name=package_name,
|
|
||||||
output_dir=output_dir,
|
output_dir=output_dir,
|
||||||
test_command=test_command,
|
test_command=test_command,
|
||||||
test_requires=test_requires,
|
test_requires=test_requires,
|
||||||
|
test_extras=test_extras,
|
||||||
before_build=before_build,
|
before_build=before_build,
|
||||||
build_verbosity=build_verbosity,
|
build_verbosity=build_verbosity,
|
||||||
build_selector=build_selector,
|
build_selector=build_selector,
|
||||||
@@ -167,6 +169,7 @@ def main():
|
|||||||
else:
|
else:
|
||||||
raise Exception('Unsupported platform')
|
raise Exception('Unsupported platform')
|
||||||
|
|
||||||
|
|
||||||
def print_preamble(platform, build_options):
|
def print_preamble(platform, build_options):
|
||||||
print(textwrap.dedent('''
|
print(textwrap.dedent('''
|
||||||
_ _ _ _ _ _ _
|
_ _ _ _ _ _ _
|
||||||
@@ -180,7 +183,7 @@ def print_preamble(platform, build_options):
|
|||||||
|
|
||||||
print('Build options:')
|
print('Build options:')
|
||||||
print(' platform: %r' % platform)
|
print(' platform: %r' % platform)
|
||||||
for option, value in build_options.items():
|
for option, value in sorted(build_options.items()):
|
||||||
print(' %s: %r' % (option, value))
|
print(' %s: %r' % (option, value))
|
||||||
|
|
||||||
warnings = detect_warnings(platform, build_options)
|
warnings = detect_warnings(platform, build_options)
|
||||||
@@ -191,6 +194,21 @@ def print_preamble(platform, build_options):
|
|||||||
|
|
||||||
print('\nHere we go!\n')
|
print('\nHere we go!\n')
|
||||||
|
|
||||||
|
|
||||||
|
def print_build_identifiers(platform, build_selector):
|
||||||
|
if platform == 'linux':
|
||||||
|
python_configurations = cibuildwheel.linux.get_python_configurations(build_selector)
|
||||||
|
elif platform == 'windows':
|
||||||
|
python_configurations = cibuildwheel.windows.get_python_configurations(build_selector)
|
||||||
|
elif platform == 'macos':
|
||||||
|
python_configurations = cibuildwheel.macos.get_python_configurations(build_selector)
|
||||||
|
else:
|
||||||
|
python_configurations = []
|
||||||
|
|
||||||
|
for config in python_configurations:
|
||||||
|
print(config.identifier)
|
||||||
|
|
||||||
|
|
||||||
def detect_warnings(platform, build_options):
|
def detect_warnings(platform, build_options):
|
||||||
warnings = []
|
warnings = []
|
||||||
|
|
||||||
|
|||||||
+19
-16
@@ -9,16 +9,7 @@ except ImportError:
|
|||||||
from pipes import quote as shlex_quote
|
from pipes import quote as shlex_quote
|
||||||
|
|
||||||
|
|
||||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment, manylinux1_images):
|
def get_python_configurations(build_selector):
|
||||||
try:
|
|
||||||
subprocess.check_call(['docker', '--version'])
|
|
||||||
except:
|
|
||||||
print('cibuildwheel: Docker not found. Docker is required to run Linux builds. '
|
|
||||||
'If you\'re building on Travis CI, add `services: [docker]` to your .travis.yml.'
|
|
||||||
'If you\'re building on Circle CI in Linux, add a `setup_remote_docker` step to your .circleci/config.yml',
|
|
||||||
file=sys.stderr)
|
|
||||||
exit(2)
|
|
||||||
|
|
||||||
PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path'])
|
PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path'])
|
||||||
python_configurations = [
|
python_configurations = [
|
||||||
PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27m'),
|
PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27m'),
|
||||||
@@ -36,8 +27,20 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
]
|
]
|
||||||
|
|
||||||
# skip builds as required
|
# skip builds as required
|
||||||
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
|
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):
|
||||||
|
try:
|
||||||
|
subprocess.check_call(['docker', '--version'])
|
||||||
|
except:
|
||||||
|
print('cibuildwheel: Docker not found. Docker is required to run Linux builds. '
|
||||||
|
'If you\'re building on Travis CI, add `services: [docker]` to your .travis.yml.'
|
||||||
|
'If you\'re building on Circle CI in Linux, add a `setup_remote_docker` step to your .circleci/config.yml',
|
||||||
|
file=sys.stderr)
|
||||||
|
exit(2)
|
||||||
|
|
||||||
|
python_configurations = get_python_configurations(build_selector)
|
||||||
platforms = [
|
platforms = [
|
||||||
('manylinux1_x86_64', manylinux1_images.get('x86_64') or 'quay.io/pypa/manylinux1_x86_64'),
|
('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'),
|
('manylinux1_i686', manylinux1_images.get('i686') or 'quay.io/pypa/manylinux1_i686'),
|
||||||
@@ -83,7 +86,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
delocated_wheel=(/tmp/delocated_wheel/*.whl)
|
delocated_wheel=(/tmp/delocated_wheel/*.whl)
|
||||||
|
|
||||||
# Install the wheel we just built
|
# Install the wheel we just built
|
||||||
"$PYBIN/pip" install "$delocated_wheel"
|
"$PYBIN/pip" install "$delocated_wheel"{test_extras}
|
||||||
|
|
||||||
# Install any requirements to run the tests
|
# Install any requirements to run the tests
|
||||||
if [ ! -z "{test_requires}" ]; then
|
if [ ! -z "{test_requires}" ]; then
|
||||||
@@ -102,9 +105,9 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
chown {uid}:{gid} "/output/$(basename "$delocated_wheel")"
|
chown {uid}:{gid} "/output/$(basename "$delocated_wheel")"
|
||||||
done
|
done
|
||||||
'''.format(
|
'''.format(
|
||||||
package_name=package_name,
|
|
||||||
pybin_paths=' '.join(c.path+'/bin' for c in platform_configs),
|
pybin_paths=' '.join(c.path+'/bin' for c in platform_configs),
|
||||||
test_requires=' '.join(test_requires),
|
test_requires=' '.join(test_requires),
|
||||||
|
test_extras=test_extras,
|
||||||
test_command=shlex_quote(
|
test_command=shlex_quote(
|
||||||
prepare_command(test_command, project='/project') if test_command else ''
|
prepare_command(test_command, project='/project') if test_command else ''
|
||||||
),
|
),
|
||||||
@@ -122,15 +125,15 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
if stdin_str is None:
|
if stdin_str is None:
|
||||||
subprocess.check_call(['docker'] + command)
|
subprocess.check_call(['docker'] + command)
|
||||||
else:
|
else:
|
||||||
process = subprocess.Popen(['docker'] + command,
|
args = ['docker'] + command
|
||||||
stdin=subprocess.PIPE, universal_newlines=True)
|
process = subprocess.Popen(args, stdin=subprocess.PIPE, universal_newlines=True)
|
||||||
try:
|
try:
|
||||||
process.communicate(stdin_str)
|
process.communicate(stdin_str)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
process.kill()
|
process.kill()
|
||||||
process.wait()
|
process.wait()
|
||||||
if process.returncode != 0:
|
if process.returncode != 0:
|
||||||
raise subprocess.CalledProcessError(process.returncode, process.args)
|
raise subprocess.CalledProcessError(process.returncode, args)
|
||||||
|
|
||||||
container_name = 'cibuildwheel-{}'.format(uuid.uuid4())
|
container_name = 'cibuildwheel-{}'.format(uuid.uuid4())
|
||||||
try:
|
try:
|
||||||
|
|||||||
+13
-10
@@ -10,15 +10,22 @@ except ImportError:
|
|||||||
from .util import prepare_command, get_build_verbosity_extra_flags
|
from .util import prepare_command, get_build_verbosity_extra_flags
|
||||||
|
|
||||||
|
|
||||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment):
|
def get_python_configurations(build_selector):
|
||||||
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'url'])
|
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'url'])
|
||||||
python_configurations = [
|
python_configurations = [
|
||||||
PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.15/python-2.7.15-macosx10.6.pkg'),
|
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='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.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.6/python-3.6.6-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.0/python-3.7.0-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'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# 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):
|
||||||
|
python_configurations = get_python_configurations(build_selector)
|
||||||
get_pip_url = 'https://bootstrap.pypa.io/get-pip.py'
|
get_pip_url = 'https://bootstrap.pypa.io/get-pip.py'
|
||||||
get_pip_script = '/tmp/get-pip.py'
|
get_pip_script = '/tmp/get-pip.py'
|
||||||
|
|
||||||
@@ -42,10 +49,6 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
call(['curl', '-L', '-o', get_pip_script, get_pip_url])
|
call(['curl', '-L', '-o', get_pip_script, get_pip_url])
|
||||||
|
|
||||||
for config in python_configurations:
|
for config in python_configurations:
|
||||||
if not build_selector(config.identifier):
|
|
||||||
print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# if this version of python isn't installed, get it from python.org and install
|
# if this version of python isn't installed, get it from python.org and install
|
||||||
python_package_identifier = 'org.python.Python.PythonFramework-%s' % config.version
|
python_package_identifier = 'org.python.Python.PythonFramework-%s' % config.version
|
||||||
if python_package_identifier not in installed_system_packages:
|
if python_package_identifier not in installed_system_packages:
|
||||||
@@ -55,7 +58,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/'])
|
call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/'])
|
||||||
# patch open ssl
|
# patch open ssl
|
||||||
if config.version in ('3.4', '3.5'):
|
if config.version in ('3.4', '3.5'):
|
||||||
call(['curl', '-fsSLo', '/tmp/python-patch.tar.gz', 'https://github.com/mayeut/patch-macos-python-openssl/releases/download/v0.1.0/patch-macos-python-%s-openssl-v0.1.0.tar.gz' % config.version])
|
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'])
|
call(['sudo', 'tar', '-C', '/Library/Frameworks/Python.framework/Versions/%s/' % config.version, '-xmf', '/tmp/python-patch.tar.gz'])
|
||||||
|
|
||||||
installation_bin_path = '/Library/Frameworks/Python.framework/Versions/{}/bin'.format(config.version)
|
installation_bin_path = '/Library/Frameworks/Python.framework/Versions/{}/bin'.format(config.version)
|
||||||
@@ -118,7 +121,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0]
|
delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0]
|
||||||
|
|
||||||
# install the wheel
|
# install the wheel
|
||||||
call(['pip', 'install', delocated_wheel], env=env)
|
call(['pip', 'install', delocated_wheel + test_extras], env=env)
|
||||||
|
|
||||||
# test the wheel
|
# test the wheel
|
||||||
if test_requires:
|
if test_requires:
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
:: To build extensions for 64 bit Python 3, we need to configure environment
|
||||||
|
:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
|
||||||
|
:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
|
||||||
|
::
|
||||||
|
:: To build extensions for 64 bit Python 2, we need to configure environment
|
||||||
|
:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of:
|
||||||
|
:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0)
|
||||||
|
::
|
||||||
|
:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific
|
||||||
|
:: environment configurations.
|
||||||
|
::
|
||||||
|
:: Note: this script needs to be run with the /E:ON and /V:ON flags for the
|
||||||
|
:: cmd interpreter, at least for (SDK v7.0)
|
||||||
|
::
|
||||||
|
:: More details at:
|
||||||
|
:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
|
||||||
|
:: http://stackoverflow.com/a/13751649/163740
|
||||||
|
::
|
||||||
|
:: Author: Olivier Grisel
|
||||||
|
:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
::
|
||||||
|
:: Notes about batch files for Python people:
|
||||||
|
::
|
||||||
|
:: Quotes in values are literally part of the values:
|
||||||
|
:: SET FOO="bar"
|
||||||
|
:: FOO is now five characters long: " b a r "
|
||||||
|
:: If you don't want quotes, don't include them on the right-hand side.
|
||||||
|
::
|
||||||
|
:: The CALL lines at the end of this file look redundant, but if you move them
|
||||||
|
:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y
|
||||||
|
:: case, I don't know why.
|
||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
SET COMMAND_TO_RUN=%*
|
||||||
|
SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
|
||||||
|
SET WIN_WDK=c:\Program Files (x86)\Windows Kits\10\Include\wdf
|
||||||
|
|
||||||
|
:: Extract the major and minor versions, and allow for the minor version to be
|
||||||
|
:: more than 9. This requires the version number to have two dots in it.
|
||||||
|
SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1%
|
||||||
|
IF "%PYTHON_VERSION:~3,1%" == "." (
|
||||||
|
SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
|
||||||
|
) ELSE (
|
||||||
|
SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2%
|
||||||
|
)
|
||||||
|
|
||||||
|
:: Based on the Python version, determine what SDK version to use, and whether
|
||||||
|
:: to set the SDK for 64-bit.
|
||||||
|
IF %MAJOR_PYTHON_VERSION% == 2 (
|
||||||
|
SET WINDOWS_SDK_VERSION="v7.0"
|
||||||
|
SET SET_SDK_64=Y
|
||||||
|
) ELSE (
|
||||||
|
IF %MAJOR_PYTHON_VERSION% == 3 (
|
||||||
|
SET WINDOWS_SDK_VERSION="v7.1"
|
||||||
|
IF %MINOR_PYTHON_VERSION% LEQ 4 (
|
||||||
|
SET SET_SDK_64=Y
|
||||||
|
) ELSE (
|
||||||
|
SET SET_SDK_64=N
|
||||||
|
IF EXIST "%WIN_WDK%" (
|
||||||
|
:: See: https://connect.microsoft.com/VisualStudio/feedback/details/1610302/
|
||||||
|
REN "%WIN_WDK%" 0wdf
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) ELSE (
|
||||||
|
ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
|
||||||
|
EXIT 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
IF %PYTHON_ARCH% == 64 (
|
||||||
|
IF %SET_SDK_64% == Y (
|
||||||
|
ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture
|
||||||
|
SET DISTUTILS_USE_SDK=1
|
||||||
|
SET MSSdk=1
|
||||||
|
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION%
|
||||||
|
"%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
|
||||||
|
ECHO Executing: %COMMAND_TO_RUN%
|
||||||
|
call %COMMAND_TO_RUN% || EXIT 1
|
||||||
|
) ELSE (
|
||||||
|
ECHO Using default MSVC build environment for 64 bit architecture
|
||||||
|
ECHO Executing: %COMMAND_TO_RUN%
|
||||||
|
call %COMMAND_TO_RUN% || EXIT 1
|
||||||
|
)
|
||||||
|
) ELSE (
|
||||||
|
ECHO Using default MSVC build environment for 32 bit architecture
|
||||||
|
ECHO Executing: %COMMAND_TO_RUN%
|
||||||
|
call %COMMAND_TO_RUN% || EXIT 1
|
||||||
|
)
|
||||||
+61
-26
@@ -1,29 +1,38 @@
|
|||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import os, tempfile, subprocess, sys, shutil
|
import os, tempfile, subprocess, shutil
|
||||||
try:
|
|
||||||
from urllib2 import urlopen
|
|
||||||
except ImportError:
|
|
||||||
from urllib.request import urlopen
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from glob import glob
|
from glob import glob
|
||||||
|
|
||||||
from .util import prepare_command, get_build_verbosity_extra_flags
|
from .util import prepare_command, get_build_verbosity_extra_flags
|
||||||
|
|
||||||
|
|
||||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment):
|
IS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache')
|
||||||
# run_with_env is a cmd file that sets the right environment variables to
|
|
||||||
run_with_env = os.path.join(tempfile.gettempdir(), 'appveyor_run_with_env.cmd')
|
|
||||||
if not os.path.exists(run_with_env):
|
|
||||||
with open(run_with_env, 'wb') as f:
|
|
||||||
request = urlopen('https://github.com/ogrisel/python-appveyor-demo/raw/09a1c8672e5015a74d8f69d07add6ee803c176ec/appveyor/run_with_env.cmd')
|
|
||||||
f.write(request.read())
|
|
||||||
|
|
||||||
def shell(args, env=None, cwd=None):
|
def get_python_path(config):
|
||||||
# print the command executing for the logs
|
if IS_RUNNING_ON_AZURE:
|
||||||
print('+ ' + ' '.join(args))
|
# We can't hard-code the paths because on Azure, we don't know which
|
||||||
args = ['cmd', '/E:ON', '/V:ON', '/C', run_with_env] + args
|
# bugfix release of Python we are getting so we need to check which
|
||||||
return subprocess.check_call(' '.join(args), env=env, cwd=cwd)
|
# 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 ''
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_python_configurations(build_selector):
|
||||||
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path'])
|
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path'])
|
||||||
python_configurations = [
|
python_configurations = [
|
||||||
PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\Python27'),
|
PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\Python27'),
|
||||||
@@ -38,18 +47,44 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\Python37-x64'),
|
PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\Python37-x64'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
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']
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
else:
|
||||||
|
run_with_env = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'appveyor_run_with_env.cmd'))
|
||||||
|
|
||||||
|
# run_with_env is a cmd file that sets the right environment variables
|
||||||
|
# to build on AppVeyor.
|
||||||
|
def shell(args, env=None, cwd=None):
|
||||||
|
# print the command executing for the logs
|
||||||
|
print('+ ' + ' '.join(args))
|
||||||
|
args = ['cmd', '/E:ON', '/V:ON', '/C', run_with_env] + args
|
||||||
|
return subprocess.check_call(' '.join(args), env=env, cwd=cwd)
|
||||||
|
|
||||||
abs_project_dir = os.path.abspath(project_dir)
|
abs_project_dir = os.path.abspath(project_dir)
|
||||||
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
|
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
|
||||||
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
|
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
|
||||||
|
|
||||||
|
python_configurations = get_python_configurations(build_selector)
|
||||||
|
|
||||||
for config in python_configurations:
|
for config in python_configurations:
|
||||||
if not build_selector(config.identifier):
|
config_python_path = get_python_path(config)
|
||||||
print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# check python & pip exist for this configuration
|
# check python & pip exist for this configuration
|
||||||
assert os.path.exists(os.path.join(config.path, 'python.exe'))
|
assert os.path.exists(os.path.join(config_python_path, 'python.exe'))
|
||||||
assert os.path.exists(os.path.join(config.path, 'Scripts', 'pip.exe'))
|
assert os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe'))
|
||||||
|
|
||||||
# setup dirs
|
# setup dirs
|
||||||
if os.path.exists(built_wheel_dir):
|
if os.path.exists(built_wheel_dir):
|
||||||
@@ -61,8 +96,8 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
env['PYTHON_VERSION'] = config.version
|
env['PYTHON_VERSION'] = config.version
|
||||||
env['PYTHON_ARCH'] = config.arch
|
env['PYTHON_ARCH'] = config.arch
|
||||||
env['PATH'] = os.pathsep.join([
|
env['PATH'] = os.pathsep.join([
|
||||||
config.path,
|
config_python_path,
|
||||||
os.path.join(config.path, 'Scripts'),
|
os.path.join(config_python_path, 'Scripts'),
|
||||||
env['PATH']
|
env['PATH']
|
||||||
])
|
])
|
||||||
env = environment.as_dictionary(prev_environment=env)
|
env = environment.as_dictionary(prev_environment=env)
|
||||||
@@ -87,7 +122,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
|||||||
built_wheel = glob(built_wheel_dir+'/*.whl')[0]
|
built_wheel = glob(built_wheel_dir+'/*.whl')[0]
|
||||||
|
|
||||||
# install the wheel
|
# install the wheel
|
||||||
shell(['pip', 'install', built_wheel], env=env)
|
shell(['pip', 'install', built_wheel + test_extras], env=env)
|
||||||
|
|
||||||
# test the wheel
|
# test the wheel
|
||||||
if test_requires:
|
if test_requires:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[bumpversion]
|
[bumpversion]
|
||||||
current_version = 0.10.0
|
current_version = 0.12.0
|
||||||
commit = True
|
commit = True
|
||||||
tag = True
|
tag = True
|
||||||
message = Bump version
|
message = Bump version
|
||||||
@@ -12,3 +12,6 @@ message = Bump version
|
|||||||
search = cibuildwheel=={current_version}
|
search = cibuildwheel=={current_version}
|
||||||
replace = cibuildwheel=={new_version}
|
replace = cibuildwheel=={new_version}
|
||||||
|
|
||||||
|
[bdist_wheel]
|
||||||
|
universal = 1
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ except ImportError:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='cibuildwheel',
|
name='cibuildwheel',
|
||||||
version='0.10.0',
|
version='0.12.0',
|
||||||
install_requires=['bashlex'],
|
install_requires=['bashlex!=0.13'],
|
||||||
description="Build Python wheels on CI with minimal configuration.",
|
description="Build Python wheels on CI with minimal configuration.",
|
||||||
long_description='For readme please see http://github.com/joerick/cibuildwheel',
|
long_description='For readme please see http://github.com/joerick/cibuildwheel',
|
||||||
author="Joe Rickerby",
|
author="Joe Rickerby",
|
||||||
@@ -18,6 +18,9 @@ setup(
|
|||||||
packages=['cibuildwheel',],
|
packages=['cibuildwheel',],
|
||||||
license="BSD",
|
license="BSD",
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
|
package_data={
|
||||||
|
'cibuildwheel': ['resources/*'],
|
||||||
|
},
|
||||||
keywords='ci wheel packaging pypi travis appveyor macos linux windows',
|
keywords='ci wheel packaging pypi travis appveyor macos linux windows',
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import os
|
||||||
|
import utils
|
||||||
|
|
||||||
|
|
||||||
|
project_dir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
def test():
|
||||||
|
# build the wheels
|
||||||
|
utils.cibuildwheel_run(project_dir)
|
||||||
|
|
||||||
|
# check that the expected wheels are produced
|
||||||
|
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||||
|
actual_wheels = os.listdir('wheelhouse')
|
||||||
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
|
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')
|
||||||
|
build_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir)
|
||||||
|
assert len(expected_wheels) == len(build_identifiers)
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import os
|
||||||
|
import utils
|
||||||
|
|
||||||
|
def test():
|
||||||
|
project_dir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
# build and test the wheels
|
||||||
|
utils.cibuildwheel_run(project_dir, add_env={
|
||||||
|
'CIBW_TEST_REQUIRES': 'nose',
|
||||||
|
# the 'false ||' bit is to ensure this command runs in a shell on
|
||||||
|
# mac/linux.
|
||||||
|
'CIBW_TEST_COMMAND': 'false || nosetests {project}/test',
|
||||||
|
'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test',
|
||||||
|
})
|
||||||
|
|
||||||
|
# also check that we got the right wheels
|
||||||
|
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||||
|
actual_wheels = os.listdir('wheelhouse')
|
||||||
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|
||||||
|
|
||||||
|
def test_extras_require():
|
||||||
|
project_dir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
# build and test the wheels
|
||||||
|
utils.cibuildwheel_run(project_dir, add_env={
|
||||||
|
'CIBW_TEST_EXTRAS': 'test',
|
||||||
|
# the 'false ||' bit is to ensure this command runs in a shell on
|
||||||
|
# mac/linux.
|
||||||
|
'CIBW_TEST_COMMAND': 'false || nosetests {project}/test',
|
||||||
|
'CIBW_TEST_COMMAND_WINDOWS': 'nosetests {project}/test',
|
||||||
|
})
|
||||||
|
|
||||||
|
# also check that we got the right wheels
|
||||||
|
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||||
|
actual_wheels = os.listdir('wheelhouse')
|
||||||
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"CIBW_TEST_REQUIRES": "nose",
|
|
||||||
"CIBW_TEST_COMMAND": "false || nosetests {project}/test",
|
|
||||||
"comment": "The 'false ||' bit is to ensure this command runs in a shell on Mac and Linux",
|
|
||||||
"CIBW_TEST_COMMAND_WINDOWS": "nosetests {project}/test"
|
|
||||||
}
|
|
||||||
@@ -3,5 +3,6 @@ from setuptools import setup, Extension
|
|||||||
setup(
|
setup(
|
||||||
name="spam",
|
name="spam",
|
||||||
ext_modules=[Extension('spam', sources=['spam.c'])],
|
ext_modules=[Extension('spam', sources=['spam.c'])],
|
||||||
|
extras_require={'test': ['nose']},
|
||||||
version="0.1.0",
|
version="0.1.0",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import os
|
||||||
|
import utils
|
||||||
|
|
||||||
|
def test():
|
||||||
|
project_dir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
# build the wheels
|
||||||
|
utils.cibuildwheel_run(project_dir, add_env={
|
||||||
|
# write python version information to a temporary file, this is
|
||||||
|
# checked in setup.py
|
||||||
|
'CIBW_BEFORE_BUILD': '''python -c "import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)"''',
|
||||||
|
'CIBW_BEFORE_BUILD_WINDOWS': '''python -c "import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)" && python -c "import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)"''',
|
||||||
|
})
|
||||||
|
|
||||||
|
# also check that we got the right wheels
|
||||||
|
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||||
|
actual_wheels = os.listdir('wheelhouse')
|
||||||
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"CIBW_BEFORE_BUILD": "python -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"",
|
|
||||||
"CIBW_BEFORE_BUILD_WINDOWS": "python -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\""
|
|
||||||
}
|
|
||||||
@@ -1,24 +1,23 @@
|
|||||||
from setuptools import setup, Extension
|
from setuptools import setup, Extension
|
||||||
import sys, os
|
import sys, os
|
||||||
|
|
||||||
if sys.argv[-1] != '--name':
|
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step
|
||||||
# assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step
|
# is the same one as is currently running.
|
||||||
# is the same one as is currently running.
|
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt'
|
||||||
version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt'
|
with open(version_file) as f:
|
||||||
with open(version_file) as f:
|
stored_version = f.read()
|
||||||
stored_version = f.read()
|
print('stored_version', stored_version)
|
||||||
print('stored_version', stored_version)
|
print('sys.version', sys.version)
|
||||||
print('sys.version', sys.version)
|
assert stored_version == sys.version
|
||||||
assert stored_version == sys.version
|
|
||||||
|
|
||||||
# check that the executable also was written
|
# check that the executable also was written
|
||||||
executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt'
|
executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt'
|
||||||
with open(executable_file) as f:
|
with open(executable_file) as f:
|
||||||
stored_executable = f.read()
|
stored_executable = f.read()
|
||||||
print('stored_executable', stored_executable)
|
print('stored_executable', stored_executable)
|
||||||
print('sys.executable', sys.executable)
|
print('sys.executable', sys.executable)
|
||||||
# windows/mac are case insensitive
|
# windows/mac are case insensitive
|
||||||
assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower()
|
assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower()
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="spam",
|
name="spam",
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
3.6.0 (default, Feb 7 2017, 23:55:32)
|
|
||||||
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import os
|
||||||
|
import utils
|
||||||
|
|
||||||
|
def test():
|
||||||
|
project_dir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
# build the wheels
|
||||||
|
utils.cibuildwheel_run(project_dir, add_env={
|
||||||
|
'CIBW_BUILD': 'cp3?-*',
|
||||||
|
'CIBW_SKIP': 'cp34-*',
|
||||||
|
})
|
||||||
|
|
||||||
|
# check that we got the right wheels. There should be no 2.7 or 3.4.
|
||||||
|
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
|
||||||
|
if ('-cp3' in w) and ('-cp34' not in w)]
|
||||||
|
actual_wheels = os.listdir('wheelhouse')
|
||||||
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"CIBW_BUILD": "cp3?-*",
|
|
||||||
"CIBW_SKIP": "cp34-*"
|
|
||||||
}
|
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
from setuptools import setup, Extension
|
from setuptools import setup, Extension
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
if sys.argv[-1] != '--name':
|
# explode if run on Python 2.7 or Python 3.4 (these should be skipped)
|
||||||
# explode if run on Python 2.7 or Python 3.4 (these should be skipped)
|
if sys.version_info[0:2] == (2, 7):
|
||||||
if sys.version_info[0:2] == (2, 7):
|
raise Exception('Python 2.7 should not be built')
|
||||||
raise Exception('Python 2.7 should not be built')
|
if sys.version_info[0:2] == (3, 4):
|
||||||
if sys.version_info[0:2] == (3, 4):
|
raise Exception('Python 3.4 should be skipped')
|
||||||
raise Exception('Python 3.4 should be skipped')
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="spam",
|
name="spam",
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
3.6.0 (default, Feb 7 2017, 23:55:32)
|
|
||||||
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import os
|
||||||
|
import utils
|
||||||
|
|
||||||
|
def test():
|
||||||
|
project_dir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
# write some information into the CIBW_ENVIRONMENT, for expansion and
|
||||||
|
# insertion into the environment by cibuildwheel. This is checked
|
||||||
|
# in setup.py
|
||||||
|
utils.cibuildwheel_run(project_dir, add_env={
|
||||||
|
'CIBW_ENVIRONMENT': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH=$PATH:/opt/cibw_test_path''',
|
||||||
|
'CIBW_ENVIRONMENT_WINDOWS': '''CIBW_TEST_VAR="a b c" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3="$(echo 'test string 3')" PATH="$PATH;/opt/cibw_test_path"''',
|
||||||
|
})
|
||||||
|
|
||||||
|
# also check that we got the right wheels built
|
||||||
|
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||||
|
actual_wheels = os.listdir('wheelhouse')
|
||||||
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"CIBW_ENVIRONMENT": "CIBW_TEST_VAR=\"a b c\" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3=\"$(echo 'test string 3')\" PATH=$PATH:/opt/cibw_test_path",
|
|
||||||
"CIBW_ENVIRONMENT_WINDOWS": "CIBW_TEST_VAR=\"a b c\" CIBW_TEST_VAR_2=1 CIBW_TEST_VAR_3=\"$(echo 'test string 3')\" PATH=\"$PATH;/opt/cibw_test_path\""
|
|
||||||
}
|
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
from setuptools import setup, Extension
|
from setuptools import setup, Extension
|
||||||
import sys, os
|
import sys, os
|
||||||
|
|
||||||
if sys.argv[-1] != '--name':
|
# explode if environment isn't correct, as set in CIBW_ENVIRONMENT
|
||||||
# explode if environment isn't correct, as set in CIBW_ENVIRONMENT
|
CIBW_TEST_VAR = os.environ.get('CIBW_TEST_VAR')
|
||||||
CIBW_TEST_VAR = os.environ.get('CIBW_TEST_VAR')
|
CIBW_TEST_VAR_2 = os.environ.get('CIBW_TEST_VAR_2')
|
||||||
CIBW_TEST_VAR_2 = os.environ.get('CIBW_TEST_VAR_2')
|
PATH = os.environ.get('PATH')
|
||||||
PATH = os.environ.get('PATH')
|
|
||||||
|
|
||||||
if CIBW_TEST_VAR != 'a b c':
|
if CIBW_TEST_VAR != 'a b c':
|
||||||
raise Exception('CIBW_TEST_VAR should equal "a b c". It was "%s"' % CIBW_TEST_VAR)
|
raise Exception('CIBW_TEST_VAR should equal "a b c". It was "%s"' % CIBW_TEST_VAR)
|
||||||
if CIBW_TEST_VAR_2 != '1':
|
if CIBW_TEST_VAR_2 != '1':
|
||||||
raise Exception('CIBW_TEST_VAR_2 should equal "1". It was "%s"' % CIBW_TEST_VAR_2)
|
raise Exception('CIBW_TEST_VAR_2 should equal "1". It was "%s"' % CIBW_TEST_VAR_2)
|
||||||
if '/opt/cibw_test_path' not in PATH:
|
if '/opt/cibw_test_path' not in PATH:
|
||||||
raise Exception('PATH should contain "/opt/cibw_test_path". It was "%s"' % PATH)
|
raise Exception('PATH should contain "/opt/cibw_test_path". It was "%s"' % PATH)
|
||||||
if '$PATH' in PATH:
|
if '$PATH' in PATH:
|
||||||
raise Exception('$PATH should be expanded in PATH. It was "%s"' % PATH)
|
raise Exception('$PATH should be expanded in PATH. It was "%s"' % PATH)
|
||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
3.6.0 (default, Feb 7 2017, 23:55:32)
|
|
||||||
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
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')
|
||||||
|
|
||||||
|
utils.cibuildwheel_run(project_dir, add_env={
|
||||||
|
'CIBW_MANYLINUX1_X86_64_IMAGE': 'dockcross/manylinux-x64',
|
||||||
|
'CIBW_MANYLINUX1_I686_IMAGE': 'dockcross/manylinux-x86',
|
||||||
|
})
|
||||||
|
|
||||||
|
# also check that we got the right wheels built
|
||||||
|
expected_wheels = utils.expected_wheels('spam', '0.1.0')
|
||||||
|
actual_wheels = os.listdir('wheelhouse')
|
||||||
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"CIBW_MANYLINUX1_X86_64_IMAGE": "dockcross/manylinux-x64",
|
|
||||||
"CIBW_MANYLINUX1_I686_IMAGE": "dockcross/manylinux-x86",
|
|
||||||
"CIBW_SKIP": "cp37-manylinux*"
|
|
||||||
}
|
|
||||||
@@ -2,11 +2,10 @@ import os, sys
|
|||||||
|
|
||||||
from setuptools import setup, Extension
|
from setuptools import setup, Extension
|
||||||
|
|
||||||
if sys.argv[-1] != '--name':
|
# check that we're running in the correct docker image as specified in the
|
||||||
# check that we're running in the correct docker image as specified in the
|
# environment options CIBW_MANYLINUX1_*_IMAGE
|
||||||
# environment options CIBW_MANYLINUX1_*_IMAGE
|
if 'linux' in sys.platform and not os.path.exists('/dockcross'):
|
||||||
if 'linux' in sys.platform and not os.path.exists('/dockcross'):
|
raise Exception('/dockcross directory not found. Is this test running in the correct docker image?')
|
||||||
raise Exception('/dockcross directory not found. Is this test running in the correct docker image?')
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="spam",
|
name="spam",
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import os
|
||||||
|
import utils
|
||||||
|
|
||||||
|
def test():
|
||||||
|
project_dir = os.path.dirname(__file__)
|
||||||
|
# this test checks that SSL is working in the build environment using
|
||||||
|
# some checks in setup.py.
|
||||||
|
|
||||||
|
utils.cibuildwheel_run(project_dir)
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
'''
|
||||||
|
Utility functions used by the cibuildwheel tests.
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
|
||||||
|
def cibuildwheel_get_build_identifiers(project_path, env=None):
|
||||||
|
'''
|
||||||
|
Returns the list of build identifiers that cibuildwheel will try to build
|
||||||
|
for the current platform.
|
||||||
|
'''
|
||||||
|
cmd_output = subprocess.check_output(
|
||||||
|
[sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers', project_path],
|
||||||
|
universal_newlines=True,
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd_output.strip().split('\n')
|
||||||
|
|
||||||
|
|
||||||
|
def cibuildwheel_run(project_path, env=None, add_env=None):
|
||||||
|
'''
|
||||||
|
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)
|
||||||
|
|
||||||
|
subprocess.check_call(
|
||||||
|
[sys.executable, '-m', 'cibuildwheel', project_path],
|
||||||
|
env=env,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def expected_wheels(package_name, package_version):
|
||||||
|
'''
|
||||||
|
Returns a list of expected wheels from a run of cibuildwheel.
|
||||||
|
'''
|
||||||
|
if platform == 'linux':
|
||||||
|
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}-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',
|
||||||
|
]
|
||||||
|
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}-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',
|
||||||
|
]
|
||||||
|
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',
|
||||||
|
]
|
||||||
|
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]
|
||||||
|
|
||||||
|
return [filename.format(package_name=package_name, package_version=package_version)
|
||||||
|
for filename in templates]
|
||||||
|
|
||||||
|
platform = None
|
||||||
|
|
||||||
|
if 'CIBW_PLATFORM' in os.environ:
|
||||||
|
platform = os.environ['CIBW_PLATFORM']
|
||||||
|
elif sys.platform.startswith('linux'):
|
||||||
|
platform = 'linux'
|
||||||
|
elif sys.platform.startswith('darwin'):
|
||||||
|
platform = 'macos'
|
||||||
|
elif sys.platform in ['win32', 'cygwin']:
|
||||||
|
platform = 'windows'
|
||||||
|
else:
|
||||||
|
raise Exception('Unsupported platform')
|
||||||
Reference in New Issue
Block a user