Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c7c2c8fc7 | ||
|
|
f0759803a3 | ||
|
|
75af5944f5 | ||
|
|
2737add6e5 | ||
|
|
e11c9070ce | ||
|
|
dff3aca4b6 | ||
|
|
07b87ea651 | ||
|
|
0d08a1c85e | ||
|
|
38ae494c0d | ||
|
|
38f52569aa | ||
|
|
2f47e64225 | ||
|
|
22d473acc0 | ||
|
|
f27943608b | ||
|
|
d8dd54af11 | ||
|
|
9975f9c9bb | ||
|
|
a50dffd844 | ||
|
|
c6ede9b542 | ||
|
|
04837dd593 | ||
|
|
e9df889f56 | ||
|
|
940b48f7e6 | ||
|
|
9c797c271b | ||
|
|
e6cab342a8 | ||
|
|
4ac219c6f0 | ||
|
|
1344fd4bd1 | ||
|
|
88e993f452 | ||
|
|
5bc6b02eea | ||
|
|
9f1f5f640d | ||
|
|
710a3095f2 | ||
|
|
b9099f35a0 | ||
|
|
076d6b7594 | ||
|
|
b142b09e22 | ||
|
|
5cbe3e2254 | ||
|
|
96aa38b56c | ||
|
|
4aecdff16a | ||
|
|
6b832703a4 | ||
|
|
d223db13d8 | ||
|
|
c9451facbd | ||
|
|
38d713fef6 | ||
|
|
4b5e9d8e88 | ||
|
|
07447ff66c | ||
|
|
845bfda599 | ||
|
|
bc93615baa | ||
|
|
86b00da754 | ||
|
|
84f82a5898 | ||
|
|
985389d5ee | ||
|
|
fe961f4a7e | ||
|
|
da24b0d361 | ||
|
|
76fd16ea8b | ||
|
|
7a51e249ec | ||
|
|
11b2c110d7 | ||
|
|
b0ac79061c | ||
|
|
b5b825783f | ||
|
|
66195bf4bc | ||
|
|
1e7961c157 | ||
|
|
14f2f4eeb1 | ||
|
|
6f217f6c90 | ||
|
|
21aab69860 | ||
|
|
93c14c805b | ||
|
|
d2772c2293 | ||
|
|
58c5e56e9f | ||
|
|
bb14c67835 | ||
|
|
bd3bc981a5 | ||
|
|
2da8e12936 | ||
|
|
dfbb20ee69 | ||
|
|
08edf62e79 | ||
|
|
b4addbf4a9 | ||
|
|
13a79bdb45 | ||
|
|
5b4a3dea50 | ||
|
|
cb579ee641 | ||
|
|
eb82806f0b | ||
|
|
b719392bd5 | ||
|
|
6908669cb1 | ||
|
|
f40c248231 | ||
|
|
ca7db28ec4 | ||
|
|
0eb29ef19b | ||
|
|
dee19309cb |
@@ -21,6 +21,7 @@ jobs:
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test cibuildwheel on ${{ matrix.os }}
|
name: Test cibuildwheel on ${{ matrix.os }}
|
||||||
|
needs: pre-commit
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -38,11 +39,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
python -m pip install -e ".[dev]"
|
python -m pip install -e ".[dev]"
|
||||||
|
|
||||||
- name: Install Visual C++ for Python 2.7
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: |
|
|
||||||
choco install vcpython27 -f -y
|
|
||||||
|
|
||||||
- name: Get PR labels
|
- name: Get PR labels
|
||||||
id: pr-labels
|
id: pr-labels
|
||||||
uses: joerick/pr-labels-action@v1.0.6
|
uses: joerick/pr-labels-action@v1.0.6
|
||||||
@@ -70,6 +66,7 @@ jobs:
|
|||||||
|
|
||||||
test-emulated:
|
test-emulated:
|
||||||
name: Test emulated cibuildwheel using qemu
|
name: Test emulated cibuildwheel using qemu
|
||||||
|
needs: pre-commit
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 180
|
timeout-minutes: 180
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
- name: "Run update: python configs"
|
- name: "Run update: python configs"
|
||||||
run: python ./bin/update_pythons.py --force
|
run: python ./bin/update_pythons.py --force
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master' && github.repository == 'joerick/cibuildwheel'
|
||||||
uses: peter-evans/create-pull-request@v3
|
uses: peter-evans/create-pull-request@v3
|
||||||
with:
|
with:
|
||||||
commit-message: Update dependencies
|
commit-message: Update dependencies
|
||||||
|
|||||||
+20
-8
@@ -6,24 +6,32 @@ repos:
|
|||||||
- id: check-case-conflict
|
- id: check-case-conflict
|
||||||
- id: check-merge-conflict
|
- id: check-merge-conflict
|
||||||
- id: check-yaml
|
- id: check-yaml
|
||||||
|
- id: check-toml
|
||||||
|
- id: debug-statements
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
exclude: (cibuildwheel/resources/pinned_docker_images.cfg)|(.svg$)
|
exclude: (cibuildwheel/resources/pinned_docker_images.cfg)|(.svg$)
|
||||||
- id: mixed-line-ending
|
- id: mixed-line-ending
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
|
|
||||||
- repo: https://github.com/PyCQA/isort
|
- repo: https://github.com/PyCQA/isort
|
||||||
rev: 5.7.0
|
rev: 5.8.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: isort
|
- id: isort
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 20.8b1
|
rev: 21.4b1
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
files: ^bin/update_pythons.py|setup.py$
|
files: ^bin/update_pythons.py|setup.py$
|
||||||
|
|
||||||
|
- repo: https://github.com/asottile/setup-cfg-fmt
|
||||||
|
rev: v1.17.0
|
||||||
|
hooks:
|
||||||
|
- id: setup-cfg-fmt
|
||||||
|
stages: [manual]
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||||
rev: v0.800
|
rev: v0.812
|
||||||
hooks:
|
hooks:
|
||||||
- id: mypy
|
- id: mypy
|
||||||
exclude: ^(bin/|cibuildwheel/resources/).*py$
|
exclude: ^(bin/|cibuildwheel/resources/).*py$
|
||||||
@@ -36,20 +44,24 @@ repos:
|
|||||||
args: ["--python-version=3.7", "--ignore-missing-imports", "--scripts-are-modules"]
|
args: ["--python-version=3.7", "--ignore-missing-imports", "--scripts-are-modules"]
|
||||||
|
|
||||||
- repo: https://github.com/asottile/pyupgrade
|
- repo: https://github.com/asottile/pyupgrade
|
||||||
rev: v2.9.0
|
rev: v2.13.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
|
name: PyUpgrade 3.6+
|
||||||
args: ["--py36-plus"]
|
args: ["--py36-plus"]
|
||||||
|
exclude: ^bin/
|
||||||
|
- id: pyupgrade
|
||||||
|
name: PyUpgrade 3.7+ on bin
|
||||||
|
exclude: ^(cibuildwheel|unit_test|test)/
|
||||||
|
args: ["--py37-plus"]
|
||||||
|
|
||||||
- repo: https://gitlab.com/pycqa/flake8
|
- repo: https://github.com/PyCQA/flake8
|
||||||
rev: 3.8.4
|
rev: 3.9.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
exclude: cibuildwheel/resources/
|
exclude: cibuildwheel/resources/
|
||||||
additional_dependencies: [flake8-bugbear]
|
additional_dependencies: [flake8-bugbear]
|
||||||
|
|
||||||
|
|
||||||
# The original pybind11 checks for a few C++ style items
|
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: disallow-caps
|
- id: disallow-caps
|
||||||
|
|||||||
+3
-3
@@ -36,9 +36,9 @@ jobs:
|
|||||||
os: windows
|
os: windows
|
||||||
language: shell
|
language: shell
|
||||||
before_install:
|
before_install:
|
||||||
- choco install python3 --version 3.6.8 --no-progress -y
|
- choco upgrade python3 -y --version 3.6.8 --limit-output
|
||||||
# Update root certificates to fix SSL error; see http://www.chawn.com/RootCerts.htm
|
# Update root certificates to fix SSL error; see http://www.chawn.com/RootCerts.htm
|
||||||
- powershell "md C:\temp\certs; CertUtil -generateSSTFromWU C:\temp\certs\RootStore.sst; Get-ChildItem -Path C:\\temp\certs\Rootstore.sst | Import-Certificate -CertStoreLocation Cert:\\LocalMachine\\Root\\ | out-null"
|
- powershell "md C:\temp\certs; CertUtil -generateSSTFromWU C:\temp\certs\RootStore.sst; Get-ChildItem -Path C:\\temp\certs\Rootstore.sst | Import-Certificate -CertStoreLocation Cert:\\LocalMachine\\Root\\ | out-null"
|
||||||
env:
|
env:
|
||||||
- PYTHON=C:\\Python36\\python
|
- PYTHON=C:\\Python36\\python
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ What does it do?
|
|||||||
| PyPy 3.6 v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
|
| PyPy 3.6 v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
|
||||||
| PyPy 3.7 (beta) v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
|
| PyPy 3.7 (beta) v7.3.3 | ✅ | | | ✅ | ✅ | | | | |
|
||||||
|
|
||||||
<sup>¹ Not supported on Travis</sup><br>
|
<sup>¹ Only using a workaround with a newer compiler; Microsoft removed the 2008 compiler for Python 2.7 in April 2021.</sup><br>
|
||||||
|
|
||||||
- Builds manylinux, macOS 10.9+, and Windows wheels for CPython and PyPy
|
- Builds manylinux, macOS 10.9+, and Windows wheels for CPython and PyPy
|
||||||
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, and GitLab CI
|
- Works on GitHub Actions, Azure Pipelines, Travis CI, AppVeyor, CircleCI, and GitLab CI
|
||||||
@@ -86,7 +86,7 @@ jobs:
|
|||||||
- uses: actions/setup-python@v2
|
- uses: actions/setup-python@v2
|
||||||
|
|
||||||
- name: Install cibuildwheel
|
- name: Install cibuildwheel
|
||||||
run: python -m pip install cibuildwheel==1.9.0
|
run: python -m pip install cibuildwheel==1.10.1
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
run: python -m cibuildwheel --output-dir wheelhouse
|
run: python -m cibuildwheel --output-dir wheelhouse
|
||||||
@@ -147,8 +147,8 @@ Here are some repos that use cibuildwheel.
|
|||||||
| [pyzmq][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python bindings for zeromq, the networking library. Uses Cython and CFFI. |
|
| [pyzmq][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python bindings for zeromq, the networking library. Uses Cython and CFFI. |
|
||||||
| [aiortc][] | ![github icon][] | ![apple icon][] ![linux icon][] | WebRTC and ORTC implementation for Python using asyncio. |
|
| [aiortc][] | ![github icon][] | ![apple icon][] ![linux icon][] | WebRTC and ORTC implementation for Python using asyncio. |
|
||||||
| [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, PyTables, pandas, bcolz and more |
|
| [numexpr][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Fast numerical array expression evaluator for Python, NumPy, PyTables, pandas, bcolz and more |
|
||||||
| [h5py][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | HDF5 for Python -- The h5py package is a Pythonic interface to the HDF5 binary data format. |
|
|
||||||
| [coverage.py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The coverage tool for Python |
|
| [coverage.py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The coverage tool for Python |
|
||||||
|
| [h5py][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | HDF5 for Python -- The h5py package is a Pythonic interface to the HDF5 binary data format. |
|
||||||
| [River][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 🌊 Online machine learning in Python |
|
| [River][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | 🌊 Online machine learning in Python |
|
||||||
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
|
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
|
||||||
| [Dependency Injector][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Dependency injection framework for Python, uses Windows TravisCI |
|
| [Dependency Injector][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Dependency injection framework for Python, uses Windows TravisCI |
|
||||||
@@ -156,18 +156,22 @@ Here are some repos that use cibuildwheel.
|
|||||||
| [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. |
|
| [ruptures][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example. |
|
||||||
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
|
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | QUIC and HTTP/3 implementation in Python |
|
||||||
| [google neuroglancer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | WebGL-based viewer for volumetric data |
|
| [google neuroglancer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | WebGL-based viewer for volumetric data |
|
||||||
| [AutoPy][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
|
|
||||||
| [pikepdf][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by qpdf |
|
| [pikepdf][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python library for reading and writing PDF, powered by qpdf |
|
||||||
|
| [AutoPy][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
|
||||||
| [Parselmouth][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels. |
|
| [Parselmouth][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels. |
|
||||||
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson |
|
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | Python wrapper around rapidjson |
|
||||||
| [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS ¶ |
|
| [Rtree][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Rtree: spatial index for Python GIS ¶ |
|
||||||
|
| [python-snappy][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Python bindings for the snappy google library |
|
||||||
|
| [markupsafe][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Safely add untrusted strings to HTML/XML markup. |
|
||||||
| [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Kernel Density Estimation in Python |
|
| [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Kernel Density Estimation in Python |
|
||||||
| [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing |
|
| [cyvcf2][] | ![github icon][] | ![apple icon][] ![linux icon][] | cython + htslib == fast VCF and BCF processing |
|
||||||
| [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a CMake-based build system |
|
| [pybind11 cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a CMake-based build system |
|
||||||
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system |
|
| [pybind11 python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Example pybind11 module built with a Python-based build system |
|
||||||
|
| [sourmash][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Compute and compare MinHash signatures for DNA data sets. |
|
||||||
| [dd-trace-py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Uses custom alternate arch emulation on GitHub |
|
| [dd-trace-py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Uses custom alternate arch emulation on GitHub |
|
||||||
| [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Jupyter-friendly Python interface for C++ MINUIT2 |
|
| [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Jupyter-friendly Python interface for C++ MINUIT2 |
|
||||||
| [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq |
|
| [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | Python bindings for jq |
|
||||||
|
| [time-machine][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Time mocking library using only the CPython C API. |
|
||||||
| [matrixprofile][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python 3 library making time series data mining tasks, utilizing matrix profile algorithms, accessible to everyone. |
|
| [matrixprofile][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python 3 library making time series data mining tasks, utilizing matrix profile algorithms, accessible to everyone. |
|
||||||
| [CTranslate2][] | ![github icon][] | ![apple icon][] ![linux icon][] | Includes libraries from the [Intel oneAPI toolkit](https://software.intel.com/content/www/us/en/develop/tools/oneapi/base-toolkit.html). The Linux wheels also include CUDA libraries for GPU execution. |
|
| [CTranslate2][] | ![github icon][] | ![apple icon][] ![linux icon][] | Includes libraries from the [Intel oneAPI toolkit](https://software.intel.com/content/www/us/en/develop/tools/oneapi/base-toolkit.html). The Linux wheels also include CUDA libraries for GPU execution. |
|
||||||
| [Tokenizer][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] | Fast and customizable text tokenization library with BPE and SentencePiece support |
|
| [Tokenizer][] | ![github icon][] ![travisci icon][] | ![apple icon][] ![linux icon][] | Fast and customizable text tokenization library with BPE and SentencePiece support |
|
||||||
@@ -179,8 +183,9 @@ Here are some repos that use cibuildwheel.
|
|||||||
| [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy |
|
| [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The interface between FastJet and NumPy |
|
||||||
| [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA and NumPy |
|
| [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | The interface between PYTHIA and NumPy |
|
||||||
| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
|
| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
|
||||||
| [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies |
|
|
||||||
| [Imagecodecs (fork)][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] | Over 20 external dependencies in compiled libraries, custom docker image, `libomp`, `openblas` and `install_name_tool` for macOS. |
|
| [Imagecodecs (fork)][] | ![azurepipelines icon][] | ![apple icon][] ![linux icon][] | Over 20 external dependencies in compiled libraries, custom docker image, `libomp`, `openblas` and `install_name_tool` for macOS. |
|
||||||
|
| [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies |
|
||||||
|
| [polaroid][] | ![github icon][] | ![apple icon][] ![linux icon][] ![windows icon][] | Full range of wheels for setuptools rust, with auto release and PyPI deploy. |
|
||||||
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
|
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
|
||||||
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 |
|
| [pybind11 scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | An example combining scikit-build and pybind11 |
|
||||||
|
|
||||||
@@ -194,8 +199,8 @@ Here are some repos that use cibuildwheel.
|
|||||||
[pyzmq]: https://github.com/zeromq/pyzmq
|
[pyzmq]: https://github.com/zeromq/pyzmq
|
||||||
[aiortc]: https://github.com/aiortc/aiortc
|
[aiortc]: https://github.com/aiortc/aiortc
|
||||||
[numexpr]: https://github.com/pydata/numexpr
|
[numexpr]: https://github.com/pydata/numexpr
|
||||||
[h5py]: https://github.com/h5py/h5py
|
|
||||||
[coverage.py]: https://github.com/nedbat/coveragepy
|
[coverage.py]: https://github.com/nedbat/coveragepy
|
||||||
|
[h5py]: https://github.com/h5py/h5py
|
||||||
[River]: https://github.com/online-ml/river
|
[River]: https://github.com/online-ml/river
|
||||||
[PyAV]: https://github.com/PyAV-Org/PyAV
|
[PyAV]: https://github.com/PyAV-Org/PyAV
|
||||||
[Dependency Injector]: https://github.com/ets-labs/python-dependency-injector
|
[Dependency Injector]: https://github.com/ets-labs/python-dependency-injector
|
||||||
@@ -203,18 +208,22 @@ Here are some repos that use cibuildwheel.
|
|||||||
[ruptures]: https://github.com/deepcharles/ruptures
|
[ruptures]: https://github.com/deepcharles/ruptures
|
||||||
[aioquic]: https://github.com/aiortc/aioquic
|
[aioquic]: https://github.com/aiortc/aioquic
|
||||||
[google neuroglancer]: https://github.com/google/neuroglancer
|
[google neuroglancer]: https://github.com/google/neuroglancer
|
||||||
[AutoPy]: https://github.com/autopilot-rs/autopy
|
|
||||||
[pikepdf]: https://github.com/pikepdf/pikepdf
|
[pikepdf]: https://github.com/pikepdf/pikepdf
|
||||||
|
[AutoPy]: https://github.com/autopilot-rs/autopy
|
||||||
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth
|
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth
|
||||||
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
|
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
|
||||||
[Rtree]: https://github.com/Toblerity/rtree
|
[Rtree]: https://github.com/Toblerity/rtree
|
||||||
|
[python-snappy]: https://github.com/andrix/python-snappy
|
||||||
|
[markupsafe]: https://github.com/pallets/markupsafe
|
||||||
[KDEpy]: https://github.com/tommyod/KDEpy
|
[KDEpy]: https://github.com/tommyod/KDEpy
|
||||||
[cyvcf2]: https://github.com/brentp/cyvcf2
|
[cyvcf2]: https://github.com/brentp/cyvcf2
|
||||||
[pybind11 cmake_example]: https://github.com/pybind/cmake_example
|
[pybind11 cmake_example]: https://github.com/pybind/cmake_example
|
||||||
[pybind11 python_example]: https://github.com/pybind/python_example
|
[pybind11 python_example]: https://github.com/pybind/python_example
|
||||||
|
[sourmash]: https://github.com/dib-lab/sourmash
|
||||||
[dd-trace-py]: https://github.com/DataDog/dd-trace-py
|
[dd-trace-py]: https://github.com/DataDog/dd-trace-py
|
||||||
[iminuit]: https://github.com/scikit-hep/iminuit
|
[iminuit]: https://github.com/scikit-hep/iminuit
|
||||||
[jq.py]: https://github.com/mwilliamson/jq.py
|
[jq.py]: https://github.com/mwilliamson/jq.py
|
||||||
|
[time-machine]: https://github.com/adamchainz/time-machine
|
||||||
[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile
|
[matrixprofile]: https://github.com/matrix-profile-foundation/matrixprofile
|
||||||
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
|
[CTranslate2]: https://github.com/OpenNMT/CTranslate2
|
||||||
[Tokenizer]: https://github.com/OpenNMT/Tokenizer
|
[Tokenizer]: https://github.com/OpenNMT/Tokenizer
|
||||||
@@ -226,8 +235,9 @@ Here are some repos that use cibuildwheel.
|
|||||||
[pyjet]: https://github.com/scikit-hep/pyjet
|
[pyjet]: https://github.com/scikit-hep/pyjet
|
||||||
[numpythia]: https://github.com/scikit-hep/numpythia
|
[numpythia]: https://github.com/scikit-hep/numpythia
|
||||||
[fathon]: https://github.com/stfbnc/fathon
|
[fathon]: https://github.com/stfbnc/fathon
|
||||||
[pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext
|
|
||||||
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
|
[Imagecodecs (fork)]: https://github.com/czaki/imagecodecs_build
|
||||||
|
[pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext
|
||||||
|
[polaroid]: https://github.com/daggy1234/polaroid
|
||||||
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
|
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
|
||||||
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
|
[pybind11 scikit_build_example]: https://github.com/pybind/scikit_build_example
|
||||||
|
|
||||||
@@ -241,52 +251,57 @@ Here are some repos that use cibuildwheel.
|
|||||||
[apple icon]: docs/data/readme_icons/apple.svg
|
[apple icon]: docs/data/readme_icons/apple.svg
|
||||||
[linux icon]: docs/data/readme_icons/linux.svg
|
[linux icon]: docs/data/readme_icons/linux.svg
|
||||||
|
|
||||||
<!-- scikit-learn: 43800, last pushed 0 days ago -->
|
<!-- scikit-learn: 44749, last pushed 0 days ago -->
|
||||||
<!-- Matplotlib: 12963, last pushed 0 days ago -->
|
<!-- Matplotlib: 13218, last pushed 0 days ago -->
|
||||||
<!-- MyPy: 9770, last pushed 0 days ago -->
|
<!-- MyPy: 10122, last pushed 0 days ago -->
|
||||||
<!-- psutil: 6990, last pushed 5 days ago -->
|
<!-- psutil: 7128, last pushed 7 days ago -->
|
||||||
<!-- scikit-image: 4143, last pushed 0 days ago -->
|
<!-- scikit-image: 4220, last pushed 0 days ago -->
|
||||||
<!-- twisted-iocpsupport: 4140, last pushed 7 days ago -->
|
<!-- twisted-iocpsupport: 4184, last pushed 0 days ago -->
|
||||||
<!-- websockets: 3146, last pushed 9 days ago -->
|
<!-- websockets: 3217, last pushed 13 days ago -->
|
||||||
<!-- pyzmq: 2675, last pushed 1 days ago -->
|
<!-- pyzmq: 2707, last pushed 13 days ago -->
|
||||||
<!-- aiortc: 2113, last pushed 7 days ago -->
|
<!-- aiortc: 2244, last pushed 0 days ago -->
|
||||||
<!-- numexpr: 1512, last pushed 16 days ago -->
|
<!-- numexpr: 1548, last pushed 0 days ago -->
|
||||||
<!-- h5py: 1474, last pushed 2 days ago -->
|
<!-- coverage.py: 1515, last pushed 1 days ago -->
|
||||||
<!-- coverage.py: 1471, last pushed 2 days ago -->
|
<!-- h5py: 1485, last pushed 0 days ago -->
|
||||||
<!-- River: 1296, last pushed 0 days ago -->
|
<!-- River: 1428, last pushed 0 days ago -->
|
||||||
<!-- PyAV: 1142, last pushed 13 days ago -->
|
<!-- PyAV: 1182, last pushed 2 days ago -->
|
||||||
<!-- Dependency Injector: 1070, last pushed 0 days ago -->
|
<!-- Dependency Injector: 1163, last pushed 0 days ago -->
|
||||||
<!-- PyTables: 1001, last pushed 6 days ago -->
|
<!-- PyTables: 1005, last pushed 18 days ago -->
|
||||||
<!-- ruptures: 589, last pushed 3 days ago -->
|
<!-- ruptures: 637, last pushed 1 days ago -->
|
||||||
<!-- aioquic: 571, last pushed 78 days ago -->
|
<!-- aioquic: 587, last pushed 15 days ago -->
|
||||||
<!-- google neuroglancer: 555, last pushed 0 days ago -->
|
<!-- google neuroglancer: 568, last pushed 5 days ago -->
|
||||||
<!-- AutoPy: 517, last pushed 134 days ago -->
|
<!-- pikepdf: 548, last pushed 0 days ago -->
|
||||||
<!-- pikepdf: 517, last pushed 5 days ago -->
|
<!-- AutoPy: 519, last pushed 175 days ago -->
|
||||||
<!-- Parselmouth: 450, last pushed 1 days ago -->
|
<!-- Parselmouth: 471, last pushed 0 days ago -->
|
||||||
<!-- python-rapidjson: 410, last pushed 39 days ago -->
|
<!-- python-rapidjson: 415, last pushed 80 days ago -->
|
||||||
<!-- Rtree: 387, last pushed 28 days ago -->
|
<!-- Rtree: 388, last pushed 69 days ago -->
|
||||||
<!-- KDEpy: 235, last pushed 37 days ago -->
|
<!-- python-snappy: 386, last pushed 6 days ago -->
|
||||||
<!-- cyvcf2: 233, last pushed 0 days ago -->
|
<!-- markupsafe: 365, last pushed 2 days ago -->
|
||||||
<!-- pybind11 cmake_example: 226, last pushed 35 days ago -->
|
<!-- KDEpy: 242, last pushed 16 days ago -->
|
||||||
<!-- pybind11 python_example: 224, last pushed 73 days ago -->
|
<!-- cyvcf2: 242, last pushed 17 days ago -->
|
||||||
<!-- dd-trace-py: 206, last pushed 0 days ago -->
|
<!-- pybind11 cmake_example: 239, last pushed 77 days ago -->
|
||||||
<!-- iminuit: 166, last pushed 25 days ago -->
|
<!-- pybind11 python_example: 235, last pushed 22 days ago -->
|
||||||
<!-- jq.py: 140, last pushed 102 days ago -->
|
<!-- sourmash: 235, last pushed 0 days ago -->
|
||||||
<!-- matrixprofile: 124, last pushed 2 days ago -->
|
<!-- dd-trace-py: 217, last pushed 0 days ago -->
|
||||||
<!-- CTranslate2: 123, last pushed 0 days ago -->
|
<!-- iminuit: 172, last pushed 20 days ago -->
|
||||||
<!-- Tokenizer: 115, last pushed 3 days ago -->
|
<!-- jq.py: 147, last pushed 7 days ago -->
|
||||||
<!-- bx-python: 95, last pushed 30 days ago -->
|
<!-- time-machine: 139, last pushed 4 days ago -->
|
||||||
<!-- boost-histogram: 66, last pushed 0 days ago -->
|
<!-- matrixprofile: 138, last pushed 36 days ago -->
|
||||||
<!-- pybase64: 54, last pushed 0 days ago -->
|
<!-- CTranslate2: 133, last pushed 0 days ago -->
|
||||||
<!-- TgCrypto: 51, last pushed 65 days ago -->
|
<!-- Tokenizer: 126, last pushed 0 days ago -->
|
||||||
<!-- etebase-py: 40, last pushed 17 days ago -->
|
<!-- bx-python: 97, last pushed 2 days ago -->
|
||||||
<!-- pyjet: 27, last pushed 3 days ago -->
|
<!-- boost-histogram: 69, last pushed 0 days ago -->
|
||||||
<!-- numpythia: 24, last pushed 9 days ago -->
|
<!-- pybase64: 56, last pushed 1 days ago -->
|
||||||
<!-- fathon: 20, last pushed 4 days ago -->
|
<!-- TgCrypto: 52, last pushed 106 days ago -->
|
||||||
<!-- pyinstrument_cext: 10, last pushed 57 days ago -->
|
<!-- etebase-py: 46, last pushed 58 days ago -->
|
||||||
<!-- Imagecodecs (fork): 10, last pushed 7 days ago -->
|
<!-- pyjet: 27, last pushed 7 days ago -->
|
||||||
<!-- xmlstarlet: 7, last pushed 2 days ago -->
|
<!-- numpythia: 25, last pushed 7 days ago -->
|
||||||
<!-- pybind11 scikit_build_example: 2, last pushed 18 days ago -->
|
<!-- fathon: 22, last pushed 31 days ago -->
|
||||||
|
<!-- Imagecodecs (fork): 16, last pushed 4 days ago -->
|
||||||
|
<!-- pyinstrument_cext: 10, last pushed 19 days ago -->
|
||||||
|
<!-- polaroid: 9, last pushed 0 days ago -->
|
||||||
|
<!-- xmlstarlet: 7, last pushed 1 days ago -->
|
||||||
|
<!-- pybind11 scikit_build_example: 4, last pushed 40 days ago -->
|
||||||
|
|
||||||
<!-- END bin/projects.py -->
|
<!-- END bin/projects.py -->
|
||||||
|
|
||||||
@@ -310,6 +325,28 @@ Changelog
|
|||||||
|
|
||||||
<!--changelog-start-->
|
<!--changelog-start-->
|
||||||
|
|
||||||
|
### v1.11.0
|
||||||
|
|
||||||
|
- 📚 Lots of docs improvements! (#650, #623, #616, #609, #606)
|
||||||
|
- 🐛 Fix nuget "Package is not found" error on Windows. (#653)
|
||||||
|
- ⚠️ cibuildwheel will no longer build Windows 2.7 wheels, unless you specify a custom toolchain using `DISTUTILS_USE_SDK=1` and `MSSdk=1`. This is because Microsoft have stopped distributing Visual C++ Compiler for Python 2.7. See [this FAQ entry](https://cibuildwheel.readthedocs.io/en/stable/faq/#windows-and-python-27) for more details. (#649)
|
||||||
|
- 🐛 Fix crash on Windows due to missing `which` command (#641).
|
||||||
|
|
||||||
|
### v1.10.0
|
||||||
|
|
||||||
|
_22 Feb 2021_
|
||||||
|
|
||||||
|
- ✨ Added `manylinux_2_24` support. To use these new Debian-based manylinux
|
||||||
|
images, set your [manylinux image](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image)
|
||||||
|
options to `manylinux_2_24`.
|
||||||
|
- 🛠 On macOS, we now set `MACOSX_DEPLOYMENT_TARGET` in before running
|
||||||
|
`CIBW_BEFORE_ALL`. This is useful when using `CIBW_BEFORE_ALL` to build a
|
||||||
|
shared library.
|
||||||
|
- 🛠 An empty `CIBW_BUILD` option is now the same as being unset i.e, `*`.
|
||||||
|
This makes some build matrix configuration easier. (#588)
|
||||||
|
- 📚 Neatened up documentation - added tabs to a few places (#576), fixed some
|
||||||
|
formatting issues.
|
||||||
|
|
||||||
### v1.9.0
|
### v1.9.0
|
||||||
|
|
||||||
_5 February 2021_
|
_5 February 2021_
|
||||||
@@ -337,14 +374,16 @@ _5 February 2021_
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
uses: joerick/cibuildwheel@v1.9.0
|
uses: joerick/cibuildwheel@version # e.g. v1.9.0
|
||||||
with:
|
with:
|
||||||
output-dir: wheelhouse
|
output-dir: wheelhouse
|
||||||
# env:
|
# env:
|
||||||
# CIBW_SOME_OPTION: value
|
# CIBW_SOME_OPTION: value
|
||||||
```
|
```
|
||||||
|
|
||||||
This saves a bit of boilerplate, and you can [use Dependabot to keep the
|
This saves a bit of boilerplate, and you can [use Dependabot to keep the
|
||||||
pinned version up-to-date](https://cibuildwheel.readthedocs.io/en/stable/faq/#automatic-updates).
|
pinned version up-to-date](https://cibuildwheel.readthedocs.io/en/stable/faq/#automatic-updates).
|
||||||
|
|
||||||
- ✨ Added `auto64` and `auto32` shortcuts to the
|
- ✨ Added `auto64` and `auto32` shortcuts to the
|
||||||
[CIBW_ARCHS](https://cibuildwheel.readthedocs.io/en/stable/options/#archs)
|
[CIBW_ARCHS](https://cibuildwheel.readthedocs.io/en/stable/options/#archs)
|
||||||
option. (#553)
|
option. (#553)
|
||||||
@@ -459,6 +498,7 @@ _9 September 2020_
|
|||||||
[still on Python 3.9b3](https://github.com/pypa/manylinux/issues/758), not a
|
[still on Python 3.9b3](https://github.com/pypa/manylinux/issues/758), not a
|
||||||
release candidate. We'd advise holding off on distributing 3.9 ppc64le wheels
|
release candidate. We'd advise holding off on distributing 3.9 ppc64le wheels
|
||||||
until a subsequent version of cibuildwheel.
|
until a subsequent version of cibuildwheel.
|
||||||
|
|
||||||
- 🌟 Add Gitlab CI support. Gitlab CI can now build Linux wheels, using
|
- 🌟 Add Gitlab CI support. Gitlab CI can now build Linux wheels, using
|
||||||
cibuildwheel. (#419)
|
cibuildwheel. (#419)
|
||||||
- 🐛 Fix a bug that causes pyproject.toml dependencies to fail to install on
|
- 🐛 Fix a bug that causes pyproject.toml dependencies to fail to install on
|
||||||
@@ -556,6 +596,7 @@ _2 May 2020_
|
|||||||
options - if you always want to use the latest toolchain, you can still do
|
options - if you always want to use the latest toolchain, you can still do
|
||||||
that, or you can specify your own pip constraints file and manylinux image.
|
that, or you can specify your own pip constraints file and manylinux image.
|
||||||
(#256)
|
(#256)
|
||||||
|
|
||||||
- ✨ Added `package_dir` command line option, meaning we now support building
|
- ✨ Added `package_dir` command line option, meaning we now support building
|
||||||
a package that lives in a subdirectory and pulls in files from the wider
|
a package that lives in a subdirectory and pulls in files from the wider
|
||||||
project. See [the `package_dir` option help](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line-options)
|
project. See [the `package_dir` option help](https://cibuildwheel.readthedocs.io/en/stable/options/#command-line-options)
|
||||||
@@ -566,6 +607,7 @@ _2 May 2020_
|
|||||||
will be copied into the Docker container. If your builds are slower on this
|
will be copied into the Docker container. If your builds are slower on this
|
||||||
version, that's likely the reason. `cd` to your project and then call
|
version, that's likely the reason. `cd` to your project and then call
|
||||||
`cibuildwheel` from there. (#319, #295)
|
`cibuildwheel` from there. (#319, #295)
|
||||||
|
|
||||||
- 🛠 On macOS, we make `MACOSX_DEPLOYMENT_TARGET` default to `10.9` if it's
|
- 🛠 On macOS, we make `MACOSX_DEPLOYMENT_TARGET` default to `10.9` if it's
|
||||||
not set. This should make things more consistent between Python versions.
|
not set. This should make things more consistent between Python versions.
|
||||||
- 🛠 Dependency updates - CPython 3.7.7, CPython 2.7.18, Pypy 7.3.1.
|
- 🛠 Dependency updates - CPython 3.7.7, CPython 2.7.18, Pypy 7.3.1.
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ jobs:
|
|||||||
- task: UsePythonVersion@0
|
- task: UsePythonVersion@0
|
||||||
inputs:
|
inputs:
|
||||||
versionSpec: '3.6'
|
versionSpec: '3.6'
|
||||||
- script: choco install vcpython27 -f -y
|
|
||||||
displayName: Install Visual C++ for Python 2.7
|
|
||||||
- bash: |
|
- bash: |
|
||||||
python -m pip install -e ".[dev]" pytest-azurepipelines
|
python -m pip install -e ".[dev]" pytest-azurepipelines
|
||||||
python ./bin/run_tests.py
|
python ./bin/run_tests.py
|
||||||
@@ -39,8 +37,6 @@ jobs:
|
|||||||
- task: UsePythonVersion@0
|
- task: UsePythonVersion@0
|
||||||
inputs:
|
inputs:
|
||||||
versionSpec: '3.8'
|
versionSpec: '3.8'
|
||||||
- script: choco install vcpython27 -f -y
|
|
||||||
displayName: Install Visual C++ for Python 2.7
|
|
||||||
- bash: |
|
- bash: |
|
||||||
python -m pip install -e ".[dev]" pytest-azurepipelines
|
python -m pip install -e ".[dev]" pytest-azurepipelines
|
||||||
python ./bin/run_tests.py
|
python ./bin/run_tests.py
|
||||||
|
|||||||
+27
-24
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -19,30 +21,32 @@ config = [
|
|||||||
('cibuildwheel/__init__.py', "__version__ = '{}'"),
|
('cibuildwheel/__init__.py', "__version__ = '{}'"),
|
||||||
('docs/faq.md', "cibuildwheel=={}"),
|
('docs/faq.md', "cibuildwheel=={}"),
|
||||||
('docs/faq.md', "cibuildwheel@v{}"),
|
('docs/faq.md', "cibuildwheel@v{}"),
|
||||||
('docs/setup.md', "cibuildwheel@v{}"),
|
('docs/setup.md', "cibuildwheel=={}"),
|
||||||
('examples/*', "cibuildwheel=={}"),
|
('examples/*', "cibuildwheel=={}"),
|
||||||
('examples/*', "cibuildwheel@v{}"),
|
('examples/*', "cibuildwheel@v{}"),
|
||||||
('setup.cfg', "version = {}"),
|
('setup.cfg', "version = {}"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
RED = "\u001b[31m"
|
||||||
|
GREEN = "\u001b[32m"
|
||||||
|
OFF = "\u001b[0m"
|
||||||
|
|
||||||
|
|
||||||
# This file requires Python 3.7
|
|
||||||
# Setting -> None will cause MyPy to notice this.
|
|
||||||
@click.command()
|
@click.command()
|
||||||
def bump_version():
|
def bump_version() -> None:
|
||||||
current_version = cibuildwheel.__version__
|
current_version = cibuildwheel.__version__
|
||||||
|
|
||||||
try:
|
try:
|
||||||
commit_date_str = subprocess.run([
|
commit_date_str = subprocess.run([
|
||||||
'git',
|
'git',
|
||||||
'show', '-s', '--pretty=format:%ci',
|
'show', '--no-patch', '--pretty=format:%ci',
|
||||||
f'v{current_version}^{{commit}}'
|
f'v{current_version}^{{commit}}',
|
||||||
], check=True, capture_output=True, encoding='utf8').stdout
|
], check=True, capture_output=True, encoding='utf8').stdout
|
||||||
commit_date_parts = commit_date_str.split(' ')
|
cd_date, cd_time, cd_tz = commit_date_str.split(' ')
|
||||||
|
|
||||||
|
url_opts = urllib.parse.urlencode({'q': f'is:pr merged:>{cd_date}T{cd_time}{cd_tz}'})
|
||||||
|
url = f'https://github.com/joerick/cibuildwheel/pulls?{url_opts}'
|
||||||
|
|
||||||
url = 'https://github.com/joerick/cibuildwheel/pulls?' + urllib.parse.urlencode({
|
|
||||||
'q': f'is:pr merged:>{commit_date_parts[0]}T{commit_date_parts[1]}{commit_date_parts[2]}',
|
|
||||||
})
|
|
||||||
print(f'PRs merged since last release:\n {url}')
|
print(f'PRs merged since last release:\n {url}')
|
||||||
print()
|
print()
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
@@ -56,8 +60,10 @@ def bump_version():
|
|||||||
print('error: Uncommitted changes detected.')
|
print('error: Uncommitted changes detected.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
print( 'Current version:', current_version) # noqa
|
print( 'Current version:', current_version) # noqa
|
||||||
new_version = input(' New version: ').strip()
|
new_version = input(' New version: ').strip()
|
||||||
|
# fmt: on
|
||||||
|
|
||||||
try:
|
try:
|
||||||
Version(new_version)
|
Version(new_version)
|
||||||
@@ -72,7 +78,7 @@ def bump_version():
|
|||||||
paths = [Path(p) for p in glob.glob(path_pattern)]
|
paths = [Path(p) for p in glob.glob(path_pattern)]
|
||||||
|
|
||||||
if not paths:
|
if not paths:
|
||||||
print(f'error: Pattern {path_pattern} didn’t match any files')
|
print(f"error: Pattern {path_pattern} didn't match any files")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
find_pattern = version_pattern.format(current_version)
|
find_pattern = version_pattern.format(current_version)
|
||||||
@@ -84,11 +90,11 @@ def bump_version():
|
|||||||
if find_pattern in contents:
|
if find_pattern in contents:
|
||||||
found_at_least_one_file_needing_update = True
|
found_at_least_one_file_needing_update = True
|
||||||
actions.append(
|
actions.append(
|
||||||
(path, find_pattern, replace_pattern)
|
(path, find_pattern, replace_pattern,)
|
||||||
)
|
)
|
||||||
|
|
||||||
if not found_at_least_one_file_needing_update:
|
if not found_at_least_one_file_needing_update:
|
||||||
print(f'error: Didn’t find any occurrences of “{find_pattern}” in “{path_pattern}”')
|
print(f'''error: Didn't find any occurrences of "{find_pattern}" in "{path_pattern}"''')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print()
|
print()
|
||||||
@@ -96,10 +102,8 @@ def bump_version():
|
|||||||
print()
|
print()
|
||||||
|
|
||||||
for action in actions:
|
for action in actions:
|
||||||
print('{} {red}{}{off} → {green}{}{off}'.format(
|
path, find, replace = action
|
||||||
*action,
|
print(f'{path} {RED}{find}{OFF} → {GREEN}{replace}{OFF}')
|
||||||
red="\u001b[31m", green="\u001b[32m", off="\u001b[0m"
|
|
||||||
))
|
|
||||||
|
|
||||||
print(f'Then commit, and tag as v{new_version}')
|
print(f'Then commit, and tag as v{new_version}')
|
||||||
|
|
||||||
@@ -123,21 +127,20 @@ def bump_version():
|
|||||||
|
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'git', 'commit',
|
'git', 'commit',
|
||||||
'-a',
|
'--all',
|
||||||
'-m', f'Bump version: v{new_version}'
|
f"--message='Bump version: v{new_version}'",
|
||||||
], check=True)
|
], check=True)
|
||||||
|
|
||||||
subprocess.run([
|
subprocess.run([
|
||||||
'git', 'tag',
|
'git', 'tag',
|
||||||
'-a',
|
'--annotate',
|
||||||
'-m', f'v{new_version}',
|
f"--message='v{new_version}'",
|
||||||
f'v{new_version}'
|
f'v{new_version}',
|
||||||
], check=True)
|
], check=True)
|
||||||
|
|
||||||
print('Done.')
|
print('Done.')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
os.chdir(os.path.dirname(__file__))
|
os.chdir(Path(__file__).parent.parent.resolve())
|
||||||
os.chdir('..')
|
|
||||||
bump_version()
|
bump_version()
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
@@ -49,17 +51,18 @@ def main():
|
|||||||
return
|
return
|
||||||
|
|
||||||
shell('git commit -a -m "Update dependencies"', check=True)
|
shell('git commit -a -m "Update dependencies"', check=True)
|
||||||
run(
|
body = textwrap.dedent(f'''
|
||||||
[
|
|
||||||
'gh', 'pr', 'create',
|
|
||||||
'--repo', 'joerick/cibuildwheel',
|
|
||||||
'--base', 'master',
|
|
||||||
'--title', 'Update dependencies',
|
|
||||||
'--body', textwrap.dedent(f'''
|
|
||||||
Update the versions of our dependencies.
|
Update the versions of our dependencies.
|
||||||
|
|
||||||
PR generated by `{os.path.basename(__file__)}`.
|
PR generated by `{os.path.basename(__file__)}`.
|
||||||
''')
|
''')
|
||||||
|
run(
|
||||||
|
[
|
||||||
|
'gh', 'pr', 'create',
|
||||||
|
'--repo=joerick/cibuildwheel',
|
||||||
|
'--base=master',
|
||||||
|
"--title='Update dependencies'",
|
||||||
|
f"--body='{body}'",
|
||||||
],
|
],
|
||||||
check=True
|
check=True
|
||||||
)
|
)
|
||||||
|
|||||||
+13
-11
@@ -9,14 +9,17 @@ Suggested usage:
|
|||||||
git diff
|
git diff
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import builtins
|
import builtins
|
||||||
import functools
|
import functools
|
||||||
|
import textwrap
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import xml.dom.minidom
|
import xml.dom.minidom
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional, TextIO
|
from typing import Any, TextIO
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import yaml
|
import yaml
|
||||||
@@ -38,7 +41,7 @@ ICONS = (
|
|||||||
class Project:
|
class Project:
|
||||||
NAME: int = 0
|
NAME: int = 0
|
||||||
|
|
||||||
def __init__(self, config: Dict[str, Any], github: Optional[Github] = None):
|
def __init__(self, config: dict[str, Any], github: Github | None = None):
|
||||||
try:
|
try:
|
||||||
self.name: str = config["name"]
|
self.name: str = config["name"]
|
||||||
self.gh: str = config["gh"]
|
self.gh: str = config["gh"]
|
||||||
@@ -48,8 +51,8 @@ class Project:
|
|||||||
|
|
||||||
self.stars_repo: str = config.get("stars", self.gh)
|
self.stars_repo: str = config.get("stars", self.gh)
|
||||||
self.notes: str = config.get("notes", "")
|
self.notes: str = config.get("notes", "")
|
||||||
self.ci: List[str] = config.get("ci", [])
|
self.ci: list[str] = config.get("ci", [])
|
||||||
self.os: List[str] = config.get("os", [])
|
self.os: list[str] = config.get("os", [])
|
||||||
|
|
||||||
self.online = github is not None
|
self.online = github is not None
|
||||||
if github is not None:
|
if github is not None:
|
||||||
@@ -72,7 +75,7 @@ class Project:
|
|||||||
name_len = len(self.name) + 4
|
name_len = len(self.name) + 4
|
||||||
self.__class__.NAME = max(self.__class__.NAME, name_len)
|
self.__class__.NAME = max(self.__class__.NAME, name_len)
|
||||||
|
|
||||||
def __lt__(self, other: "Project") -> bool:
|
def __lt__(self, other: Project) -> bool:
|
||||||
if self.online:
|
if self.online:
|
||||||
return self.num_stars < other.num_stars
|
return self.num_stars < other.num_stars
|
||||||
else:
|
else:
|
||||||
@@ -80,10 +83,9 @@ class Project:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def header(cls) -> str:
|
def header(cls) -> str:
|
||||||
return (
|
return textwrap.dedent(f"""\
|
||||||
f"| {'Name':{cls.NAME}} | CI | OS | Notes |\n"
|
| {'Name':{cls.NAME}} | CI | OS | Notes |
|
||||||
f"|{'':-^{cls.NAME+2 }}|----|----|:------|"
|
|{'':-^{cls.NAME+2 }}|----|----|:------|""")
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def namelink(self) -> str:
|
def namelink(self) -> str:
|
||||||
@@ -140,7 +142,7 @@ def path_for_icon(icon_name: str) -> Path:
|
|||||||
|
|
||||||
|
|
||||||
def str_projects(
|
def str_projects(
|
||||||
config: List[Dict[str, Any]], *, online: bool = True, auth: Optional[str] = None
|
config: list[dict[str, Any]], *, online: bool = True, auth: str | None = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
io = StringIO()
|
io = StringIO()
|
||||||
print = functools.partial(builtins.print, file=io)
|
print = functools.partial(builtins.print, file=io)
|
||||||
@@ -178,7 +180,7 @@ def str_projects(
|
|||||||
@click.option("--auth", help="GitHub authentication token")
|
@click.option("--auth", help="GitHub authentication token")
|
||||||
@click.option("--readme", type=click.File("r+"), help="Modify a readme file if given")
|
@click.option("--readme", type=click.File("r+"), help="Modify a readme file if given")
|
||||||
def projects(
|
def projects(
|
||||||
input: TextIO, online: bool, auth: Optional[str], readme: Optional[TextIO]
|
input: TextIO, online: bool, auth: str | None, readme: TextIO | None
|
||||||
) -> None:
|
) -> None:
|
||||||
config = yaml.safe_load(input)
|
config = yaml.safe_load(input)
|
||||||
output = str_projects(config, online=online, auth=auth)
|
output = str_projects(config, online=online, auth=auth)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
@@ -123,13 +125,14 @@ def run_example_ci_configs(config_files=None):
|
|||||||
shutil.copyfile(src_config_file, dst_config_file)
|
shutil.copyfile(src_config_file, dst_config_file)
|
||||||
|
|
||||||
run(['git', 'add', example_project], check=True)
|
run(['git', 'add', example_project], check=True)
|
||||||
run(['git', 'commit', '--no-verify', '-m', textwrap.dedent(f'''
|
message = textwrap.dedent(f'''
|
||||||
Test example minimal configs
|
Test example minimal configs
|
||||||
|
|
||||||
Testing files: {config_files}
|
Testing files: {config_files}
|
||||||
Generated from branch: {previous_branch}
|
Generated from branch: {previous_branch}
|
||||||
Time: {timestamp}
|
Time: {timestamp}
|
||||||
''')], check=True)
|
''')
|
||||||
|
run(['git', 'commit', '--no-verify', '--message', message], check=True)
|
||||||
shell(f'git subtree --prefix={example_project} push origin {branch_name}', check=True)
|
shell(f'git subtree --prefix={example_project} push origin {branch_name}', check=True)
|
||||||
|
|
||||||
print('---')
|
print('---')
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ if __name__ == '__main__':
|
|||||||
# run the docker unit tests only on Linux
|
# run the docker unit tests only on Linux
|
||||||
if sys.platform.startswith('linux'):
|
if sys.platform.startswith('linux'):
|
||||||
unit_test_args += ['--run-docker']
|
unit_test_args += ['--run-docker']
|
||||||
subprocess.check_call(unit_test_args)
|
subprocess.run(unit_test_args, check=True)
|
||||||
|
|
||||||
# run the integration tests
|
# run the integration tests
|
||||||
subprocess.check_call([sys.executable, '-m', 'pytest', '-x', '--durations', '0', '--timeout=2400', 'test'])
|
subprocess.run([sys.executable, '-m', 'pytest', '-x', '--durations', '0', '--timeout=2400', 'test'], check=True)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
+42
-25
@@ -1,11 +1,12 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import configparser
|
import configparser
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from collections import namedtuple
|
from typing import NamedTuple
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
@@ -20,20 +21,21 @@ PYTHON_VERSIONS = ['27', '35', '36', '37', '38', '39']
|
|||||||
|
|
||||||
if '--no-docker' in sys.argv:
|
if '--no-docker' in sys.argv:
|
||||||
for python_version in PYTHON_VERSIONS:
|
for python_version in PYTHON_VERSIONS:
|
||||||
subprocess.check_call([
|
subprocess.run([
|
||||||
f'./env{python_version}/bin/pip-compile',
|
f'./env{python_version}/bin/pip-compile',
|
||||||
'--allow-unsafe',
|
'--allow-unsafe',
|
||||||
'--upgrade',
|
'--upgrade',
|
||||||
'cibuildwheel/resources/constraints.in',
|
'cibuildwheel/resources/constraints.in',
|
||||||
'--output-file', f'cibuildwheel/resources/constraints-python{python_version}.txt'
|
'--output-file=cibuildwheel/resources/constraints-python{python_version}.txt',
|
||||||
])
|
], check=True)
|
||||||
else:
|
else:
|
||||||
image_runner = 'quay.io/pypa/manylinux2010_x86_64:latest'
|
# latest manylinux2010 image with cpython 2.7 support
|
||||||
subprocess.check_call(['docker', 'pull', image_runner])
|
image_runner = 'quay.io/pypa/manylinux2010_x86_64:2021-02-06-3d322a5'
|
||||||
|
subprocess.run(['docker', 'pull', image_runner], check=True)
|
||||||
for python_version in PYTHON_VERSIONS:
|
for python_version in PYTHON_VERSIONS:
|
||||||
abi_flags = '' if int(python_version) >= 38 else 'm'
|
abi_flags = '' if int(python_version) >= 38 else 'm'
|
||||||
python_path = f'/opt/python/cp{python_version}-cp{python_version}{abi_flags}/bin/'
|
python_path = f'/opt/python/cp{python_version}-cp{python_version}{abi_flags}/bin/'
|
||||||
subprocess.check_call([
|
subprocess.run([
|
||||||
'docker', 'run', '--rm',
|
'docker', 'run', '--rm',
|
||||||
'-e', 'CUSTOM_COMPILE_COMMAND',
|
'-e', 'CUSTOM_COMPILE_COMMAND',
|
||||||
'-v', f'{os.getcwd()}:/volume',
|
'-v', f'{os.getcwd()}:/volume',
|
||||||
@@ -43,37 +45,52 @@ else:
|
|||||||
f'{python_path}pip-compile --allow-unsafe --upgrade '
|
f'{python_path}pip-compile --allow-unsafe --upgrade '
|
||||||
'cibuildwheel/resources/constraints.in '
|
'cibuildwheel/resources/constraints.in '
|
||||||
f'--output-file cibuildwheel/resources/constraints-python{python_version}.txt'
|
f'--output-file cibuildwheel/resources/constraints-python{python_version}.txt'
|
||||||
])
|
], check=True)
|
||||||
|
|
||||||
# default constraints.txt
|
# default constraints.txt
|
||||||
shutil.copyfile(f'cibuildwheel/resources/constraints-python{PYTHON_VERSIONS[-1]}.txt', 'cibuildwheel/resources/constraints.txt')
|
shutil.copyfile(f'cibuildwheel/resources/constraints-python{PYTHON_VERSIONS[-1]}.txt', 'cibuildwheel/resources/constraints.txt',)
|
||||||
|
|
||||||
|
|
||||||
|
class Image(NamedTuple):
|
||||||
|
manylinux_version: str
|
||||||
|
platform: str
|
||||||
|
image_name: str
|
||||||
|
tag: str | None
|
||||||
|
|
||||||
Image = namedtuple('Image', [
|
|
||||||
'manylinux_version',
|
|
||||||
'platform',
|
|
||||||
'image_name',
|
|
||||||
])
|
|
||||||
|
|
||||||
images = [
|
images = [
|
||||||
Image('manylinux1', 'x86_64', 'quay.io/pypa/manylinux1_x86_64'),
|
Image('manylinux1', 'x86_64', 'quay.io/pypa/manylinux1_x86_64', None),
|
||||||
Image('manylinux1', 'i686', 'quay.io/pypa/manylinux1_i686'),
|
Image('manylinux1', 'i686', 'quay.io/pypa/manylinux1_i686', None),
|
||||||
|
|
||||||
Image('manylinux2010', 'x86_64', 'quay.io/pypa/manylinux2010_x86_64'),
|
# Images for manylinux2010 are pinned to the latest tag supporting cp27
|
||||||
Image('manylinux2010', 'i686', 'quay.io/pypa/manylinux2010_i686'),
|
Image('manylinux2010', 'x86_64', 'quay.io/pypa/manylinux2010_x86_64', '2021-02-06-3d322a5'),
|
||||||
Image('manylinux2010', 'pypy_x86_64', 'pypywheels/manylinux2010-pypy_x86_64'),
|
Image('manylinux2010', 'i686', 'quay.io/pypa/manylinux2010_i686', '2021-02-06-3d322a5'),
|
||||||
|
|
||||||
Image('manylinux2014', 'x86_64', 'quay.io/pypa/manylinux2014_x86_64'),
|
Image('manylinux2010', 'pypy_x86_64', 'pypywheels/manylinux2010-pypy_x86_64', None),
|
||||||
Image('manylinux2014', 'i686', 'quay.io/pypa/manylinux2014_i686'),
|
|
||||||
Image('manylinux2014', 'aarch64', 'quay.io/pypa/manylinux2014_aarch64'),
|
# 2014 images
|
||||||
Image('manylinux2014', 'ppc64le', 'quay.io/pypa/manylinux2014_ppc64le'),
|
Image('manylinux2014', 'x86_64', 'quay.io/pypa/manylinux2014_x86_64', None),
|
||||||
Image('manylinux2014', 's390x', 'quay.io/pypa/manylinux2014_s390x'),
|
Image('manylinux2014', 'i686', 'quay.io/pypa/manylinux2014_i686', None),
|
||||||
|
Image('manylinux2014', 'aarch64', 'quay.io/pypa/manylinux2014_aarch64', None),
|
||||||
|
Image('manylinux2014', 'ppc64le', 'quay.io/pypa/manylinux2014_ppc64le', None),
|
||||||
|
Image('manylinux2014', 's390x', 'quay.io/pypa/manylinux2014_s390x', None),
|
||||||
|
|
||||||
|
# 2_24 images
|
||||||
|
Image('manylinux_2_24', 'x86_64', 'quay.io/pypa/manylinux_2_24_x86_64', None),
|
||||||
|
Image('manylinux_2_24', 'i686', 'quay.io/pypa/manylinux_2_24_i686', None),
|
||||||
|
Image('manylinux_2_24', 'aarch64', 'quay.io/pypa/manylinux_2_24_aarch64', None),
|
||||||
|
Image('manylinux_2_24', 'ppc64le', 'quay.io/pypa/manylinux_2_24_ppc64le', None),
|
||||||
|
Image('manylinux_2_24', 's390x', 'quay.io/pypa/manylinux_2_24_s390x', None),
|
||||||
]
|
]
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
|
|
||||||
for image in images:
|
for image in images:
|
||||||
# get the tag name whose digest matches 'latest'
|
# get the tag name whose digest matches 'latest'
|
||||||
if image.image_name.startswith('quay.io/'):
|
if image.tag is not None:
|
||||||
|
# image has been pinned, do not update
|
||||||
|
tag_name = image.tag
|
||||||
|
elif image.image_name.startswith('quay.io/'):
|
||||||
_, _, repository_name = image.image_name.partition('/')
|
_, _, repository_name = image.image_name.partition('/')
|
||||||
response = requests.get(
|
response = requests.get(
|
||||||
f'https://quay.io/api/v1/repository/{repository_name}?includeTags=true'
|
f'https://quay.io/api/v1/repository/{repository_name}?includeTags=true'
|
||||||
|
|||||||
+10
-9
@@ -1,10 +1,12 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import difflib
|
import difflib
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Optional, Union
|
from typing import Union
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import requests
|
import requests
|
||||||
@@ -80,7 +82,7 @@ class WindowsVersions:
|
|||||||
versions = (Version(v) for v in cp_info["versions"])
|
versions = (Version(v) for v in cp_info["versions"])
|
||||||
self.versions = sorted(v for v in versions if not v.is_devrelease)
|
self.versions = sorted(v for v in versions if not v.is_devrelease)
|
||||||
|
|
||||||
def update_version_windows(self, spec: Specifier) -> Optional[ConfigWinCP]:
|
def update_version_windows(self, spec: Specifier) -> ConfigWinCP | None:
|
||||||
versions = sorted(v for v in self.versions if spec.contains(v))
|
versions = sorted(v for v in self.versions if spec.contains(v))
|
||||||
if not all(v.is_prerelease for v in versions):
|
if not all(v.is_prerelease for v in versions):
|
||||||
versions = [v for v in versions if not v.is_prerelease]
|
versions = [v for v in versions if not v.is_prerelease]
|
||||||
@@ -91,12 +93,11 @@ class WindowsVersions:
|
|||||||
|
|
||||||
version = versions[-1]
|
version = versions[-1]
|
||||||
identifier = f"cp{version.major}{version.minor}-{self.arch}"
|
identifier = f"cp{version.major}{version.minor}-{self.arch}"
|
||||||
result = ConfigWinCP(
|
return ConfigWinCP(
|
||||||
identifier=identifier,
|
identifier=identifier,
|
||||||
version=str(version),
|
version=str(version),
|
||||||
arch=self.arch_str,
|
arch=self.arch_str,
|
||||||
)
|
)
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class PyPyVersions:
|
class PyPyVersions:
|
||||||
@@ -171,7 +172,7 @@ class CPythonVersions:
|
|||||||
|
|
||||||
releases_info = response.json()
|
releases_info = response.json()
|
||||||
|
|
||||||
self.versions_dict: Dict[Version, int] = {}
|
self.versions_dict: dict[Version, int] = {}
|
||||||
for release in releases_info:
|
for release in releases_info:
|
||||||
# Removing the prefix, Python 3.9 would use: release["name"].removeprefix("Python ")
|
# Removing the prefix, Python 3.9 would use: release["name"].removeprefix("Python ")
|
||||||
version = Version(release["name"][7:])
|
version = Version(release["name"][7:])
|
||||||
@@ -180,8 +181,8 @@ class CPythonVersions:
|
|||||||
uri = int(release["resource_uri"].rstrip("/").split("/")[-1])
|
uri = int(release["resource_uri"].rstrip("/").split("/")[-1])
|
||||||
self.versions_dict[version] = uri
|
self.versions_dict[version] = uri
|
||||||
|
|
||||||
def update_version_macos(self, identifier: str, spec: Specifier) -> Optional[ConfigMacOS]:
|
def update_version_macos(self, identifier: str, spec: Specifier) -> ConfigMacOS | None:
|
||||||
file_idents = ("macos11.0.pkg", "macosx10.9.pkg", "macosx10.6.pkg")
|
file_idents = ("macos11.pkg", "macosx10.9.pkg", "macosx10.6.pkg")
|
||||||
sorted_versions = sorted(v for v in self.versions_dict if spec.contains(v))
|
sorted_versions = sorted(v for v in self.versions_dict if spec.contains(v))
|
||||||
|
|
||||||
for version in reversed(sorted_versions):
|
for version in reversed(sorted_versions):
|
||||||
@@ -216,13 +217,13 @@ class AllVersions:
|
|||||||
self.macos_cpython = CPythonVersions()
|
self.macos_cpython = CPythonVersions()
|
||||||
self.macos_pypy = PyPyVersions("64")
|
self.macos_pypy = PyPyVersions("64")
|
||||||
|
|
||||||
def update_config(self, config: Dict[str, str]) -> None:
|
def update_config(self, config: dict[str, str]) -> None:
|
||||||
identifier = config["identifier"]
|
identifier = config["identifier"]
|
||||||
version = Version(config["version"])
|
version = Version(config["version"])
|
||||||
spec = Specifier(f"=={version.major}.{version.minor}.*")
|
spec = Specifier(f"=={version.major}.{version.minor}.*")
|
||||||
log.info(f"Reading in '{identifier}' -> {spec} @ {version}")
|
log.info(f"Reading in '{identifier}' -> {spec} @ {version}")
|
||||||
orig_config = copy.copy(config)
|
orig_config = copy.copy(config)
|
||||||
config_update: Optional[AnyConfig]
|
config_update: AnyConfig | None
|
||||||
|
|
||||||
# We need to use ** in update due to MyPy (probably a bug)
|
# We need to use ** in update due to MyPy (probably a bug)
|
||||||
if "macos" in identifier:
|
if "macos" in identifier:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = '1.9.0'
|
__version__ = '1.10.1'
|
||||||
|
|||||||
@@ -73,19 +73,22 @@ def main() -> None:
|
|||||||
Python. Default: auto.
|
Python. Default: auto.
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
arch_list_str = ", ".join(a.name for a in Architecture)
|
||||||
parser.add_argument('--archs',
|
parser.add_argument('--archs',
|
||||||
default=None,
|
default=None,
|
||||||
help='''
|
help=f'''
|
||||||
Comma-separated list of CPU architectures to build for.
|
Comma-separated list of CPU architectures to build for.
|
||||||
When set to 'auto', builds the architectures natively supported
|
When set to 'auto', builds the architectures natively supported
|
||||||
on this machine. Set this option to build an architecture
|
on this machine. Set this option to build an architecture
|
||||||
via emulation, for example, using binfmt_misc and QEMU.
|
via emulation, for example, using binfmt_misc and QEMU.
|
||||||
Default: auto.
|
Default: auto.
|
||||||
Choices: auto, auto64, auto32, native, all, {}
|
Choices: auto, auto64, auto32, native, all, {arch_list_str}
|
||||||
'''.format(", ".join(a.name for a in Architecture)))
|
''')
|
||||||
|
|
||||||
parser.add_argument('--output-dir',
|
parser.add_argument('--output-dir',
|
||||||
default=os.environ.get('CIBW_OUTPUT_DIR', 'wheelhouse'),
|
default=os.environ.get('CIBW_OUTPUT_DIR', 'wheelhouse'),
|
||||||
help='Destination folder for the wheels.')
|
help='Destination folder for the wheels.')
|
||||||
|
|
||||||
parser.add_argument('package_dir',
|
parser.add_argument('package_dir',
|
||||||
default='.',
|
default='.',
|
||||||
nargs='?',
|
nargs='?',
|
||||||
@@ -99,6 +102,7 @@ def main() -> None:
|
|||||||
parser.add_argument('--print-build-identifiers',
|
parser.add_argument('--print-build-identifiers',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Print the build identifiers matched by the current invocation and exit.')
|
help='Print the build identifiers matched by the current invocation and exit.')
|
||||||
|
|
||||||
parser.add_argument('--allow-empty',
|
parser.add_argument('--allow-empty',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Do not report an error code if the build does not match any wheels.')
|
help='Do not report an error code if the build does not match any wheels.')
|
||||||
@@ -147,7 +151,8 @@ def main() -> None:
|
|||||||
else:
|
else:
|
||||||
assert_never(platform)
|
assert_never(platform)
|
||||||
|
|
||||||
build_config, skip_config = os.environ.get('CIBW_BUILD', '*'), os.environ.get('CIBW_SKIP', '')
|
build_config = os.environ.get('CIBW_BUILD') or '*'
|
||||||
|
skip_config = os.environ.get('CIBW_SKIP', '')
|
||||||
test_skip = os.environ.get('CIBW_TEST_SKIP', '')
|
test_skip = os.environ.get('CIBW_TEST_SKIP', '')
|
||||||
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
|
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
|
||||||
before_all = get_option_from_environment('CIBW_BEFORE_ALL', platform=platform, default='')
|
before_all = get_option_from_environment('CIBW_BEFORE_ALL', platform=platform, default='')
|
||||||
@@ -282,7 +287,7 @@ def main() -> None:
|
|||||||
if not output_dir.exists():
|
if not output_dir.exists():
|
||||||
output_dir.mkdir(parents=True)
|
output_dir.mkdir(parents=True)
|
||||||
|
|
||||||
with cibuildwheel.util.print_new_wheels("{n} wheels produced in {m:.0f} minutes:", output_dir):
|
with cibuildwheel.util.print_new_wheels("\n{n} wheels produced in {m:.0f} minutes:", output_dir):
|
||||||
if platform == 'linux':
|
if platform == 'linux':
|
||||||
cibuildwheel.linux.build(build_options)
|
cibuildwheel.linux.build(build_options)
|
||||||
elif platform == 'windows':
|
elif platform == 'windows':
|
||||||
@@ -366,9 +371,13 @@ def detect_warnings(platform: str, build_options: BuildOptions) -> List[str]:
|
|||||||
for option_name in ['test_command', 'before_build']:
|
for option_name in ['test_command', 'before_build']:
|
||||||
option_value = getattr(build_options, option_name)
|
option_value = getattr(build_options, option_name)
|
||||||
|
|
||||||
if option_value:
|
if option_value and ('{python}' in option_value or '{pip}' in option_value):
|
||||||
if '{python}' in option_value or '{pip}' in option_value:
|
# Reminder: in an f-string, double braces means literal single brace
|
||||||
warnings.append(option_name + ": '{python}' and '{pip}' are no longer needed, and will be removed in a future release. Simply use 'python' or 'pip' instead.")
|
msg = (
|
||||||
|
f"{option_name}: '{{python}}' and '{{pip}}' are no longer needed, "
|
||||||
|
"and will be removed in a future release. Simply use 'python' or 'pip' instead."
|
||||||
|
)
|
||||||
|
warnings.append(msg)
|
||||||
|
|
||||||
return warnings
|
return warnings
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ EnvironmentExecutor = Callable[[List[str], Dict[str, str]], str]
|
|||||||
|
|
||||||
|
|
||||||
def local_environment_executor(command: List[str], env: Dict[str, str]) -> str:
|
def local_environment_executor(command: List[str], env: Dict[str, str]) -> str:
|
||||||
return subprocess.check_output(command, env=env, universal_newlines=True)
|
return subprocess.run(command, env=env, universal_newlines=True, stdout=subprocess.PIPE, check=True).stdout
|
||||||
|
|
||||||
|
|
||||||
class NodeExecutionContext(NamedTuple):
|
class NodeExecutionContext(NamedTuple):
|
||||||
@@ -58,9 +58,8 @@ def evaluate_word_node(node: bashlex.ast.node, context: NodeExecutionContext) ->
|
|||||||
|
|
||||||
if part_string not in value:
|
if part_string not in value:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
'bash parse failed. part "{}" not found in "{}". Word was "{}". Full input was "{}"'.format(
|
f'bash parse failed. part "{part_string}" not found in "{value}". '
|
||||||
part_string, value, node.word, context.input,
|
f'Word was "{node.word}". Full input was "{context.input}"'
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
value = value.replace(part_string, part_value, 1)
|
value = value.replace(part_string, part_value, 1)
|
||||||
@@ -85,9 +84,7 @@ def evaluate_nodes_as_compound_command(nodes: Sequence[bashlex.ast.node], contex
|
|||||||
if node.kind == 'command':
|
if node.kind == 'command':
|
||||||
result += evaluate_command_node(node, context=context)
|
result += evaluate_command_node(node, context=context)
|
||||||
elif node.kind == 'operator':
|
elif node.kind == 'operator':
|
||||||
if node.op == ';':
|
if node.op != ';':
|
||||||
pass
|
|
||||||
else:
|
|
||||||
raise ValueError(f'Unsupported bash operator: "{node.op}"')
|
raise ValueError(f'Unsupported bash operator: "{node.op}"')
|
||||||
else:
|
else:
|
||||||
raise ValueError(f'Unsupported bash node in compound command: "{node.kind}"')
|
raise ValueError(f'Unsupported bash node in compound command: "{node.kind}"')
|
||||||
|
|||||||
@@ -45,10 +45,10 @@ class DockerContainer:
|
|||||||
subprocess.run(
|
subprocess.run(
|
||||||
[
|
[
|
||||||
'docker', 'create',
|
'docker', 'create',
|
||||||
'--env', 'CIBUILDWHEEL',
|
'--env=CIBUILDWHEEL',
|
||||||
'--name', self.name,
|
f'--name={self.name}',
|
||||||
'-i',
|
'--interactive',
|
||||||
'-v', '/:/host', # ignored on CircleCI
|
'--volume=/:/host', # ignored on CircleCI
|
||||||
*cwd_args,
|
*cwd_args,
|
||||||
self.docker_image,
|
self.docker_image,
|
||||||
*shell_args
|
*shell_args
|
||||||
@@ -169,13 +169,15 @@ class DockerContainer:
|
|||||||
while True:
|
while True:
|
||||||
line = self.bash_stdout.readline()
|
line = self.bash_stdout.readline()
|
||||||
|
|
||||||
if line.endswith(b'%s\n' % (bytes(end_of_message, encoding='utf8'))):
|
if line.endswith(bytes(end_of_message, encoding='utf8') + b'\n'):
|
||||||
|
# fmt: off
|
||||||
footer_offset = (
|
footer_offset = (
|
||||||
len(line)
|
len(line)
|
||||||
- 1 # newline character
|
- 1 # newline character
|
||||||
- len(end_of_message) # delimiter
|
- len(end_of_message) # delimiter
|
||||||
- 4 # 4 returncode decimals
|
- 4 # 4 returncode decimals
|
||||||
)
|
)
|
||||||
|
# fmt: on
|
||||||
returncode_str = line[footer_offset:footer_offset+4]
|
returncode_str = line[footer_offset:footer_offset+4]
|
||||||
returncode = int(returncode_str)
|
returncode = int(returncode_str)
|
||||||
# add the last line to output, without the footer
|
# add the last line to output, without the footer
|
||||||
|
|||||||
@@ -14,11 +14,10 @@ class InlineArrayDictEncoder(toml.encoder.TomlEncoder): # type: ignore
|
|||||||
self.dump_funcs[Version] = lambda v: f'"{v}"'
|
self.dump_funcs[Version] = lambda v: f'"{v}"'
|
||||||
|
|
||||||
def dump_sections(self, o: Dict[str, Any], sup: str) -> Any:
|
def dump_sections(self, o: Dict[str, Any], sup: str) -> Any:
|
||||||
if all(isinstance(a, list) for a in o.values()):
|
if not all(isinstance(a, list) for a in o.values()):
|
||||||
val = ""
|
|
||||||
for k, v in o.items():
|
|
||||||
inner = ",\n ".join(self.dump_inline_table(d_i).strip() for d_i in v)
|
|
||||||
val += f"{k} = [\n {inner},\n]\n"
|
|
||||||
return val, self._dict()
|
|
||||||
else:
|
|
||||||
return super().dump_sections(o, sup)
|
return super().dump_sections(o, sup)
|
||||||
|
val = ""
|
||||||
|
for k, v in o.items():
|
||||||
|
inner = ",\n ".join(self.dump_inline_table(d_i).strip() for d_i in v)
|
||||||
|
val += f"{k} = [\n {inner},\n]\n"
|
||||||
|
return val, self._dict()
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class PythonConfiguration(NamedTuple):
|
|||||||
|
|
||||||
def get_python_configurations(
|
def get_python_configurations(
|
||||||
build_selector: BuildSelector,
|
build_selector: BuildSelector,
|
||||||
architectures: Set[Architecture]
|
architectures: Set[Architecture],
|
||||||
) -> List[PythonConfiguration]:
|
) -> List[PythonConfiguration]:
|
||||||
|
|
||||||
full_python_configs = read_python_configs('linux')
|
full_python_configs = read_python_configs('linux')
|
||||||
@@ -49,7 +49,8 @@ def get_python_configurations(
|
|||||||
|
|
||||||
def build(options: BuildOptions) -> None:
|
def build(options: BuildOptions) -> None:
|
||||||
try:
|
try:
|
||||||
subprocess.check_output(['docker', '--version'])
|
# check docker is installed
|
||||||
|
subprocess.run(['docker', '--version'], check=True, stdout=subprocess.DEVNULL)
|
||||||
except Exception:
|
except Exception:
|
||||||
print('cibuildwheel: Docker not found. Docker is required to run Linux builds. '
|
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 Travis CI, add `services: [docker]` to your .travis.yml.'
|
||||||
@@ -158,7 +159,7 @@ def build(options: BuildOptions) -> None:
|
|||||||
docker.call([
|
docker.call([
|
||||||
'pip', 'wheel',
|
'pip', 'wheel',
|
||||||
container_package_dir,
|
container_package_dir,
|
||||||
'-w', built_wheel_dir,
|
'--wheel-dir', built_wheel_dir,
|
||||||
'--no-deps',
|
'--no-deps',
|
||||||
*get_build_verbosity_extra_flags(options.build_verbosity)
|
*get_build_verbosity_extra_flags(options.build_verbosity)
|
||||||
], env=env)
|
], env=env)
|
||||||
@@ -252,5 +253,5 @@ def troubleshoot(package_dir: Path, error: Exception) -> None:
|
|||||||
'''), file=sys.stderr)
|
'''), file=sys.stderr)
|
||||||
|
|
||||||
print(' Files detected:')
|
print(' Files detected:')
|
||||||
print('\n'.join([f' {f}' for f in so_files]))
|
print('\n'.join(f' {f}' for f in so_files))
|
||||||
print('')
|
print('')
|
||||||
|
|||||||
+41
-32
@@ -28,14 +28,14 @@ from .util import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def call(args: Sequence[PathOrStr], env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None, shell: bool = False) -> int:
|
def call(args: Sequence[PathOrStr], env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None, shell: bool = False) -> None:
|
||||||
# print the command executing for the logs
|
# print the command executing for the logs
|
||||||
if shell:
|
if shell:
|
||||||
print(f'+ {args}')
|
print(f'+ {args}')
|
||||||
else:
|
else:
|
||||||
print('+ ' + ' '.join(shlex.quote(str(a)) for a in args))
|
print('+ ' + ' '.join(shlex.quote(str(a)) for a in args))
|
||||||
|
|
||||||
return subprocess.check_call(args, env=env, cwd=cwd, shell=shell)
|
subprocess.run(args, env=env, cwd=cwd, shell=shell, check=True)
|
||||||
|
|
||||||
|
|
||||||
def get_macos_version() -> Tuple[int, int]:
|
def get_macos_version() -> Tuple[int, int]:
|
||||||
@@ -53,10 +53,12 @@ def get_macos_version() -> Tuple[int, int]:
|
|||||||
|
|
||||||
|
|
||||||
def get_macos_sdks() -> List[str]:
|
def get_macos_sdks() -> List[str]:
|
||||||
output = subprocess.check_output(
|
output = subprocess.run(
|
||||||
['xcodebuild', '-showsdks'],
|
['xcodebuild', '-showsdks'],
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
)
|
check=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
).stdout
|
||||||
|
|
||||||
return [m.group(1) for m in re.finditer(r'-sdk (macosx\S+)', output)]
|
return [m.group(1) for m in re.finditer(r'-sdk (macosx\S+)', output)]
|
||||||
|
|
||||||
@@ -125,7 +127,7 @@ def make_symlinks(installation_bin_path: Path, python_executable: str, pip_execu
|
|||||||
|
|
||||||
|
|
||||||
def install_cpython(version: str, url: str) -> Path:
|
def install_cpython(version: str, url: str) -> Path:
|
||||||
installed_system_packages = subprocess.check_output(['pkgutil', '--pkgs'], universal_newlines=True).splitlines()
|
installed_system_packages = subprocess.run(['pkgutil', '--pkgs'], universal_newlines=True, check=True, stdout=subprocess.PIPE).stdout.splitlines()
|
||||||
|
|
||||||
# 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 = f'org.python.Python.PythonFramework-{version}'
|
python_package_identifier = f'org.python.Python.PythonFramework-{version}'
|
||||||
@@ -211,7 +213,7 @@ def setup_python(python_configuration: PythonConfiguration,
|
|||||||
# check what version we're on
|
# check what version we're on
|
||||||
call(['which', 'python'], env=env)
|
call(['which', 'python'], env=env)
|
||||||
call(['python', '--version'], env=env)
|
call(['python', '--version'], env=env)
|
||||||
which_python = subprocess.check_output(['which', 'python'], env=env, universal_newlines=True).strip()
|
which_python = subprocess.run(['which', 'python'], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE).stdout.strip()
|
||||||
if which_python != '/tmp/cibw_bin/python':
|
if which_python != '/tmp/cibw_bin/python':
|
||||||
print("cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.", file=sys.stderr)
|
print("cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -221,7 +223,7 @@ def setup_python(python_configuration: PythonConfiguration,
|
|||||||
assert (installation_bin_path / 'pip').exists()
|
assert (installation_bin_path / 'pip').exists()
|
||||||
call(['which', 'pip'], env=env)
|
call(['which', 'pip'], env=env)
|
||||||
call(['pip', '--version'], env=env)
|
call(['pip', '--version'], env=env)
|
||||||
which_pip = subprocess.check_output(['which', 'pip'], env=env, universal_newlines=True).strip()
|
which_pip = subprocess.run(['which', 'pip'], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE).stdout.strip()
|
||||||
if which_pip != '/tmp/cibw_bin/pip':
|
if which_pip != '/tmp/cibw_bin/pip':
|
||||||
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
|
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -231,6 +233,9 @@ def setup_python(python_configuration: PythonConfiguration,
|
|||||||
# inconsistencies if it's left unset.
|
# inconsistencies if it's left unset.
|
||||||
env.setdefault('MACOSX_DEPLOYMENT_TARGET', '10.9')
|
env.setdefault('MACOSX_DEPLOYMENT_TARGET', '10.9')
|
||||||
|
|
||||||
|
config_is_arm64 = python_configuration.identifier.endswith('arm64')
|
||||||
|
config_is_universal2 = python_configuration.identifier.endswith('universal2')
|
||||||
|
|
||||||
if python_configuration.version == '3.5':
|
if python_configuration.version == '3.5':
|
||||||
# Cross-compilation platform override - CPython 3.5 has an
|
# Cross-compilation platform override - CPython 3.5 has an
|
||||||
# i386/x86_64 version of Python, but we only want a x64_64 build
|
# i386/x86_64 version of Python, but we only want a x64_64 build
|
||||||
@@ -244,34 +249,34 @@ def setup_python(python_configuration: PythonConfiguration,
|
|||||||
# compatible back to 10.9.
|
# compatible back to 10.9.
|
||||||
env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-10.9-x86_64')
|
env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-10.9-x86_64')
|
||||||
env.setdefault('ARCHFLAGS', '-arch x86_64')
|
env.setdefault('ARCHFLAGS', '-arch x86_64')
|
||||||
elif python_configuration.identifier.endswith('arm64'):
|
elif config_is_arm64:
|
||||||
# macOS 11 is the first OS with arm64 support, so the wheels
|
# macOS 11 is the first OS with arm64 support, so the wheels
|
||||||
# have that as a minimum.
|
# have that as a minimum.
|
||||||
env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-11.0-arm64')
|
env.setdefault('_PYTHON_HOST_PLATFORM', 'macosx-11.0-arm64')
|
||||||
env.setdefault('ARCHFLAGS', '-arch arm64')
|
env.setdefault('ARCHFLAGS', '-arch arm64')
|
||||||
elif python_configuration.identifier.endswith('universal2'):
|
elif config_is_universal2:
|
||||||
if get_macos_version() < (10, 16):
|
if get_macos_version() < (10, 16):
|
||||||
# we can do universal2 builds on macos 10.15, but we need to
|
# we can do universal2 builds on macos 10.15, but we need to
|
||||||
# set ARCHFLAGS otherwise CPython sets it to `-arch x86_64`
|
# set ARCHFLAGS otherwise CPython sets it to `-arch x86_64`
|
||||||
env.setdefault('ARCHFLAGS', '-arch arm64 -arch x86_64')
|
env.setdefault('ARCHFLAGS', '-arch arm64 -arch x86_64')
|
||||||
|
|
||||||
if python_configuration.identifier.endswith('arm64') or python_configuration.identifier.endswith('universal2'):
|
building_arm64 = config_is_arm64 or config_is_universal2
|
||||||
if get_macos_version() < (10, 16) and 'SDKROOT' not in env:
|
if building_arm64 and get_macos_version() < (10, 16) and 'SDKROOT' not in env:
|
||||||
# xcode 12.2 or higher can build arm64 on macos 10.15 or below, but
|
# xcode 12.2 or higher can build arm64 on macos 10.15 or below, but
|
||||||
# needs the correct SDK selected.
|
# needs the correct SDK selected.
|
||||||
sdks = get_macos_sdks()
|
sdks = get_macos_sdks()
|
||||||
|
|
||||||
# Different versions of Xcode contain different SDK versions...
|
# Different versions of Xcode contain different SDK versions...
|
||||||
# we're happy with anything newer than macOS 11.0
|
# we're happy with anything newer than macOS 11.0
|
||||||
arm64_compatible_sdks = [s for s in sdks if not s.startswith('macosx10.')]
|
arm64_compatible_sdks = [s for s in sdks if not s.startswith('macosx10.')]
|
||||||
|
|
||||||
if not arm64_compatible_sdks:
|
if not arm64_compatible_sdks:
|
||||||
log.warning(unwrap('''
|
log.warning(unwrap('''
|
||||||
SDK for building arm64-compatible wheels not found. You need Xcode 12.2 or later
|
SDK for building arm64-compatible wheels not found. You need Xcode 12.2 or later
|
||||||
to build universal2 or arm64 wheels.
|
to build universal2 or arm64 wheels.
|
||||||
'''))
|
'''))
|
||||||
else:
|
else:
|
||||||
env.setdefault('SDKROOT', arm64_compatible_sdks[0])
|
env.setdefault('SDKROOT', arm64_compatible_sdks[0])
|
||||||
|
|
||||||
log.step('Installing build tools...')
|
log.step('Installing build tools...')
|
||||||
call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', 'delocate', *dependency_constraint_flags], env=env)
|
call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', 'delocate', *dependency_constraint_flags], env=env)
|
||||||
@@ -288,6 +293,7 @@ def build(options: BuildOptions) -> None:
|
|||||||
if options.before_all:
|
if options.before_all:
|
||||||
log.step('Running before_all...')
|
log.step('Running before_all...')
|
||||||
env = options.environment.as_dictionary(prev_environment=os.environ)
|
env = options.environment.as_dictionary(prev_environment=os.environ)
|
||||||
|
env.setdefault('MACOSX_DEPLOYMENT_TARGET', '10.9')
|
||||||
before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir)
|
before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir)
|
||||||
call([before_all_prepared], shell=True, env=env)
|
call([before_all_prepared], shell=True, env=env)
|
||||||
|
|
||||||
@@ -296,6 +302,9 @@ def build(options: BuildOptions) -> None:
|
|||||||
for config in python_configurations:
|
for config in python_configurations:
|
||||||
log.build_start(config.identifier)
|
log.build_start(config.identifier)
|
||||||
|
|
||||||
|
config_is_arm64 = config.identifier.endswith('arm64')
|
||||||
|
config_is_universal2 = config.identifier.endswith('universal2')
|
||||||
|
|
||||||
dependency_constraint_flags: Sequence[PathOrStr] = []
|
dependency_constraint_flags: Sequence[PathOrStr] = []
|
||||||
if options.dependency_constraints:
|
if options.dependency_constraints:
|
||||||
dependency_constraint_flags = [
|
dependency_constraint_flags = [
|
||||||
@@ -319,7 +328,7 @@ def build(options: BuildOptions) -> None:
|
|||||||
call([
|
call([
|
||||||
'pip', 'wheel',
|
'pip', 'wheel',
|
||||||
options.package_dir.resolve(),
|
options.package_dir.resolve(),
|
||||||
'-w', built_wheel_dir,
|
'--wheel-dir', built_wheel_dir,
|
||||||
'--no-deps',
|
'--no-deps',
|
||||||
*get_build_verbosity_extra_flags(options.build_verbosity)
|
*get_build_verbosity_extra_flags(options.build_verbosity)
|
||||||
], env=env)
|
], env=env)
|
||||||
@@ -336,9 +345,9 @@ def build(options: BuildOptions) -> None:
|
|||||||
if options.repair_command:
|
if options.repair_command:
|
||||||
log.step('Repairing wheel...')
|
log.step('Repairing wheel...')
|
||||||
|
|
||||||
if config.identifier.endswith('universal2'):
|
if config_is_universal2:
|
||||||
delocate_archs = 'x86_64,arm64'
|
delocate_archs = 'x86_64,arm64'
|
||||||
elif config.identifier.endswith('arm64'):
|
elif config_is_arm64:
|
||||||
delocate_archs = 'arm64'
|
delocate_archs = 'arm64'
|
||||||
else:
|
else:
|
||||||
delocate_archs = 'x86_64'
|
delocate_archs = 'x86_64'
|
||||||
@@ -361,28 +370,28 @@ def build(options: BuildOptions) -> None:
|
|||||||
machine_arch = platform.machine()
|
machine_arch = platform.machine()
|
||||||
testing_archs: List[Literal['x86_64', 'arm64']] = []
|
testing_archs: List[Literal['x86_64', 'arm64']] = []
|
||||||
|
|
||||||
if config.identifier.endswith('_arm64'):
|
if config_is_arm64:
|
||||||
testing_archs = ['arm64']
|
testing_archs = ['arm64']
|
||||||
elif config.identifier.endswith('_universal2'):
|
elif config_is_universal2:
|
||||||
testing_archs = ['x86_64', 'arm64']
|
testing_archs = ['x86_64', 'arm64']
|
||||||
else:
|
else:
|
||||||
testing_archs = ['x86_64']
|
testing_archs = ['x86_64']
|
||||||
|
|
||||||
for testing_arch in testing_archs:
|
for testing_arch in testing_archs:
|
||||||
if config.identifier.endswith('_universal2'):
|
if config_is_universal2:
|
||||||
arch_specific_identifier = f'{config.identifier}:{testing_arch}'
|
arch_specific_identifier = f'{config.identifier}:{testing_arch}'
|
||||||
if not options.test_selector(arch_specific_identifier):
|
if not options.test_selector(arch_specific_identifier):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if machine_arch == 'x86_64' and testing_arch == 'arm64':
|
if machine_arch == 'x86_64' and testing_arch == 'arm64':
|
||||||
if config.identifier.endswith('_arm64'):
|
if config_is_arm64:
|
||||||
log.warning(unwrap('''
|
log.warning(unwrap('''
|
||||||
While arm64 wheels can be built on x86_64, they cannot be tested. The
|
While arm64 wheels can be built on x86_64, they cannot be tested. The
|
||||||
ability to test the arm64 wheels will be added in a future release of
|
ability to test the arm64 wheels will be added in a future release of
|
||||||
cibuildwheel, once Apple Silicon CI runners are widely available. To
|
cibuildwheel, once Apple Silicon CI runners are widely available. To
|
||||||
silence this warning, set `CIBW_TEST_SKIP: *-macosx_arm64`.
|
silence this warning, set `CIBW_TEST_SKIP: *-macosx_arm64`.
|
||||||
'''))
|
'''))
|
||||||
elif config.identifier.endswith('_universal2'):
|
elif config_is_universal2:
|
||||||
log.warning(unwrap('''
|
log.warning(unwrap('''
|
||||||
While universal2 wheels can be built on x86_64, the arm64 part of them
|
While universal2 wheels can be built on x86_64, the arm64 part of them
|
||||||
cannot currently be tested. The ability to test the arm64 part of a
|
cannot currently be tested. The ability to test the arm64 part of a
|
||||||
@@ -412,12 +421,12 @@ def build(options: BuildOptions) -> None:
|
|||||||
raise RuntimeError("don't know how to emulate {testing_arch} on {machine_arch}")
|
raise RuntimeError("don't know how to emulate {testing_arch} on {machine_arch}")
|
||||||
|
|
||||||
# define a custom 'call' function that adds the arch prefix each time
|
# define a custom 'call' function that adds the arch prefix each time
|
||||||
def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> int:
|
def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
|
||||||
if isinstance(args, str):
|
if isinstance(args, str):
|
||||||
args = ' '.join(arch_prefix) + ' ' + args
|
args = ' '.join(arch_prefix) + ' ' + args
|
||||||
else:
|
else:
|
||||||
args = [*arch_prefix, *args]
|
args = [*arch_prefix, *args]
|
||||||
return call(args, **kwargs)
|
call(args, **kwargs)
|
||||||
|
|
||||||
# Use --no-download to ensure determinism by using seed libraries
|
# Use --no-download to ensure determinism by using seed libraries
|
||||||
# built into virtualenv
|
# built into virtualenv
|
||||||
@@ -437,7 +446,7 @@ def build(options: BuildOptions) -> None:
|
|||||||
call_with_arch(before_test_prepared, env=virtualenv_env, shell=True)
|
call_with_arch(before_test_prepared, env=virtualenv_env, shell=True)
|
||||||
|
|
||||||
# install the wheel
|
# install the wheel
|
||||||
call_with_arch(['pip', 'install', str(repaired_wheel) + options.test_extras], env=virtualenv_env)
|
call_with_arch(['pip', 'install', f"{repaired_wheel}{options.test_extras}"], env=virtualenv_env)
|
||||||
|
|
||||||
# test the wheel
|
# test the wheel
|
||||||
if options.test_requires:
|
if options.test_requires:
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ python_configurations = [
|
|||||||
{ identifier = "cp35-macosx_x86_64", version = "3.5", url = "https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg" },
|
{ identifier = "cp35-macosx_x86_64", version = "3.5", url = "https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg" },
|
||||||
{ identifier = "cp36-macosx_x86_64", version = "3.6", url = "https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.9.pkg" },
|
{ identifier = "cp36-macosx_x86_64", version = "3.6", url = "https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.9.pkg" },
|
||||||
{ identifier = "cp37-macosx_x86_64", version = "3.7", url = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-macosx10.9.pkg" },
|
{ identifier = "cp37-macosx_x86_64", version = "3.7", url = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-macosx10.9.pkg" },
|
||||||
{ identifier = "cp38-macosx_x86_64", version = "3.8", url = "https://www.python.org/ftp/python/3.8.7/python-3.8.7-macosx10.9.pkg" },
|
{ identifier = "cp38-macosx_x86_64", version = "3.8", url = "https://www.python.org/ftp/python/3.8.9/python-3.8.9-macosx10.9.pkg" },
|
||||||
{ identifier = "cp39-macosx_x86_64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.1/python-3.9.1-macos11.0.pkg" },
|
{ identifier = "cp39-macosx_x86_64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" },
|
||||||
{ identifier = "cp39-macosx_arm64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.1/python-3.9.1-macos11.0.pkg" },
|
{ identifier = "cp39-macosx_arm64", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" },
|
||||||
{ identifier = "cp39-macosx_universal2", version = "3.9", url = "https://www.python.org/ftp/python/3.9.1/python-3.9.1-macos11.0.pkg" },
|
{ identifier = "cp39-macosx_universal2", version = "3.9", url = "https://www.python.org/ftp/python/3.9.4/python-3.9.4-macos11.pkg" },
|
||||||
{ identifier = "pp27-macosx_x86_64", version = "2.7", url = "https://downloads.python.org/pypy/pypy2.7-v7.3.3-osx64.tar.bz2" },
|
{ identifier = "pp27-macosx_x86_64", version = "2.7", url = "https://downloads.python.org/pypy/pypy2.7-v7.3.3-osx64.tar.bz2" },
|
||||||
{ identifier = "pp36-macosx_x86_64", version = "3.6", url = "https://downloads.python.org/pypy/pypy3.6-v7.3.3-osx64.tar.bz2" },
|
{ identifier = "pp36-macosx_x86_64", version = "3.6", url = "https://downloads.python.org/pypy/pypy3.6-v7.3.3-osx64.tar.bz2" },
|
||||||
{ identifier = "pp37-macosx_x86_64", version = "3.7", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.3-osx64.tar.bz2" },
|
{ identifier = "pp37-macosx_x86_64", version = "3.7", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.3-osx64.tar.bz2" },
|
||||||
@@ -59,10 +59,10 @@ python_configurations = [
|
|||||||
{ identifier = "cp36-win_amd64", version = "3.6.8", arch = "64" },
|
{ identifier = "cp36-win_amd64", version = "3.6.8", arch = "64" },
|
||||||
{ identifier = "cp37-win32", version = "3.7.9", arch = "32" },
|
{ identifier = "cp37-win32", version = "3.7.9", arch = "32" },
|
||||||
{ identifier = "cp37-win_amd64", version = "3.7.9", arch = "64" },
|
{ identifier = "cp37-win_amd64", version = "3.7.9", arch = "64" },
|
||||||
{ identifier = "cp38-win32", version = "3.8.7", arch = "32" },
|
{ identifier = "cp38-win32", version = "3.8.9", arch = "32" },
|
||||||
{ identifier = "cp38-win_amd64", version = "3.8.7", arch = "64" },
|
{ identifier = "cp38-win_amd64", version = "3.8.9", arch = "64" },
|
||||||
{ identifier = "cp39-win32", version = "3.9.1", arch = "32" },
|
{ identifier = "cp39-win32", version = "3.9.4", arch = "32" },
|
||||||
{ identifier = "cp39-win_amd64", version = "3.9.1", arch = "64" },
|
{ identifier = "cp39-win_amd64", version = "3.9.4", arch = "64" },
|
||||||
{ identifier = "pp27-win32", version = "2.7", arch = "32", url = "https://downloads.python.org/pypy/pypy2.7-v7.3.3-win32.zip" },
|
{ identifier = "pp27-win32", version = "2.7", arch = "32", url = "https://downloads.python.org/pypy/pypy2.7-v7.3.3-win32.zip" },
|
||||||
{ identifier = "pp36-win32", version = "3.6", arch = "32", url = "https://downloads.python.org/pypy/pypy3.6-v7.3.3-win32.zip" },
|
{ identifier = "pp36-win32", version = "3.6", arch = "32", url = "https://downloads.python.org/pypy/pypy3.6-v7.3.3-win32.zip" },
|
||||||
{ identifier = "pp37-win32", version = "3.7", arch = "32", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.3-win32.zip" },
|
{ identifier = "pp37-win32", version = "3.7", arch = "32", url = "https://downloads.python.org/pypy/pypy3.7-v7.3.3-win32.zip" },
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ pathlib2==2.3.5
|
|||||||
# virtualenv
|
# virtualenv
|
||||||
scandir==1.10.0
|
scandir==1.10.0
|
||||||
# via pathlib2
|
# via pathlib2
|
||||||
singledispatch==3.4.0.3
|
singledispatch==3.6.1
|
||||||
# via importlib-resources
|
# via importlib-resources
|
||||||
six==1.15.0
|
six==1.15.0
|
||||||
# via
|
# via
|
||||||
@@ -37,7 +37,7 @@ six==1.15.0
|
|||||||
# virtualenv
|
# virtualenv
|
||||||
typing==3.7.4.3
|
typing==3.7.4.3
|
||||||
# via importlib-resources
|
# via importlib-resources
|
||||||
virtualenv==20.4.2
|
virtualenv==20.4.3
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
wheel==0.36.2
|
wheel==0.36.2
|
||||||
# via
|
# via
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ importlib-resources==3.2.1
|
|||||||
# via virtualenv
|
# via virtualenv
|
||||||
six==1.15.0
|
six==1.15.0
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
virtualenv==20.4.2
|
virtualenv==20.4.3
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
wheel==0.36.2
|
wheel==0.36.2
|
||||||
# via
|
# via
|
||||||
|
|||||||
@@ -12,21 +12,21 @@ distlib==0.3.1
|
|||||||
# via virtualenv
|
# via virtualenv
|
||||||
filelock==3.0.12
|
filelock==3.0.12
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
importlib-metadata==3.4.0
|
importlib-metadata==3.10.0
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
importlib-resources==5.1.0
|
importlib-resources==5.1.2
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
six==1.15.0
|
six==1.15.0
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
typing-extensions==3.7.4.3
|
typing-extensions==3.7.4.3
|
||||||
# via importlib-metadata
|
# via importlib-metadata
|
||||||
virtualenv==20.4.2
|
virtualenv==20.4.3
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
wheel==0.36.2
|
wheel==0.36.2
|
||||||
# via
|
# via
|
||||||
# -r cibuildwheel/resources/constraints.in
|
# -r cibuildwheel/resources/constraints.in
|
||||||
# delocate
|
# delocate
|
||||||
zipp==3.4.0
|
zipp==3.4.1
|
||||||
# via
|
# via
|
||||||
# importlib-metadata
|
# importlib-metadata
|
||||||
# importlib-resources
|
# importlib-resources
|
||||||
@@ -34,5 +34,5 @@ zipp==3.4.0
|
|||||||
# The following packages are considered to be unsafe in a requirements file:
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
pip==21.0.1
|
pip==21.0.1
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
setuptools==53.0.0
|
setuptools==54.2.0
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
|
|||||||
@@ -12,23 +12,23 @@ distlib==0.3.1
|
|||||||
# via virtualenv
|
# via virtualenv
|
||||||
filelock==3.0.12
|
filelock==3.0.12
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
importlib-metadata==3.4.0
|
importlib-metadata==3.10.0
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
six==1.15.0
|
six==1.15.0
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
typing-extensions==3.7.4.3
|
typing-extensions==3.7.4.3
|
||||||
# via importlib-metadata
|
# via importlib-metadata
|
||||||
virtualenv==20.4.2
|
virtualenv==20.4.3
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
wheel==0.36.2
|
wheel==0.36.2
|
||||||
# via
|
# via
|
||||||
# -r cibuildwheel/resources/constraints.in
|
# -r cibuildwheel/resources/constraints.in
|
||||||
# delocate
|
# delocate
|
||||||
zipp==3.4.0
|
zipp==3.4.1
|
||||||
# via importlib-metadata
|
# via importlib-metadata
|
||||||
|
|
||||||
# The following packages are considered to be unsafe in a requirements file:
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
pip==21.0.1
|
pip==21.0.1
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
setuptools==53.0.0
|
setuptools==54.2.0
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ filelock==3.0.12
|
|||||||
# via virtualenv
|
# via virtualenv
|
||||||
six==1.15.0
|
six==1.15.0
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
virtualenv==20.4.2
|
virtualenv==20.4.3
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
wheel==0.36.2
|
wheel==0.36.2
|
||||||
# via
|
# via
|
||||||
@@ -24,5 +24,5 @@ wheel==0.36.2
|
|||||||
# The following packages are considered to be unsafe in a requirements file:
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
pip==21.0.1
|
pip==21.0.1
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
setuptools==53.0.0
|
setuptools==54.2.0
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ filelock==3.0.12
|
|||||||
# via virtualenv
|
# via virtualenv
|
||||||
six==1.15.0
|
six==1.15.0
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
virtualenv==20.4.2
|
virtualenv==20.4.3
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
wheel==0.36.2
|
wheel==0.36.2
|
||||||
# via
|
# via
|
||||||
@@ -24,5 +24,5 @@ wheel==0.36.2
|
|||||||
# The following packages are considered to be unsafe in a requirements file:
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
pip==21.0.1
|
pip==21.0.1
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
setuptools==53.0.0
|
setuptools==54.2.0
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ filelock==3.0.12
|
|||||||
# via virtualenv
|
# via virtualenv
|
||||||
six==1.15.0
|
six==1.15.0
|
||||||
# via virtualenv
|
# via virtualenv
|
||||||
virtualenv==20.4.2
|
virtualenv==20.4.3
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
wheel==0.36.2
|
wheel==0.36.2
|
||||||
# via
|
# via
|
||||||
@@ -24,5 +24,5 @@ wheel==0.36.2
|
|||||||
# The following packages are considered to be unsafe in a requirements file:
|
# The following packages are considered to be unsafe in a requirements file:
|
||||||
pip==21.0.1
|
pip==21.0.1
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
setuptools==53.0.0
|
setuptools==54.2.0
|
||||||
# via -r cibuildwheel/resources/constraints.in
|
# via -r cibuildwheel/resources/constraints.in
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
[x86_64]
|
[x86_64]
|
||||||
manylinux1 = quay.io/pypa/manylinux1_x86_64:2021-01-24-153e846
|
manylinux1 = quay.io/pypa/manylinux1_x86_64:2021-04-05-14df3a6
|
||||||
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2021-01-24-4117e7c
|
manylinux2010 = quay.io/pypa/manylinux2010_x86_64:2021-02-06-3d322a5
|
||||||
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2021-01-24-91ce2b8
|
manylinux2014 = quay.io/pypa/manylinux2014_x86_64:2021-04-05-b4fd19d
|
||||||
|
manylinux_2_24 = quay.io/pypa/manylinux_2_24_x86_64:2021-04-05-b4fd19d
|
||||||
|
|
||||||
[i686]
|
[i686]
|
||||||
manylinux1 = quay.io/pypa/manylinux1_i686:2021-01-24-153e846
|
manylinux1 = quay.io/pypa/manylinux1_i686:2021-04-05-14df3a6
|
||||||
manylinux2010 = quay.io/pypa/manylinux2010_i686:2021-01-24-4117e7c
|
manylinux2010 = quay.io/pypa/manylinux2010_i686:2021-02-06-3d322a5
|
||||||
manylinux2014 = quay.io/pypa/manylinux2014_i686:2021-01-24-91ce2b8
|
manylinux2014 = quay.io/pypa/manylinux2014_i686:2021-04-05-b4fd19d
|
||||||
|
manylinux_2_24 = quay.io/pypa/manylinux_2_24_i686:2021-04-05-b4fd19d
|
||||||
|
|
||||||
[pypy_x86_64]
|
[pypy_x86_64]
|
||||||
manylinux2010 = pypywheels/manylinux2010-pypy_x86_64:2020-12-11-f1e0e80
|
manylinux2010 = pypywheels/manylinux2010-pypy_x86_64:2020-12-11-f1e0e80
|
||||||
|
|
||||||
[aarch64]
|
[aarch64]
|
||||||
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2021-01-24-91ce2b8
|
manylinux2014 = quay.io/pypa/manylinux2014_aarch64:2021-04-05-b4fd19d
|
||||||
|
manylinux_2_24 = quay.io/pypa/manylinux_2_24_aarch64:2021-04-05-b4fd19d
|
||||||
|
|
||||||
[ppc64le]
|
[ppc64le]
|
||||||
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2021-01-24-91ce2b8
|
manylinux2014 = quay.io/pypa/manylinux2014_ppc64le:2021-04-05-b4fd19d
|
||||||
|
manylinux_2_24 = quay.io/pypa/manylinux_2_24_ppc64le:2021-04-05-b4fd19d
|
||||||
|
|
||||||
[s390x]
|
[s390x]
|
||||||
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2021-01-24-91ce2b8
|
manylinux2014 = quay.io/pypa/manylinux2014_s390x:2021-04-05-b4fd19d
|
||||||
|
manylinux_2_24 = quay.io/pypa/manylinux_2_24_s390x:2021-04-05-b4fd19d
|
||||||
|
|
||||||
|
|||||||
@@ -209,9 +209,7 @@ class NonPlatformWheelError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
def strtobool(val: str) -> bool:
|
def strtobool(val: str) -> bool:
|
||||||
if val.lower() in ('y', 'yes', 't', 'true', 'on', '1'):
|
return val.lower() in {'y', 'yes', 't', 'true', 'on', '1'}
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class CIProvider(Enum):
|
class CIProvider(Enum):
|
||||||
|
|||||||
+16
-13
@@ -25,7 +25,6 @@ from .util import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
IS_RUNNING_ON_AZURE = Path('C:\\hostedtoolcache').exists()
|
IS_RUNNING_ON_AZURE = Path('C:\\hostedtoolcache').exists()
|
||||||
IS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows'
|
|
||||||
|
|
||||||
|
|
||||||
def call(args: Sequence[PathOrStr], env: Optional[Dict[str, str]] = None,
|
def call(args: Sequence[PathOrStr], env: Optional[Dict[str, str]] = None,
|
||||||
@@ -33,19 +32,24 @@ def call(args: Sequence[PathOrStr], env: Optional[Dict[str, str]] = None,
|
|||||||
print('+ ' + ' '.join(str(a) for a in args))
|
print('+ ' + ' '.join(str(a) for a in args))
|
||||||
# we use shell=True here, even though we don't need a shell due to a bug
|
# we use shell=True here, even though we don't need a shell due to a bug
|
||||||
# https://bugs.python.org/issue8557
|
# https://bugs.python.org/issue8557
|
||||||
subprocess.check_call([str(a) for a in args], env=env, cwd=cwd, shell=True)
|
subprocess.run([str(a) for a in args], env=env, cwd=cwd, shell=True, check=True)
|
||||||
|
|
||||||
|
|
||||||
def shell(command: str, env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None) -> None:
|
def shell(command: str, env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None) -> None:
|
||||||
print(f'+ {command}')
|
print(f'+ {command}')
|
||||||
subprocess.check_call(command, env=env, cwd=cwd, shell=True)
|
subprocess.run(command, env=env, cwd=cwd, shell=True, check=True)
|
||||||
|
|
||||||
|
|
||||||
def get_nuget_args(version: str, arch: str) -> List[str]:
|
def get_nuget_args(version: str, arch: str) -> List[str]:
|
||||||
python_name = 'python' if version[0] == '3' else 'python2'
|
python_name = 'python' if version[0] == '3' else 'python2'
|
||||||
if arch == '32':
|
if arch == '32':
|
||||||
python_name = python_name + 'x86'
|
python_name += 'x86'
|
||||||
return [python_name, '-Version', version, '-OutputDirectory', 'C:\\cibw\\python']
|
return [
|
||||||
|
python_name,
|
||||||
|
'-Version', version,
|
||||||
|
'-FallbackSource', 'https://api.nuget.org/v3/index.json',
|
||||||
|
'-OutputDirectory', 'C:\\cibw\\python',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class PythonConfiguration(NamedTuple):
|
class PythonConfiguration(NamedTuple):
|
||||||
@@ -69,10 +73,9 @@ def get_python_configurations(
|
|||||||
'64': Architecture.AMD64,
|
'64': Architecture.AMD64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Only supported with custom compiler, since MS removed the 2008 compiler download
|
||||||
custom_compiler = os.environ.get('DISTUTILS_USE_SDK') and os.environ.get('MSSdk')
|
custom_compiler = os.environ.get('DISTUTILS_USE_SDK') and os.environ.get('MSSdk')
|
||||||
if IS_RUNNING_ON_TRAVIS and not custom_compiler:
|
if not custom_compiler:
|
||||||
# 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')]
|
python_configurations = [c for c in python_configurations if not c.version.startswith('2.7')]
|
||||||
|
|
||||||
# skip builds as required
|
# skip builds as required
|
||||||
@@ -152,7 +155,7 @@ def setup_python(python_configuration: PythonConfiguration, dependency_constrain
|
|||||||
call(['where', 'python'], env=env)
|
call(['where', 'python'], env=env)
|
||||||
call(['python', '--version'], env=env)
|
call(['python', '--version'], env=env)
|
||||||
call(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)"'], env=env)
|
call(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)"'], env=env)
|
||||||
where_python = subprocess.check_output(['where', 'python'], env=env, universal_newlines=True).splitlines()[0].strip()
|
where_python = subprocess.run(['where', 'python'], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE).stdout.splitlines()[0].strip()
|
||||||
if where_python != str(installation_path / 'python.exe'):
|
if where_python != str(installation_path / 'python.exe'):
|
||||||
print("cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.", file=sys.stderr)
|
print("cibuildwheel: python available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert python above it.", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -161,7 +164,7 @@ def setup_python(python_configuration: PythonConfiguration, dependency_constrain
|
|||||||
if not (installation_path / 'Scripts' / 'pip.exe').exists():
|
if not (installation_path / 'Scripts' / 'pip.exe').exists():
|
||||||
call(['python', get_pip_script, *dependency_constraint_flags], env=env, cwd="C:\\cibw")
|
call(['python', get_pip_script, *dependency_constraint_flags], env=env, cwd="C:\\cibw")
|
||||||
assert (installation_path / 'Scripts' / 'pip.exe').exists()
|
assert (installation_path / 'Scripts' / 'pip.exe').exists()
|
||||||
where_pip = subprocess.check_output(['where', 'pip'], env=env, universal_newlines=True).splitlines()[0].strip()
|
where_pip = subprocess.run(['where', 'pip'], env=env, universal_newlines=True, check=True, stdout=subprocess.PIPE).stdout.splitlines()[0].strip()
|
||||||
if where_pip.strip() != str(installation_path / 'Scripts' / 'pip.exe'):
|
if where_pip.strip() != str(installation_path / 'Scripts' / 'pip.exe'):
|
||||||
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
|
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@@ -295,13 +298,13 @@ def build(options: BuildOptions) -> None:
|
|||||||
])
|
])
|
||||||
|
|
||||||
# check that we are using the Python from the virtual environment
|
# check that we are using the Python from the virtual environment
|
||||||
call(['which', 'python'], env=virtualenv_env)
|
call(['where', 'python'], env=virtualenv_env)
|
||||||
|
|
||||||
if options.before_test:
|
if options.before_test:
|
||||||
before_test_prepared = prepare_command(
|
before_test_prepared = prepare_command(
|
||||||
options.before_test,
|
options.before_test,
|
||||||
project='.',
|
project='.',
|
||||||
package=options.package_dir
|
package=options.package_dir,
|
||||||
)
|
)
|
||||||
shell(before_test_prepared, env=virtualenv_env)
|
shell(before_test_prepared, env=virtualenv_env)
|
||||||
|
|
||||||
@@ -318,7 +321,7 @@ def build(options: BuildOptions) -> None:
|
|||||||
test_command_prepared = prepare_command(
|
test_command_prepared = prepare_command(
|
||||||
options.test_command,
|
options.test_command,
|
||||||
project=Path('.').resolve(),
|
project=Path('.').resolve(),
|
||||||
package=options.package_dir.resolve()
|
package=options.package_dir.resolve(),
|
||||||
)
|
)
|
||||||
shell(test_command_prepared, cwd='c:\\', env=virtualenv_env)
|
shell(test_command_prepared, cwd='c:\\', env=virtualenv_env)
|
||||||
|
|
||||||
|
|||||||
+17
-17
@@ -2,9 +2,9 @@
|
|||||||
title: Contributing
|
title: Contributing
|
||||||
---
|
---
|
||||||
|
|
||||||
Wheel-building can be pretty complex. I expect users to find many edge-cases - please help the rest of the community out by documenting these, adding features to support them, and reporting bugs.
|
Wheel-building can be pretty complex. We expect users to find edge-cases - please help the rest of the community out by documenting these, adding features to support them, and reporting bugs.
|
||||||
|
|
||||||
I plan to be pretty liberal in accepting pull requests, as long as they align with the design goals below.
|
If you have an idea for a modification or feature, it's probably best to raise an issue first and discuss it with the maintainer team. Once we have rough consensus on a design, begin work in a PR.
|
||||||
|
|
||||||
`cibuildwheel` is indie open source. We're not paid to work on this.
|
`cibuildwheel` is indie open source. We're not paid to work on this.
|
||||||
|
|
||||||
@@ -27,12 +27,12 @@ cibuildwheel doesn't really do anything itself - it's always deferring to other
|
|||||||
|
|
||||||
We're not responsible for errors in those tools, for fixing errors/crashes there. But cibuildwheel's job is providing users with an 'integrated' user experience across those tools. We provide an abstraction. The user says 'build me some wheels', not 'open the docker container, build a wheel with pip, fix up the symbols with auditwheel' etc. However, errors have a habit of breaking abstractions. And this is where users get confused, because the mechanism of cibuildwheel is laid bare, and they must understand a little bit how it works to debug.
|
We're not responsible for errors in those tools, for fixing errors/crashes there. But cibuildwheel's job is providing users with an 'integrated' user experience across those tools. We provide an abstraction. The user says 'build me some wheels', not 'open the docker container, build a wheel with pip, fix up the symbols with auditwheel' etc. However, errors have a habit of breaking abstractions. And this is where users get confused, because the mechanism of cibuildwheel is laid bare, and they must understand a little bit how it works to debug.
|
||||||
|
|
||||||
So, if we can, I'd like to improve the experience on errors as well. In [this](https://github.com/joerick/cibuildwheel/issues/139) case, it takes a bit of knowledge to understand that the linux builds are happening in a totally different OS via docker, that the linked symbols won't match, that auditwheel will fail because of this. A problem with how the tools fit together, instead of the tools themselves.
|
So, if we can, I'd like to improve the experience on errors as well. In [this](https://github.com/joerick/cibuildwheel/issues/139) case, it takes a bit of knowledge to understand that the Linux builds are happening in a different OS via Docker, that the linked symbols won't match, that auditwheel will fail because of this. A problem with how the tools fit together, instead of the tools themselves.
|
||||||
|
|
||||||
Maintainer notes
|
Maintainer notes
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
## Local testing
|
### Local testing
|
||||||
|
|
||||||
You should run:
|
You should run:
|
||||||
|
|
||||||
@@ -44,10 +44,9 @@ pip install -e .[dev]
|
|||||||
|
|
||||||
To prepare a development environment.
|
To prepare a development environment.
|
||||||
|
|
||||||
## Testing minimal configs
|
### Testing sample configs
|
||||||
|
|
||||||
|
cibuildwheel's example configs can be tested on a simple project on cibuildwheel's existing CI. These should be run whenever the minimal configs change.
|
||||||
cibuildwheel's _minimal_ example configs can be tested on a simple project on cibuildwheel's existing CI. These should be run whenever the minimal configs change.
|
|
||||||
|
|
||||||
To test minimal configs, make sure you have a clean git repo, then run the script:
|
To test minimal configs, make sure you have a clean git repo, then run the script:
|
||||||
|
|
||||||
@@ -57,9 +56,15 @@ bin/run_example_ci_configs.py
|
|||||||
|
|
||||||
The script will create an isolated 'orphan' commit containing all the minimal config CI files, and a simple C extension project, and push that to a branch on the `origin` repo. The project's CI is already set up to run on branch push, so will begin testing.
|
The script will create an isolated 'orphan' commit containing all the minimal config CI files, and a simple C extension project, and push that to a branch on the `origin` repo. The project's CI is already set up to run on branch push, so will begin testing.
|
||||||
|
|
||||||
|
You can test any other configs using `bin/run_example_ci_configs.py CONFIG_PATH`, e.g.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bin/run_example_ci_configs.py examples/github-with-qemu.yml
|
||||||
|
```
|
||||||
|
|
||||||
The script then outputs a Markdown table that can be copy/pasted into a PR to monitor and record the test.
|
The script then outputs a Markdown table that can be copy/pasted into a PR to monitor and record the test.
|
||||||
|
|
||||||
## Preparing environments
|
### Preparing environments
|
||||||
|
|
||||||
This has been moved to using docker, so you only need the following instructions if you add `--no-docker` to avoid using docker.
|
This has been moved to using docker, so you only need the following instructions if you add `--no-docker` to avoid using docker.
|
||||||
|
|
||||||
@@ -92,16 +97,9 @@ And, you need to install the requirements into each environment:
|
|||||||
for f in env*/bin/pip; do $f install pip-tools; done
|
for f in env*/bin/pip; do $f install pip-tools; done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Making a release
|
||||||
|
|
||||||
## Making a release
|
Before making a release, ensure pinned dependencies are up-to-date. Autoupdates are run weekly, with a PR being raised with any changes as required, so just make sure the latest one is merged before continuing.
|
||||||
|
|
||||||
Before making a release, ensure pinned dependencies are up-to-date. Run the script:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
bin/make_dependency_update_pr.py
|
|
||||||
```
|
|
||||||
|
|
||||||
If updates are needed, this will push a PR with those updates for the CI to test. Once green, merge this PR.
|
|
||||||
|
|
||||||
Then, increment the project version number using:
|
Then, increment the project version number using:
|
||||||
|
|
||||||
@@ -119,3 +117,5 @@ python setup.py sdist bdist_wheel
|
|||||||
twine upload dist/*
|
twine upload dist/*
|
||||||
git push && git push --tags
|
git push && git push --tags
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Then head to https://github.com/joerick/cibuildwheel/releases and create a GitHub release from the new tag, pasting in the changelog entry.
|
||||||
|
|||||||
@@ -30,9 +30,11 @@ For more details see https://en.cppreference.com/w/cpp/compiler_support, https:/
|
|||||||
|
|
||||||
## Windows and Python 2.7
|
## Windows and Python 2.7
|
||||||
|
|
||||||
Visual C++ for Python 2.7 does not support modern C++ standards (i.e., C++11 and later). When building on Appveyor, you will need to either use the "Visual Studio 2017" or "Visual Studio 2019" image, but Python 2.7 is not supported on these images - skip it by setting `CIBW_SKIP=cp27-win*`.
|
In previous years, Microsoft distributed a compiler toolchain called 'Visual C++ for Python 2.7', which was a distribution of MSVC 2008 that was created to make it easier to build Python 2.7 extensions on Windows, because it was fully compatible with the toolchain that built Python 2.7.
|
||||||
|
|
||||||
There is an optional workaround for this, though: the pybind11 project argues and shows that it is [possible to compile Python 2.7 extension with a newer compiler](https://pybind11.readthedocs.io/en/stable/faq.html#working-with-ancient-visual-studio-2008-builds-on-windows) and has an example project showing how to do this: https://github.com/pybind/python_example. The main catch is that a user might need to install [a newer "Microsoft Visual C++ Redistributable"](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads), since the newer C++ standard library's binaries are not included by default with the Python 2.7 installation.
|
This toolchain does not support modern C++ standards (i.e., C++11 and later). And it is hard to find this toolchain these days, since Microsoft removed the download for the required Visual Studio 2008 needed to build a native extension in April, 2021. So, by default, cibuildwheel does not attempt to build Python 2.7 extensions on Windows.
|
||||||
|
|
||||||
|
There is an optional workaround, though: the pybind11 project argues and shows that it is [possible to compile Python 2.7 extension with a newer compiler](https://pybind11.readthedocs.io/en/stable/faq.html#working-with-ancient-visual-studio-2008-builds-on-windows) and has an example project showing how to do this: https://github.com/pybind/python_example. The main catch is that a user might need to install [a newer "Microsoft Visual C++ Redistributable"](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads), since the newer C++ standard library's binaries are not included by default with the Python 2.7 installation.
|
||||||
|
|
||||||
Forcing `distutils` or `setuptools` to use a more recent version of MSVC that supports modern C++ can be done in the following way:
|
Forcing `distutils` or `setuptools` to use a more recent version of MSVC that supports modern C++ can be done in the following way:
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
# name: required, printed name
|
# name: required, printed name
|
||||||
# gh: GitHub repo (eventually a url: could be added for non-github projects)
|
# gh: GitHub repo (eventually a url: could be added for non-github projects)
|
||||||
# stars: GitHub repo (optional, if different from package, such as for Twisted)
|
# stars: GitHub repo (optional, if different from package, such as for Twisted)
|
||||||
|
# pypi: The pypi name, if different from the GitHub package name
|
||||||
# os: Operating system list, [windows, apple, linux] (optional)
|
# os: Operating system list, [windows, apple, linux] (optional)
|
||||||
# ci: [appveyor, github, azurepipelines, circleci, gitlab, travisci] (optional)
|
# ci: [appveyor, github, azurepipelines, circleci, gitlab, travisci] (optional)
|
||||||
# notes: (text, optional)
|
# notes: (text, optional)
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
- name: Parselmouth
|
- name: Parselmouth
|
||||||
gh: YannickJadoul/Parselmouth
|
gh: YannickJadoul/Parselmouth
|
||||||
|
pypi: praat-parselmouth
|
||||||
notes: A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels.
|
notes: A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels.
|
||||||
ci: [github]
|
ci: [github]
|
||||||
os: [windows, apple, linux]
|
os: [windows, apple, linux]
|
||||||
@@ -82,6 +84,7 @@
|
|||||||
|
|
||||||
- name: PyAV
|
- name: PyAV
|
||||||
gh: PyAV-Org/PyAV
|
gh: PyAV-Org/PyAV
|
||||||
|
pypi: av
|
||||||
ci: [github]
|
ci: [github]
|
||||||
os: [windows, apple, linux]
|
os: [windows, apple, linux]
|
||||||
notes: Pythonic bindings for FFmpeg's libraries.
|
notes: Pythonic bindings for FFmpeg's libraries.
|
||||||
@@ -109,6 +112,7 @@
|
|||||||
|
|
||||||
- name: etebase-py
|
- name: etebase-py
|
||||||
gh: etesync/etebase-py
|
gh: etesync/etebase-py
|
||||||
|
pypi: etebase
|
||||||
notes: Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed.
|
notes: Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed.
|
||||||
ci: [travisci]
|
ci: [travisci]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
@@ -175,6 +179,7 @@
|
|||||||
|
|
||||||
- name: jq.py
|
- name: jq.py
|
||||||
gh: mwilliamson/jq.py
|
gh: mwilliamson/jq.py
|
||||||
|
pypi: jq
|
||||||
ci: [travisci]
|
ci: [travisci]
|
||||||
os: [apple, linux]
|
os: [apple, linux]
|
||||||
|
|
||||||
@@ -226,6 +231,7 @@
|
|||||||
|
|
||||||
- name: Dependency Injector
|
- name: Dependency Injector
|
||||||
gh: ets-labs/python-dependency-injector
|
gh: ets-labs/python-dependency-injector
|
||||||
|
pypi: dependency-injector
|
||||||
ci: [travisci]
|
ci: [travisci]
|
||||||
os: [windows, apple, linux]
|
os: [windows, apple, linux]
|
||||||
notes: Dependency injection framework for Python, uses Windows TravisCI
|
notes: Dependency injection framework for Python, uses Windows TravisCI
|
||||||
@@ -237,11 +243,13 @@
|
|||||||
|
|
||||||
- name: PyTables
|
- name: PyTables
|
||||||
gh: PyTables/PyTables
|
gh: PyTables/PyTables
|
||||||
|
pypi: tables
|
||||||
ci: [github]
|
ci: [github]
|
||||||
os: [windows, apple, linux]
|
os: [windows, apple, linux]
|
||||||
|
|
||||||
- name: dd-trace-py
|
- name: dd-trace-py
|
||||||
gh: DataDog/dd-trace-py
|
gh: DataDog/dd-trace-py
|
||||||
|
pypi: ddtrace
|
||||||
ci: [github]
|
ci: [github]
|
||||||
os: [windows, apple, linux]
|
os: [windows, apple, linux]
|
||||||
notes: Uses custom alternate arch emulation on GitHub
|
notes: Uses custom alternate arch emulation on GitHub
|
||||||
@@ -270,6 +278,7 @@
|
|||||||
- name: MyPy
|
- name: MyPy
|
||||||
gh: mypyc/mypy_mypyc-wheels
|
gh: mypyc/mypy_mypyc-wheels
|
||||||
stars: python/mypy
|
stars: python/mypy
|
||||||
|
pypi: mypy
|
||||||
ci: [github]
|
ci: [github]
|
||||||
os: [apple, linux, windows]
|
os: [apple, linux, windows]
|
||||||
notes: MyPyC, the compiled component of MyPy.
|
notes: MyPyC, the compiled component of MyPy.
|
||||||
@@ -277,6 +286,7 @@
|
|||||||
- name: Imagecodecs (fork)
|
- name: Imagecodecs (fork)
|
||||||
gh: czaki/imagecodecs_build
|
gh: czaki/imagecodecs_build
|
||||||
stars: cgohlke/imagecodecs
|
stars: cgohlke/imagecodecs
|
||||||
|
pypi: imagecodecs
|
||||||
ci: [azurepipelines]
|
ci: [azurepipelines]
|
||||||
ci_config: azure-pipelines.yaml
|
ci_config: azure-pipelines.yaml
|
||||||
os: [apple, linux]
|
os: [apple, linux]
|
||||||
@@ -287,3 +297,30 @@
|
|||||||
ci: [github]
|
ci: [github]
|
||||||
os: [apple, linux, windows]
|
os: [apple, linux, windows]
|
||||||
notes: Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example.
|
notes: Extensive Cython + NumPy [pyproject.toml](https://github.com/deepcharles/ruptures/blob/master/pyproject.toml) example.
|
||||||
|
|
||||||
|
- name: time-machine
|
||||||
|
gh: adamchainz/time-machine
|
||||||
|
ci: [github]
|
||||||
|
os: [apple, linux, windows]
|
||||||
|
notes: Time mocking library using only the CPython C API.
|
||||||
|
|
||||||
|
- name: polaroid
|
||||||
|
gh: daggy1234/polaroid
|
||||||
|
ci: [github]
|
||||||
|
os: [apple, linux, windows]
|
||||||
|
notes: Full range of wheels for setuptools rust, with auto release and PyPI deploy.
|
||||||
|
|
||||||
|
- name: python-snappy
|
||||||
|
gh: andrix/python-snappy
|
||||||
|
ci: [github]
|
||||||
|
os: [apple, linux, windows]
|
||||||
|
|
||||||
|
- name: sourmash
|
||||||
|
gh: dib-lab/sourmash
|
||||||
|
ci: [github]
|
||||||
|
os: [apple, linux, windows]
|
||||||
|
|
||||||
|
- name: markupsafe
|
||||||
|
gh: pallets/markupsafe
|
||||||
|
ci: [github]
|
||||||
|
os: [apple, linux, windows]
|
||||||
|
|||||||
+66
-1
@@ -3,13 +3,14 @@
|
|||||||
|
|
||||||
p {
|
p {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
line-height: 26px;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
background-color: rgba(27,31,35,.05);
|
background-color: rgba(27,31,35,.05);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: .2em .4em;
|
padding: .15em .4em;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
border: none;
|
border: none;
|
||||||
margin: 0 1px;
|
margin: 0 1px;
|
||||||
@@ -39,6 +40,14 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rst-content .admonition {
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admonition code {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Code block filename style
|
Code block filename style
|
||||||
|
|
||||||
@@ -89,3 +98,59 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
|
|
||||||
/* import font awesome 4 for icons */
|
/* import font awesome 4 for icons */
|
||||||
@import url(https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css);
|
@import url(https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css);
|
||||||
|
|
||||||
|
|
||||||
|
/* Tabs */
|
||||||
|
|
||||||
|
/* Style the tab */
|
||||||
|
.tabs {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs-header {
|
||||||
|
background-color: white;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
border-bottom: 2px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style the buttons that are used to open the tab content */
|
||||||
|
.tabs-header button {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
color: inherit;
|
||||||
|
font: inherit;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
|
||||||
|
/* put the border on top of the parent border */
|
||||||
|
margin-bottom: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs-header button:focus-visible {
|
||||||
|
/* preserve an outline for accesibility purposes */
|
||||||
|
outline: 1px solid currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change background color of buttons on hover */
|
||||||
|
.tabs-header button:hover {
|
||||||
|
background-color: rgba(0, 0, 0, 0.02);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create an active/current tablink class */
|
||||||
|
.tabs-header button.active {
|
||||||
|
color: #4086bd;
|
||||||
|
border-bottom-color: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style the tab content */
|
||||||
|
.tabs-content {
|
||||||
|
background-color: #f1f6fa;
|
||||||
|
padding: 1px 1em;
|
||||||
|
padding-top: 0.8em;
|
||||||
|
}
|
||||||
|
|||||||
+46
-1
@@ -1,4 +1,49 @@
|
|||||||
|
// add classes for code-block-filename styling
|
||||||
$('.rst-content pre')
|
$('.rst-content pre')
|
||||||
.prev('blockquote')
|
.prev('blockquote')
|
||||||
.addClass('code-block-filename');
|
.addClass('code-block-filename');
|
||||||
|
|
||||||
|
var tabConversionIterations = 0
|
||||||
|
|
||||||
|
// convert tab admonition to tabs
|
||||||
|
while (true) {
|
||||||
|
const firstTab = $('.rst-content .admonition.tab').first()
|
||||||
|
if (firstTab.length == 0) break;
|
||||||
|
|
||||||
|
const otherTabs = firstTab.nextUntil(':not(.admonition.tab)');
|
||||||
|
const allTabs = $($.merge($.merge([], firstTab), otherTabs));
|
||||||
|
|
||||||
|
const tabContainer = $('<div>').addClass('tabs');
|
||||||
|
const headerContainer = $('<div>').addClass('tabs-header');
|
||||||
|
const contentContainer = $('<div>').addClass('tabs-content');
|
||||||
|
|
||||||
|
tabContainer.insertBefore(firstTab);
|
||||||
|
tabContainer.append(headerContainer, contentContainer)
|
||||||
|
|
||||||
|
const selectTab = function (index) {
|
||||||
|
headerContainer.children().removeClass('active')
|
||||||
|
headerContainer.children().eq(index).addClass('active')
|
||||||
|
contentContainer.children().hide()
|
||||||
|
contentContainer.children().eq(index).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
allTabs.each(function (tabI, el) {
|
||||||
|
const $el = $(el)
|
||||||
|
const titleElement = $el.children('.admonition-title')
|
||||||
|
const title = titleElement.text()
|
||||||
|
const button = $('<button>').text(title)
|
||||||
|
button.click(function () {
|
||||||
|
selectTab(tabI)
|
||||||
|
})
|
||||||
|
headerContainer.append(button)
|
||||||
|
|
||||||
|
titleElement.remove()
|
||||||
|
$el.removeClass('admonition')
|
||||||
|
contentContainer.append($el)
|
||||||
|
})
|
||||||
|
|
||||||
|
selectTab(0)
|
||||||
|
|
||||||
|
// this will catch infinite loops which can occur when editing the above
|
||||||
|
if (tabConversionIterations++ > 1000) throw 'too many iterations'
|
||||||
|
}
|
||||||
|
|||||||
+35
-3
@@ -18,7 +18,7 @@ If your wheel didn't compile, check the list below for some debugging tips.
|
|||||||
|
|
||||||
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:
|
Linux wheels are built in the [`manylinux` docker images](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 571](https://www.python.org/dev/peps/pep-0571/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
|
||||||
|
|
||||||
- Programs and libraries cannot be installed on the Travis CI Ubuntu host with `apt-get`, but can be installed inside of the Docker image using `yum` or manually. The same goes for environment variables that are potentially needed to customize the wheel building. `cibuildwheel` supports this by providing the `CIBW_ENVIRONMENT` and `CIBW_BEFORE_BUILD` options to setup the build environment inside the running Docker image. See [the options docs](options.md#build-environment) for details on these options.
|
- Programs and libraries are not installed on the Travis CI Ubuntu host, but rather should be installed inside of the Docker image (using `yum` for `manylinux2010` or `manylinux2014`, and `apt-get` for `manylinux_2_24`) or manually. The same goes for environment variables that are potentially needed to customize the wheel building. `cibuildwheel` supports this by providing the `CIBW_ENVIRONMENT` and `CIBW_BEFORE_BUILD` options to setup the build environment inside the running Docker image. See [the options docs](options.md#build-environment) for details on these options.
|
||||||
|
|
||||||
- The project directory is mounted in the running Docker instance as `/project`, the output directory for the wheels as `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system. Note that this is not available on CircleCI due to their Docker policies.
|
- 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.
|
||||||
|
|
||||||
@@ -105,6 +105,7 @@ Actions. Once QEMU is set up and registered, you just need to set the
|
|||||||
Linux), and the other architectures are emulated automatically.
|
Linux), and the other architectures are emulated automatically.
|
||||||
|
|
||||||
> .github/workflows/build.yml
|
> .github/workflows/build.yml
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
{% include "../examples/github-with-qemu.yml" %}
|
{% include "../examples/github-with-qemu.yml" %}
|
||||||
```
|
```
|
||||||
@@ -130,10 +131,41 @@ Hopefully, this is a temporary situation. Once we have widely available Apple Si
|
|||||||
Here's an example GitHub Actions workflow with a job that builds for Apple Silicon:
|
Here's an example GitHub Actions workflow with a job that builds for Apple Silicon:
|
||||||
|
|
||||||
> .github/workflows/build_macos.yml
|
> .github/workflows/build_macos.yml
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
{% include "../examples/github-apple-silicon.yml" %}
|
{% include "../examples/github-apple-silicon.yml" %}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Windows and Python 2.7
|
||||||
|
|
||||||
|
Building 2.7 extensions on Windows is difficult, because the VS 2008 compiler that was used for the original Python compilation was discontinued in 2018, and has since been removed from Microsoft's downloads. Most people choose to not build Windows 2.7 wheels, or to override the compiler to something more modern.
|
||||||
|
|
||||||
|
To override, you need to have a modern compiler toolchain activated, and set `DISTUTILS_USE_SDK=1` and `MSSdk=1`. For example, on GitHub Actions, you would add these steps:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Prepare compiler environment for Windows
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: x64
|
||||||
|
|
||||||
|
- name: Set Windows environment variables
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "DISTUTILS_USE_SDK=1" >> $GITHUB_ENV
|
||||||
|
echo "MSSdk=1" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
# invoke cibuildwheel...
|
||||||
|
```
|
||||||
|
|
||||||
|
cibuildwheel will not try to build 2.7 on Windows unless it detects that the above two variables are set. Note that changing to a more modern compiler will mean your wheel picks up a runtime dependency to a different [Visual C++ Redistributable][]. You also need to be [a bit careful][] in designing your extension; some major binding tools like pybind11 do this for you.
|
||||||
|
|
||||||
|
More on setting a custom Windows toolchain in our docs on modern C++ standards [here](cpp_standards.md#windows-and-python-27).
|
||||||
|
|
||||||
|
[Visual C++ Redistributable]: https://support.microsoft.com/en-us/topic/the-latest-supported-visual-c-downloads-2647da03-1eea-4433-9aff-95f26a218cc0
|
||||||
|
[a bit careful]: https://pybind11.readthedocs.io/en/stable/faq.html#working-with-ancient-visual-studio-2008-builds-on-windows
|
||||||
|
|
||||||
### Building packages with optional C extensions
|
### Building packages with optional C extensions
|
||||||
|
|
||||||
`cibuildwheel` defines the environment variable `CIBUILDWHEEL` to the value `1` allowing projects for which the C extension is optional to make it mandatory when building wheels.
|
`cibuildwheel` defines the environment variable `CIBUILDWHEEL` to the value `1` allowing projects for which the C extension is optional to make it mandatory when building wheels.
|
||||||
@@ -203,7 +235,7 @@ There are two suggested methods for keeping cibuildwheel up to date that instead
|
|||||||
If you use GitHub Actions for builds, you can use cibuildwheel as an action:
|
If you use GitHub Actions for builds, you can use cibuildwheel as an action:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
uses: joerick/cibuildwheel@v1.9.0
|
uses: joerick/cibuildwheel@v1.10.1
|
||||||
```
|
```
|
||||||
|
|
||||||
This is a composite step that just runs cibuildwheel using pipx. You can set command-line options as `with:` parameters, and use `env:` as normal.
|
This is a composite step that just runs cibuildwheel using pipx. You can set command-line options as `with:` parameters, and use `env:` as normal.
|
||||||
@@ -229,7 +261,7 @@ The second option, and the only one that supports other CI systems, is using a `
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# requirements-cibw.txt
|
# requirements-cibw.txt
|
||||||
cibuildwheel==1.9.0
|
cibuildwheel==1.10.1
|
||||||
```
|
```
|
||||||
|
|
||||||
Then your install step would have `python -m pip install -r requirements-cibw.txt` in it. Your `dependabot.yml` file could look like this:
|
Then your install step would have `python -m pip install -r requirements-cibw.txt` in it. Your `dependabot.yml` file could look like this:
|
||||||
|
|||||||
+138
-70
@@ -4,50 +4,78 @@
|
|||||||
|
|
||||||
## Setting options
|
## Setting options
|
||||||
|
|
||||||
cibuildwheel is configured using environment variables, that can be set using
|
cibuildwheel is configured using environment variables that can be set using
|
||||||
your CI config.
|
your CI config.
|
||||||
|
|
||||||
For example, to configure cibuildwheel to run tests, add the following YAML to
|
For example, to configure cibuildwheel to run tests, add the following YAML to
|
||||||
your CI config file:
|
your CI config file:
|
||||||
|
|
||||||
> .travis.yml ([docs](https://docs.travis-ci.com/user/environment-variables/))
|
|
||||||
```yaml
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- CIBW_TEST_REQUIRES=pytest
|
|
||||||
- CIBW_TEST_COMMAND="pytest {project}/tests"
|
|
||||||
```
|
|
||||||
|
|
||||||
> appveyor.yml ([docs](https://www.appveyor.com/docs/build-configuration/#environment-variables))
|
!!! tab "GitHub Actions"
|
||||||
```yaml
|
|
||||||
environment:
|
|
||||||
global:
|
|
||||||
CIBW_TEST_REQUIRES: pytest
|
|
||||||
CIBW_TEST_COMMAND: "pytest {project}\\tests"
|
|
||||||
```
|
|
||||||
|
|
||||||
> .circleci/config.yml ([docs](https://circleci.com/docs/2.0/configuration-reference/#environment))
|
> .github/workflows/*.yml ([docs](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables)) (can be global, in job, or in step)
|
||||||
```yaml
|
|
||||||
jobs:
|
```yaml
|
||||||
job_name:
|
env:
|
||||||
environment:
|
|
||||||
CIBW_TEST_REQUIRES: pytest
|
CIBW_TEST_REQUIRES: pytest
|
||||||
CIBW_TEST_COMMAND: "pytest {project}/tests"
|
CIBW_TEST_COMMAND: "pytest {project}/tests"
|
||||||
```
|
```
|
||||||
|
|
||||||
> azure-pipelines.yml ([docs](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables))
|
!!! tab "Azure Pipelines"
|
||||||
```yaml
|
|
||||||
variables:
|
> azure-pipelines.yml ([docs](https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables))
|
||||||
CIBW_TEST_REQUIRES: pytest
|
|
||||||
CIBW_TEST_COMMAND: "pytest {project}/tests"
|
```yaml
|
||||||
```
|
variables:
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: "pytest {project}/tests"
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tab "Travis CI"
|
||||||
|
|
||||||
|
> .travis.yml ([docs](https://docs.travis-ci.com/user/environment-variables/))
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- CIBW_TEST_REQUIRES=pytest
|
||||||
|
- CIBW_TEST_COMMAND="pytest {project}/tests"
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tab "AppVeyor"
|
||||||
|
|
||||||
|
> appveyor.yml ([docs](https://www.appveyor.com/docs/build-configuration/#environment-variables))
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
global:
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: "pytest {project}\\tests"
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tab "CircleCI"
|
||||||
|
|
||||||
|
> .circleci/config.yml ([docs](https://circleci.com/docs/2.0/configuration-reference/#environment))
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
job_name:
|
||||||
|
environment:
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: "pytest {project}/tests"
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tab "Gitlab CI"
|
||||||
|
|
||||||
|
> .gitlab-ci.yml ([docs](https://docs.gitlab.com/ee/ci/variables/README.html#create-a-custom-variable-in-gitlab-ciyml))
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
linux:
|
||||||
|
variables:
|
||||||
|
CIBW_TEST_REQUIRES: pytest
|
||||||
|
CIBW_TEST_COMMAND: "pytest {project}/tests"
|
||||||
|
```
|
||||||
|
|
||||||
> .github/workflows/*.yml ([docs](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables)) (can be global, in job, or in step)
|
|
||||||
```yaml
|
|
||||||
env:
|
|
||||||
CIBW_TEST_REQUIRES: pytest
|
|
||||||
CIBW_TEST_COMMAND: "pytest {project}/tests"
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## Build selection
|
## Build selection
|
||||||
@@ -62,37 +90,48 @@ Default: `auto`
|
|||||||
|
|
||||||
`auto` will auto-detect platform using environment variables, such as `TRAVIS_OS_NAME`/`APPVEYOR`/`CIRCLECI`.
|
`auto` will auto-detect platform using environment variables, such as `TRAVIS_OS_NAME`/`APPVEYOR`/`CIRCLECI`.
|
||||||
|
|
||||||
For `linux` you need Docker running, on macOS or Linux. For `macos`, you need a Mac machine, and note that this script is going to automatically install MacPython on your system, so don't run on your development machine. For `windows`, you need to run in Windows, and `cibuildwheel` will install required versions of Python to `C:\cibw\python` using NuGet.
|
- For `linux`, you need Docker running, on macOS or Linux.
|
||||||
|
- For `macos`, you need a Mac machine. Note that cibuildwheel is going to install MacPython on your system, so you probably don't want to run this on your development machine.
|
||||||
|
- For `windows`, you need to run in Windows. cibuildwheel will install required versions of Python to `C:\cibw\python` using NuGet.
|
||||||
|
|
||||||
This option can also be set using the [command-line option](#command-line) `--platform`.
|
This option can also be set using the [command-line option](#command-line) `--platform`.
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
If you have Docker installed, you can locally debug your cibuildwheel Linux config, instead of pushing to CI to test every change. For example:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export CIBW_BUILD='cp37-*'
|
||||||
|
export CIBW_TEST_COMMAND='pytest {package}/tests'
|
||||||
|
cibuildwheel --platform linux .
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### `CIBW_BUILD`, `CIBW_SKIP` {: #build-skip}
|
### `CIBW_BUILD`, `CIBW_SKIP` {: #build-skip}
|
||||||
|
|
||||||
> Choose the Python versions to build
|
> Choose the Python versions to build
|
||||||
|
|
||||||
Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux_x86_64` or `cp35-macosx_x86_64` - 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_x86_64` - 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.
|
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.
|
||||||
|
|
||||||
When setting the options, you can use shell-style globbing syntax, as per [`fnmatch`](https://docs.python.org/3/library/fnmatch.html) with the addition of curly bracket syntax `{option1,option2}`, provided by [`bracex`](https://pypi.org/project/bracex/). All the build identifiers supported by cibuildwheel are shown below:
|
When setting the options, you can use shell-style globbing syntax, as per [fnmatch](https://docs.python.org/3/library/fnmatch.html) with the addition of curly bracket syntax `{option1,option2}`, provided by [bracex](https://pypi.org/project/bracex/). All the build identifiers supported by cibuildwheel are shown below:
|
||||||
|
|
||||||
<div class="build-id-table-marker"></div>
|
<div class="build-id-table-marker"></div>
|
||||||
|
|
||||||
| | macOS 64bit | Manylinux x86 64bit | Manylinux x86 32bit | Windows 64bit | Windows 32bit | Manylinux Armv8 64bit | Manylinux PPC64LE | Manylinux s390x |
|
| | macOS | Windows | Manylinux Intel | Manylinux Other |
|
||||||
|-----------------|---------------------|------------------------|----------------------|-----------------|----------------|------------------------|------------------------|----------------------|
|
|--------------|---------------------------------------------------------------------|-------------------------------|-----------------------------------------------|----------------------------------------------------------------------------|
|
||||||
| Python 2.7 | cp27-macosx_x86_64 | cp27-manylinux_x86_64 | cp27-manylinux_i686 | cp27-win_amd64 | cp27-win32 | | | |
|
| Python 2.7 | cp27-macosx_x86_64 | cp27-win_amd64<br/>cp27-win32 | cp27-manylinux_x86_64<br/>cp27-manylinux_i686 | |
|
||||||
| Python 3.5 | cp35-macosx_x86_64 | cp35-manylinux_x86_64 | cp35-manylinux_i686 | cp35-win_amd64 | cp35-win32 | cp35-manylinux_aarch64 | cp35-manylinux_ppc64le | cp35-manylinux_s390x |
|
| Python 3.5 | cp35-macosx_x86_64 | cp35-win_amd64<br/>cp35-win32 | cp35-manylinux_x86_64<br/>cp35-manylinux_i686 | cp35-manylinux_aarch64<br/>cp35-manylinux_ppc64le<br/>cp35-manylinux_s390x |
|
||||||
| Python 3.6 | cp36-macosx_x86_64 | cp36-manylinux_x86_64 | cp36-manylinux_i686 | cp36-win_amd64 | cp36-win32 | cp36-manylinux_aarch64 | cp36-manylinux_ppc64le | cp36-manylinux_s390x |
|
| Python 3.6 | cp36-macosx_x86_64 | cp36-win_amd64<br/>cp36-win32 | cp36-manylinux_x86_64<br/>cp36-manylinux_i686 | cp36-manylinux_aarch64<br/>cp36-manylinux_ppc64le<br/>cp36-manylinux_s390x |
|
||||||
| Python 3.7 | cp37-macosx_x86_64 | cp37-manylinux_x86_64 | cp37-manylinux_i686 | cp37-win_amd64 | cp37-win32 | cp37-manylinux_aarch64 | cp37-manylinux_ppc64le | cp37-manylinux_s390x |
|
| Python 3.7 | cp37-macosx_x86_64 | cp37-win_amd64<br/>cp37-win32 | cp37-manylinux_x86_64<br/>cp37-manylinux_i686 | cp37-manylinux_aarch64<br/>cp37-manylinux_ppc64le<br/>cp37-manylinux_s390x |
|
||||||
| Python 3.8 | cp38-macosx_x86_64 | cp38-manylinux_x86_64 | cp38-manylinux_i686 | cp38-win_amd64 | cp38-win32 | cp38-manylinux_aarch64 | cp38-manylinux_ppc64le | cp38-manylinux_s390x |
|
| Python 3.8 | cp38-macosx_x86_64 | cp38-win_amd64<br/>cp38-win32 | cp38-manylinux_x86_64<br/>cp38-manylinux_i686 | cp38-manylinux_aarch64<br/>cp38-manylinux_ppc64le<br/>cp38-manylinux_s390x |
|
||||||
| Python 3.9 | cp39-macosx_x86_64 | cp39-manylinux_x86_64 | cp39-manylinux_i686 | cp39-win_amd64 | cp39-win32 | cp39-manylinux_aarch64 | cp39-manylinux_ppc64le | cp39-manylinux_s390x |
|
| Python 3.9 | cp39-macosx_x86_64<br/>cp39-macosx_universal2<br/>cp39-macosx_arm64 | cp39-win_amd64<br/>cp39-win32 | cp39-manylinux_x86_64<br/>cp39-manylinux_i686 | cp39-manylinux_aarch64<br/>cp39-manylinux_ppc64le<br/>cp39-manylinux_s390x |
|
||||||
| PyPy 2.7 v7.3.3 | pp27-macosx_x86_64 | pp27-manylinux_x86_64 | | | pp27-win32 | | | |
|
| PyPy2.7 v7.3 | pp27-macosx_x86_64 | pp27-win32 | pp27-manylinux_x86_64 | |
|
||||||
| PyPy 3.6 v7.3.3 | pp36-macosx_x86_64 | pp36-manylinux_x86_64 | | | pp36-win32 | | | |
|
| PyPy3.6 v7.3 | pp36-macosx_x86_64 | pp36-win32 | pp36-manylinux_x86_64 | |
|
||||||
| PyPy 3.7 (beta) v7.3.3 | pp37-macosx_x86_64 | pp37-manylinux_x86_64 | | | pp37-win32 | | | |
|
| PyPy3.7 v7.3 | pp37-macosx_x86_64 | pp37-win32 | pp37-manylinux_x86_64 | |
|
||||||
|
|
||||||
|
|
||||||
The list of supported and currently selected build identifiers can also be retrieved by passing the `--print-build-identifiers` flag to `cibuildwheel`.
|
The list of supported and currently selected build identifiers can also be retrieved by passing the `--print-build-identifiers` flag to cibuildwheel.
|
||||||
The format is `python_tag-platform_tag`, with tags similar to those in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details).
|
The format is `python_tag-platform_tag`, with tags similar to those in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details).
|
||||||
|
|
||||||
For CPython, the minimally supported macOS version is 10.9; for PyPy 2.7 and PyPy 3.6/3.7, respectively macOS 10.7 and 10.13 or higher is required.
|
For CPython, the minimally supported macOS version is 10.9; for PyPy 2.7 and PyPy 3.6/3.7, respectively macOS 10.7 and 10.13 or higher is required.
|
||||||
@@ -248,8 +287,8 @@ the package is compatible with all versions of Python that it can build.
|
|||||||
|
|
||||||
Currently, setuptools has not yet added support for reading this value from
|
Currently, setuptools has not yet added support for reading this value from
|
||||||
pyproject.toml yet, and so does not copy it to Requires-Python in the wheel
|
pyproject.toml yet, and so does not copy it to Requires-Python in the wheel
|
||||||
metadata. This mechanism is used by `pip` to scan through older versions of
|
metadata. This mechanism is used by pip to scan through older versions of
|
||||||
your package until it finds a release compatible with the curernt version
|
your package until it finds a release compatible with the current version
|
||||||
of Python compatible when installing, so it is an important value to set if
|
of Python compatible when installing, so it is an important value to set if
|
||||||
you plan to drop support for a version of Python in the future.
|
you plan to drop support for a version of Python in the future.
|
||||||
|
|
||||||
@@ -301,7 +340,7 @@ CIBW_ENVIRONMENT: "BUILD_TIME=$(date) SAMPLE_TEXT=\"sample text\""
|
|||||||
```
|
```
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
`cibuildwheel` always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](faq.md#building-packages-with-optional-c-extensions).
|
cibuildwheel always defines the environment variable `CIBUILDWHEEL=1`. This can be useful for [building wheels with optional extensions](faq.md#building-packages-with-optional-c-extensions).
|
||||||
|
|
||||||
### `CIBW_BEFORE_ALL` {: #before-all}
|
### `CIBW_BEFORE_ALL` {: #before-all}
|
||||||
> Execute a shell command on the build system before any wheels are built.
|
> Execute a shell command on the build system before any wheels are built.
|
||||||
@@ -310,7 +349,7 @@ Shell command to prepare a common part of the project (e.g. build or install lib
|
|||||||
|
|
||||||
This option is very useful for the Linux build, where builds take place in isolated Docker containers managed by cibuildwheel. This command will run inside the container before the wheel builds start. Note, if you're building both x86_64 and i686 wheels (the default), your build uses two different Docker images. In that case, this command will execute twice - once per build container.
|
This option is very useful for the Linux build, where builds take place in isolated Docker containers managed by cibuildwheel. This command will run inside the container before the wheel builds start. Note, if you're building both x86_64 and i686 wheels (the default), your build uses two different Docker images. In that case, this command will execute twice - once per build container.
|
||||||
|
|
||||||
The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by `cibuildwheel`.
|
The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by cibuildwheel.
|
||||||
|
|
||||||
On Windows and macOS, the version of Python available inside `CIBW_BEFORE_ALL` is whatever is available on the host machine. On Linux, a modern Python version is available on PATH.
|
On Windows and macOS, the version of Python available inside `CIBW_BEFORE_ALL` is whatever is available on the host machine. On Linux, a modern Python version is available on PATH.
|
||||||
|
|
||||||
@@ -326,6 +365,11 @@ CIBW_BEFORE_ALL: make -C third_party_lib
|
|||||||
CIBW_BEFORE_ALL_LINUX: yum install -y libffi-dev
|
CIBW_BEFORE_ALL_LINUX: yum install -y libffi-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that manylinux2_24 builds occur inside a Debian9 docker, where
|
||||||
|
manylinux2010 and manylinux2014 builds occur inside a CentOS one. So for
|
||||||
|
`manylinux2_24` the `CIBW_BEFORE_ALL_LINUX` command must use `apt-get -y`
|
||||||
|
instead.
|
||||||
|
|
||||||
### `CIBW_BEFORE_BUILD` {: #before-build}
|
### `CIBW_BEFORE_BUILD` {: #before-build}
|
||||||
> Execute a shell command preparing each wheel's build
|
> Execute a shell command preparing each wheel's build
|
||||||
|
|
||||||
@@ -333,7 +377,7 @@ A shell command to run before building the wheel. This option allows you to run
|
|||||||
|
|
||||||
If dependencies are required to build your wheel (for example if you include a header from a Python module), instead of using this command, we recommend adding requirements to a pyproject.toml file. This is reproducible, and users who do not get your wheels (such as Alpine or ClearLinux users) will still benefit.
|
If dependencies are required to build your wheel (for example if you include a header from a Python module), instead of using this command, we recommend adding requirements to a pyproject.toml file. This is reproducible, and users who do not get your wheels (such as Alpine or ClearLinux users) will still benefit.
|
||||||
|
|
||||||
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. The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by `cibuildwheel`.
|
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. The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by cibuildwheel.
|
||||||
|
|
||||||
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
|
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
|
||||||
|
|
||||||
@@ -393,7 +437,7 @@ Default:
|
|||||||
A shell command to repair a built wheel by copying external library dependencies into the wheel tree and relinking them.
|
A shell command to repair a built wheel by copying external library dependencies into the wheel tree and relinking them.
|
||||||
The command is run on each built wheel (except for pure Python ones) before testing it.
|
The command is run on each built wheel (except for pure Python ones) before testing it.
|
||||||
|
|
||||||
The following placeholders must be used inside the command and will be replaced by `cibuildwheel`:
|
The following placeholders must be used inside the command and will be replaced by cibuildwheel:
|
||||||
|
|
||||||
- `{wheel}` for the absolute path to the built wheel
|
- `{wheel}` for the absolute path to the built wheel
|
||||||
- `{dest_dir}` for the absolute path of the directory where to create the repaired wheel
|
- `{dest_dir}` for the absolute path of the directory where to create the repaired wheel
|
||||||
@@ -404,30 +448,53 @@ The command is run in a shell, so you can run multiple commands like `cmd1 && cm
|
|||||||
Platform-specific variants also available:<br/>
|
Platform-specific variants also available:<br/>
|
||||||
`CIBW_REPAIR_WHEEL_COMMAND_MACOS` | `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS` | `CIBW_REPAIR_WHEEL_COMMAND_LINUX`
|
`CIBW_REPAIR_WHEEL_COMMAND_MACOS` | `CIBW_REPAIR_WHEEL_COMMAND_WINDOWS` | `CIBW_REPAIR_WHEEL_COMMAND_LINUX`
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
cibuildwheel doesn't yet ship a default repair command for Windows.
|
||||||
|
|
||||||
|
**If that's an issue for you, check out [delvewheel]** - a new package that aims to do the same as auditwheel or delocate for Windows.
|
||||||
|
|
||||||
|
Because delvewheel is still relatively early-stage, cibuildwheel does not yet run it by default. However, we'd recommend giving it a try! See the examples below for usage.
|
||||||
|
|
||||||
|
[Delvewheel]: https://github.com/adang1345/delvewheel
|
||||||
|
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
|
# use delvewheel on windows (only works on Python 3.6+)
|
||||||
|
CIBW_BEFORE_BUILD_WINDOWS: "pip install delvewheel"
|
||||||
|
CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "delvewheel repair -w {dest_dir} {wheel}"
|
||||||
|
|
||||||
# don't repair macOS wheels
|
# don't repair macOS wheels
|
||||||
CIBW_REPAIR_WHEEL_COMMAND_MACOS: ""
|
CIBW_REPAIR_WHEEL_COMMAND_MACOS: ""
|
||||||
|
|
||||||
# pass the `--lib-sdir .` flag to auditwheel on Linux
|
# pass the `--lib-sdir .` flag to auditwheel on Linux
|
||||||
CIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel repair --lib-sdir . -w {dest_dir} {wheel}"
|
CIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel repair --lib-sdir . -w {dest_dir} {wheel}"
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### `CIBW_MANYLINUX_X86_64_IMAGE`, `CIBW_MANYLINUX_I686_IMAGE`, `CIBW_MANYLINUX_PYPY_X86_64_IMAGE`, `CIBW_MANYLINUX_AARCH64_IMAGE`, `CIBW_MANYLINUX_PPC64LE_IMAGE`, `CIBW_MANYLINUX_S390X_IMAGE` {: #manylinux-image}
|
### CIBW_MANYLINUX_*_IMAGE {: #manylinux-image}
|
||||||
> Specify alternative manylinux docker images
|
> Specify alternative manylinux Docker images
|
||||||
|
|
||||||
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), [`quay.io/pypa/manylinux2010_i686`](https://quay.io/pypa/manylinux2010_i686), [`pypywheels/manylinux2010-pypy_x86_64`](https://hub.docker.com/r/pypywheels/manylinux2010-pypy_x86_64), [`quay.io/pypa/manylinux2014_aarch64`](https://quay.io/pypa/manylinux2014_aarch64), [`quay.io/pypa/manylinux2014_ppc64le`](https://quay.io/pypa/manylinux2014_ppc64le), and [`quay.io/pypa/manylinux2014_s390x`](https://quay.io/pypa/manylinux2010_s390x).
|
The available options are:
|
||||||
|
|
||||||
The value of this option can either be set to `manylinux1`, `manylinux2010` or `manylinux2014` to use a pinned version of the [official `manylinux` images](https://github.com/pypa/manylinux) and [PyPy `manylinux` images](https://github.com/pypy/manylinux). Alternatively, set these options to any other valid Docker image name. Note that for PyPy, only the official `manylinux2010` image is currently available. For architectures other
|
- `CIBW_MANYLINUX_X86_64_IMAGE`
|
||||||
than x86 (x86\_64 and i686) manylinux2014 must be used because this is the first version of the manylinux specification that supports additional architectures.
|
- `CIBW_MANYLINUX_I686_IMAGE`
|
||||||
|
- `CIBW_MANYLINUX_PYPY_X86_64_IMAGE`
|
||||||
|
- `CIBW_MANYLINUX_AARCH64_IMAGE`
|
||||||
|
- `CIBW_MANYLINUX_PPC64LE_IMAGE`
|
||||||
|
- `CIBW_MANYLINUX_S390X_IMAGE`
|
||||||
|
|
||||||
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-, manylinux2010- or manylinux2014-compatible in order to produce valid `manylinux1`/`manylinux2010`/`manylinux2014` wheels (see [pypa/manylinux on GitHub](https://github.com/pypa/manylinux), [PEP 513](https://www.python.org/dev/peps/pep-0513/), [PEP 571](https://www.python.org/dev/peps/pep-0571/) and [PEP 599](https://www.python.org/dev/peps/pep-0599/) for more details).
|
Set 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), [`quay.io/pypa/manylinux2010_i686`](https://quay.io/pypa/manylinux2010_i686), [`pypywheels/manylinux2010-pypy_x86_64`](https://hub.docker.com/r/pypywheels/manylinux2010-pypy_x86_64), [`quay.io/pypa/manylinux2014_aarch64`](https://quay.io/pypa/manylinux2014_aarch64), [`quay.io/pypa/manylinux2014_ppc64le`](https://quay.io/pypa/manylinux2014_ppc64le), and [`quay.io/pypa/manylinux2014_s390x`](https://quay.io/pypa/manylinux2010_s390x).
|
||||||
|
|
||||||
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='AUDITWHEEL_PLAT="manylinux2010_$(uname -m)"'`).
|
The value of this option can either be set to `manylinux1`, `manylinux2010`, `manylinux2014` or `manylinux_2_24` to use a pinned version of the [official manylinux images](https://github.com/pypa/manylinux) and [PyPy manylinux images](https://github.com/pypy/manylinux). Alternatively, set these options to any other valid Docker image name. For PyPy, only the official `manylinux2010` image is currently available. For architectures other
|
||||||
|
than x86 (x86\_64 and i686) `manylinux2014` or `manylinux_2_24` must be used, because the first version of the manylinux specification that supports additional architectures is `manylinux2014`.
|
||||||
|
|
||||||
Note that `manylinux2014` doesn't support builds with Python 2.7 - when building with `manylinux2014`, skip Python 2.7 using `CIBW_SKIP` (see example below).
|
Note that `manylinux2014`/`manylinux_2_24` don't support builds with Python 2.7 - when building with `manylinux2014`/`manylinux_2_24`, skip Python 2.7 using `CIBW_SKIP` (see example below).
|
||||||
|
|
||||||
|
If setting a custom Docker image, you'll need to make sure it 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 compatible to the relevant standard to produce valid manylinux1/manylinux2010/manylinux2014/manylinux_2_24 wheels (see [pypa/manylinux on GitHub](https://github.com/pypa/manylinux), [PEP 513](https://www.python.org/dev/peps/pep-0513/), [PEP 571](https://www.python.org/dev/peps/pep-0571/), [PEP 599](https://www.python.org/dev/peps/pep-0599/) and [PEP 600](https://www.python.org/dev/peps/pep-0600/) for more details).
|
||||||
|
|
||||||
|
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='AUDITWHEEL_PLAT="manylinux2010_$(uname -m)"'`).
|
||||||
|
|
||||||
#### Examples
|
#### Examples
|
||||||
|
|
||||||
@@ -511,8 +578,8 @@ CIBW_DEPENDENCY_VERSIONS: ./constraints.txt
|
|||||||
|
|
||||||
Shell command to run tests after the build. The wheel will be installed
|
Shell command to run tests after the build. The wheel will be installed
|
||||||
automatically and available for import from the tests. To ensure the wheel is
|
automatically and available for import from the tests. To ensure the wheel is
|
||||||
imported by your tests (instead of your source copy), tests are run from a
|
imported by your tests (instead of your source copy), **tests are not run from
|
||||||
different directory. Use the placeholders `{project}` and `{package}` when
|
your project directory**. Use the placeholders `{project}` and `{package}` when
|
||||||
specifying paths in your project. If this variable is not set, your wheel will
|
specifying paths in your project. If this variable is not set, your wheel will
|
||||||
not be installed after building.
|
not be installed after building.
|
||||||
|
|
||||||
@@ -543,10 +610,10 @@ CIBW_TEST_COMMAND: "echo Wheel installed"
|
|||||||
### `CIBW_BEFORE_TEST` {: #before-test}
|
### `CIBW_BEFORE_TEST` {: #before-test}
|
||||||
> Execute a shell command before testing each wheel
|
> Execute a shell command before testing each wheel
|
||||||
|
|
||||||
A shell command to run in **each** test virtual environment, before your wheel is installed and tested. This is useful if you need to install a non pip package, change values of environment variables
|
A shell command to run in **each** test virtual environment, before your wheel is installed and tested. This is useful if you need to install a non-pip package, invoke pip with different environment variables,
|
||||||
or perform multi step pip installation (e.g. installing `scikit-build` or `cython` before install test package)
|
or perform a multi-step pip installation (e.g. installing scikit-build or Cython before installing test package).
|
||||||
|
|
||||||
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. The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by `cibuildwheel`.
|
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. The placeholder `{package}` can be used here; it will be replaced by the path to the package being built by cibuildwheel.
|
||||||
|
|
||||||
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
|
The command is run in a shell, so you can write things like `cmd1 && cmd2`.
|
||||||
|
|
||||||
@@ -611,7 +678,7 @@ CIBW_TEST_EXTRAS: test,qt
|
|||||||
### `CIBW_TEST_SKIP` {: #test-skip}
|
### `CIBW_TEST_SKIP` {: #test-skip}
|
||||||
> Skip running tests on some builds
|
> Skip running tests on some builds
|
||||||
|
|
||||||
This will skip testing on any identifiers that match the given skip patterns (see [`CIBW_SKIP`](#build-skip)). This can be used to mask out tests for wheels that have missing dependencies upstream that are slow or hard to build, or to mask up slow tests on emulated architectures.
|
This will skip testing on any identifiers that match the given skip patterns (see [`CIBW_SKIP`](#build-skip)). This can be used to mask out tests for wheels that have missing dependencies upstream that are slow or hard to build, or to skip slow tests on emulated architectures.
|
||||||
|
|
||||||
With macOS `universal2` wheels, you can also skip the the individual archs inside the wheel using an `:arch` suffix. For example, `cp39-macosx_universal2:x86_64` or `cp39-macosx_universal2:arm64`.
|
With macOS `universal2` wheels, you can also skip the the individual archs inside the wheel using an `:arch` suffix. For example, `cp39-macosx_universal2:x86_64` or `cp39-macosx_universal2:arm64`.
|
||||||
|
|
||||||
@@ -690,12 +757,13 @@ optional arguments:
|
|||||||
<style>
|
<style>
|
||||||
.options-toc {
|
.options-toc {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-auto-columns: fit-content(20%) 1fr;
|
grid-template-columns: fit-content(20%) 1fr;
|
||||||
grid-gap: 16px 32px;
|
grid-gap: 16px 32px;
|
||||||
gap: 16px 32px;
|
gap: 16px 32px;
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
margin-bottom: 28px;
|
margin-bottom: 28px;
|
||||||
margin-top: 28px;
|
margin-top: 28px;
|
||||||
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
.options-toc .header {
|
.options-toc .header {
|
||||||
grid-column: 1 / 3;
|
grid-column: 1 / 3;
|
||||||
@@ -721,7 +789,7 @@ optional arguments:
|
|||||||
|
|
||||||
$('.rst-content h3')
|
$('.rst-content h3')
|
||||||
.filter(function (i, el) {
|
.filter(function (i, el) {
|
||||||
return !!$(el).text().match(/(^([A-Z0-9, _]| and )+)¶$/);
|
return !!$(el).text().match(/(^([A-Z0-9, _*]| and )+)¶$/);
|
||||||
})
|
})
|
||||||
.each(function (i, el) {
|
.each(function (i, el) {
|
||||||
var optionName = $(el).text().replace('¶', '');
|
var optionName = $(el).text().replace('¶', '');
|
||||||
|
|||||||
+119
-35
@@ -4,12 +4,93 @@ title: 'Setup'
|
|||||||
|
|
||||||
# GitHub Actions [linux/mac/windows] {: #github-actions}
|
# GitHub Actions [linux/mac/windows] {: #github-actions}
|
||||||
|
|
||||||
To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/workflows/build.yml` file in your repo.
|
To build Linux, Mac, and Windows wheels using GitHub Actions, create a `.github/workflows/build_wheels.yml` file in your repo.
|
||||||
|
|
||||||
|
!!! tab "Action"
|
||||||
|
For GitHub Actions, `cibuildwheel` provides an action you can use. This is
|
||||||
|
concise and enables easier auto updating via GitHub's Dependabot; see
|
||||||
|
[Automatic updates](faq.md#automatic-updates).
|
||||||
|
|
||||||
|
> .github/workflows/build_wheels.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
{% include "../examples/github-minimal.yml" %}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
You can use `env:` with the action just like you would with `run:`; you can
|
||||||
|
also use `with:` to set the command line options: `package-dir: .` and
|
||||||
|
`output-dir: wheelhouse` (those values are the defaults).
|
||||||
|
|
||||||
|
!!! tab "pipx"
|
||||||
|
The GitHub Actions runners have pipx installed, so you can easily build in
|
||||||
|
just one line. This is internally how the action works; the main benefit of
|
||||||
|
the action form is easy updates via GitHub's Dependabot.
|
||||||
|
|
||||||
|
> .github/workflows/build_wheels.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_wheels:
|
||||||
|
name: Build wheels on ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-20.04, windows-2019, macos-10.15]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Build wheels
|
||||||
|
run: pipx run cibuildwheel==1.10.1
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
path: ./wheelhouse/*.whl
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! tab "Generic"
|
||||||
|
This is the most generic form using setup-python and pip; it looks the most
|
||||||
|
like the other CI examples. If you want to avoid having setup that takes
|
||||||
|
advantage of GitHub Actions features or pipx being preinstalled, this might
|
||||||
|
appeal to you.
|
||||||
|
|
||||||
|
> .github/workflows/build_wheels.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Build
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_wheels:
|
||||||
|
name: Build wheels on ${{ matrix.os }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-20.04, windows-2019, macos-10.15]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# Used to host cibuildwheel
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
|
||||||
|
- name: Install cibuildwheel
|
||||||
|
run: python -m pip install cibuildwheel==1.10.1
|
||||||
|
|
||||||
|
- name: Build wheels
|
||||||
|
run: python -m cibuildwheel --output-dir wheelhouse
|
||||||
|
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
path: ./wheelhouse/*.whl
|
||||||
|
```
|
||||||
|
|
||||||
> build.yml
|
|
||||||
```yaml
|
|
||||||
{% include "../examples/github-minimal.yml" %}
|
|
||||||
```
|
|
||||||
|
|
||||||
Commit this file, and push to GitHub - either to your default branch, or to a PR branch. The build should start automatically.
|
Commit this file, and push to GitHub - either to your default branch, or to a PR branch. The build should start automatically.
|
||||||
|
|
||||||
@@ -17,13 +98,13 @@ For more info on this file, check out the [docs](https://help.github.com/en/acti
|
|||||||
|
|
||||||
[`examples/github-deploy.yml`](https://github.com/joerick/cibuildwheel/blob/master/examples/github-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
|
[`examples/github-deploy.yml`](https://github.com/joerick/cibuildwheel/blob/master/examples/github-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
|
||||||
|
|
||||||
You can also use cibuildwheel directly as an action with `uses: joerick/cibuildwheel@v1.9.0`; this combines the download and run steps into a single action, and command line arguments are available via `with:`. This makes it easy to manage cibuildwheel updates via normal actions update mechanisms like dependabot, see [Automatic updates](faq.md#automatic-updates).
|
|
||||||
|
|
||||||
# Azure Pipelines [linux/mac/windows] {: #azure-pipelines}
|
# Azure Pipelines [linux/mac/windows] {: #azure-pipelines}
|
||||||
|
|
||||||
To build Linux, Mac, and Windows wheels on Azure Pipelines, create a `azure-pipelines.yml` file in your repo.
|
To build Linux, Mac, and Windows wheels on Azure Pipelines, create a `azure-pipelines.yml` file in your repo.
|
||||||
|
|
||||||
> azure-pipelines.yml
|
> azure-pipelines.yml
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
{% include "../examples/azure-pipelines-minimal.yml" %}
|
{% include "../examples/azure-pipelines-minimal.yml" %}
|
||||||
```
|
```
|
||||||
@@ -40,6 +121,7 @@ Wheels will be stored for you and available through the Pipelines interface. For
|
|||||||
To build Linux, Mac, and Windows wheels on Travis CI, create a `.travis.yml` file in your repo.
|
To build Linux, Mac, and Windows wheels on Travis CI, create a `.travis.yml` file in your repo.
|
||||||
|
|
||||||
> .travis.yml
|
> .travis.yml
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
{% include "../examples/travis-ci-minimal.yml" %}
|
{% include "../examples/travis-ci-minimal.yml" %}
|
||||||
```
|
```
|
||||||
@@ -52,35 +134,6 @@ Then setup a deployment method by following the [Travis CI deployment docs](http
|
|||||||
|
|
||||||
[`examples/travis-ci-deploy.yml`](https://github.com/joerick/cibuildwheel/blob/master/examples/travis-ci-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
|
[`examples/travis-ci-deploy.yml`](https://github.com/joerick/cibuildwheel/blob/master/examples/travis-ci-deploy.yml) extends this minimal example with a demonstration of how to automatically upload the built wheels to PyPI.
|
||||||
|
|
||||||
# CircleCI [linux/mac] {: #circleci}
|
|
||||||
|
|
||||||
To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo,
|
|
||||||
|
|
||||||
> .circleci/config.yml
|
|
||||||
```yaml
|
|
||||||
{% include "../examples/circleci-minimal.yml" %}
|
|
||||||
```
|
|
||||||
|
|
||||||
Commit this file, enable building of your repo on CircleCI, and push.
|
|
||||||
|
|
||||||
!!! note
|
|
||||||
CircleCI doesn't enable free macOS containers for open source by default, but you can ask for access. See [here](https://circleci.com/docs/2.0/oss/#overview) for more information.
|
|
||||||
|
|
||||||
CircleCI will store the built wheels for you - you can access them from the project console. Check out the CircleCI [docs](https://circleci.com/docs/2.0/configuration-reference/#section=configuration) for more info on this config file.
|
|
||||||
|
|
||||||
# Gitlab CI [linux] {: #gitlab-ci}
|
|
||||||
|
|
||||||
To build Linux wheels on Gitlab CI, create a `.gitlab-ci.yml` file in your repo,
|
|
||||||
|
|
||||||
> .gitlab-ci.yml
|
|
||||||
```yaml
|
|
||||||
{% include "../examples/gitlab-minimal.yml" %}
|
|
||||||
```
|
|
||||||
|
|
||||||
Commit this file, and push to Gitlab. The pipeline should start automatically.
|
|
||||||
|
|
||||||
Gitlab will store the built wheels for you - you can access them from the Pipelines view. Check out the Gitlab [docs](https://docs.gitlab.com/ee/ci/yaml/) for more info on this config file.
|
|
||||||
|
|
||||||
# AppVeyor [linux/mac/windows] {: #appveyor}
|
# AppVeyor [linux/mac/windows] {: #appveyor}
|
||||||
|
|
||||||
To build Linux, Mac, and Windows wheels on AppVeyor, create an `appveyor.yml` file in your repo.
|
To build Linux, Mac, and Windows wheels on AppVeyor, create an `appveyor.yml` file in your repo.
|
||||||
@@ -97,6 +150,37 @@ AppVeyor will store the built wheels for you - you can access them from the proj
|
|||||||
|
|
||||||
For more info on this config file, check out the [docs](https://www.appveyor.com/docs/).
|
For more info on this config file, check out the [docs](https://www.appveyor.com/docs/).
|
||||||
|
|
||||||
|
# CircleCI [linux/mac] {: #circleci}
|
||||||
|
|
||||||
|
To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo,
|
||||||
|
|
||||||
|
> .circleci/config.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
{% include "../examples/circleci-minimal.yml" %}
|
||||||
|
```
|
||||||
|
|
||||||
|
Commit this file, enable building of your repo on CircleCI, and push.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
CircleCI doesn't enable free macOS containers for open source by default, but you can ask for access. See [here](https://circleci.com/docs/2.0/oss/#overview) for more information.
|
||||||
|
|
||||||
|
CircleCI will store the built wheels for you - you can access them from the project console. Check out the CircleCI [docs](https://circleci.com/docs/2.0/configuration-reference/#section=configuration) for more info on this config file.
|
||||||
|
|
||||||
|
# Gitlab CI [linux] {: #gitlab-ci}
|
||||||
|
|
||||||
|
To build Linux wheels on Gitlab CI, create a `.gitlab-ci.yml` file in your repo,
|
||||||
|
|
||||||
|
> .gitlab-ci.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
{% include "../examples/gitlab-minimal.yml" %}
|
||||||
|
```
|
||||||
|
|
||||||
|
Commit this file, and push to Gitlab. The pipeline should start automatically.
|
||||||
|
|
||||||
|
Gitlab will store the built wheels for you - you can access them from the Pipelines view. Check out the Gitlab [docs](https://docs.gitlab.com/ee/ci/yaml/) for more info on this config file.
|
||||||
|
|
||||||
> ⚠️ Got an error? Check the [FAQ](faq.md).
|
> ⚠️ Got an error? Check the [FAQ](faq.md).
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ stack: python 3.7
|
|||||||
init:
|
init:
|
||||||
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
|
- cmd: set PATH=C:\Python37;C:\Python37\Scripts;%PATH%
|
||||||
|
|
||||||
install: python -m pip install cibuildwheel==1.9.0
|
install: python -m pip install cibuildwheel==1.10.1
|
||||||
|
|
||||||
build_script: python -m cibuildwheel --output-dir wheelhouse
|
build_script: python -m cibuildwheel --output-dir wheelhouse
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ jobs:
|
|||||||
- bash: |
|
- bash: |
|
||||||
set -o errexit
|
set -o errexit
|
||||||
python3 -m pip install --upgrade pip
|
python3 -m pip install --upgrade pip
|
||||||
pip3 install cibuildwheel==1.9.0
|
pip3 install cibuildwheel==1.10.1
|
||||||
displayName: Install dependencies
|
displayName: Install dependencies
|
||||||
- bash: cibuildwheel --output-dir wheelhouse .
|
- bash: cibuildwheel --output-dir wheelhouse .
|
||||||
displayName: Build wheels
|
displayName: Build wheels
|
||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- bash: |
|
- bash: |
|
||||||
set -o errexit
|
set -o errexit
|
||||||
python3 -m pip install --upgrade pip
|
python3 -m pip install --upgrade pip
|
||||||
python3 -m pip install cibuildwheel==1.9.0
|
python3 -m pip install cibuildwheel==1.10.1
|
||||||
displayName: Install dependencies
|
displayName: Install dependencies
|
||||||
- bash: cibuildwheel --output-dir wheelhouse .
|
- bash: cibuildwheel --output-dir wheelhouse .
|
||||||
displayName: Build wheels
|
displayName: Build wheels
|
||||||
@@ -31,12 +31,10 @@ jobs:
|
|||||||
pool: {vmImage: 'vs2017-win2016'}
|
pool: {vmImage: 'vs2017-win2016'}
|
||||||
steps:
|
steps:
|
||||||
- task: UsePythonVersion@0
|
- task: UsePythonVersion@0
|
||||||
- script: choco install vcpython27 -f -y
|
|
||||||
displayName: Install Visual C++ for Python 2.7
|
|
||||||
- bash: |
|
- bash: |
|
||||||
set -o errexit
|
set -o errexit
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install cibuildwheel==1.9.0
|
pip install cibuildwheel==1.10.1
|
||||||
displayName: Install dependencies
|
displayName: Install dependencies
|
||||||
- bash: cibuildwheel --output-dir wheelhouse .
|
- bash: cibuildwheel --output-dir wheelhouse .
|
||||||
displayName: Build wheels
|
displayName: Build wheels
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Build the Linux wheels.
|
name: Build the Linux wheels.
|
||||||
command: |
|
command: |
|
||||||
pip3 install --user cibuildwheel==1.9.0
|
pip3 install --user cibuildwheel==1.10.1
|
||||||
cibuildwheel --output-dir wheelhouse
|
cibuildwheel --output-dir wheelhouse
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: wheelhouse/
|
path: wheelhouse/
|
||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
- run:
|
- run:
|
||||||
name: Build the OS X wheels.
|
name: Build the OS X wheels.
|
||||||
command: |
|
command: |
|
||||||
pip3 install cibuildwheel==1.9.0
|
pip3 install cibuildwheel==1.10.1
|
||||||
cibuildwheel --output-dir wheelhouse
|
cibuildwheel --output-dir wheelhouse
|
||||||
- store_artifacts:
|
- store_artifacts:
|
||||||
path: wheelhouse/
|
path: wheelhouse/
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
uses: joerick/cibuildwheel@v1.9.0
|
uses: joerick/cibuildwheel@v1.10.1
|
||||||
env:
|
env:
|
||||||
CIBW_ARCHS_MACOS: x86_64 universal2
|
CIBW_ARCHS_MACOS: x86_64 universal2
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: '3.8'
|
python-version: '3.8'
|
||||||
|
|
||||||
- name: Install Visual C++ for Python 2.7
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: choco install vcpython27 -f -y
|
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
uses: joerick/cibuildwheel@v1.9.0
|
uses: joerick/cibuildwheel@v1.10.1
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v2
|
- uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -13,12 +13,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install Visual C++ for Python 2.7
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: choco install vcpython27 -f -y
|
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
uses: joerick/cibuildwheel@v1.9.0
|
uses: joerick/cibuildwheel@v1.10.1
|
||||||
# to supply options, put them in 'env', like:
|
# to supply options, put them in 'env', like:
|
||||||
# env:
|
# env:
|
||||||
# CIBW_SOME_OPTION: value
|
# CIBW_SOME_OPTION: value
|
||||||
|
|||||||
@@ -18,10 +18,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
python-version: '3.7'
|
python-version: '3.7'
|
||||||
|
|
||||||
- name: Install Visual C++ for Python 2.7
|
|
||||||
if: runner.os == 'Windows'
|
|
||||||
run: choco install vcpython27 -f -y
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
if: runner.os == 'Linux'
|
if: runner.os == 'Linux'
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-qemu-action@v1
|
||||||
@@ -29,7 +25,7 @@ jobs:
|
|||||||
platforms: all
|
platforms: all
|
||||||
|
|
||||||
- name: Build wheels
|
- name: Build wheels
|
||||||
uses: joerick/cibuildwheel@v1.9.0
|
uses: joerick/cibuildwheel@v1.10.1
|
||||||
env:
|
env:
|
||||||
# configure cibuildwheel to build native archs ('auto'), and some
|
# configure cibuildwheel to build native archs ('auto'), and some
|
||||||
# emulated ones
|
# emulated ones
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ linux:
|
|||||||
DOCKER_TLS_CERTDIR: ""
|
DOCKER_TLS_CERTDIR: ""
|
||||||
script:
|
script:
|
||||||
- curl -sSL https://get.docker.com/ | sh
|
- curl -sSL https://get.docker.com/ | sh
|
||||||
- python -m pip install cibuildwheel
|
- python -m pip install cibuildwheel==1.10.1
|
||||||
- cibuildwheel --output-dir wheelhouse
|
- cibuildwheel --output-dir wheelhouse
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ jobs:
|
|||||||
- os: windows
|
- os: windows
|
||||||
language: shell
|
language: shell
|
||||||
before_install:
|
before_install:
|
||||||
- choco install python --version 3.8.6
|
- choco upgrade python -y --version 3.8.6
|
||||||
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
||||||
# make sure it's on PATH as 'python3'
|
# make sure it's on PATH as 'python3'
|
||||||
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
|
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- python3 -m pip install cibuildwheel==1.9.0
|
- python3 -m pip install cibuildwheel==1.10.1
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# build the wheels, put them into './wheelhouse'
|
# build the wheels, put them into './wheelhouse'
|
||||||
|
|||||||
@@ -20,13 +20,13 @@ jobs:
|
|||||||
- os: windows
|
- os: windows
|
||||||
language: shell
|
language: shell
|
||||||
before_install:
|
before_install:
|
||||||
- choco install python --version 3.8.6
|
- choco upgrade python -y --version 3.8.6
|
||||||
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
- export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
||||||
# make sure it's on PATH as 'python3'
|
# make sure it's on PATH as 'python3'
|
||||||
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
|
- ln -s /c/Python38/python.exe /c/Python38/python3.exe
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- python3 -m pip install cibuildwheel==1.9.0
|
- python3 -m pip install cibuildwheel==1.10.1
|
||||||
|
|
||||||
script:
|
script:
|
||||||
# build the wheels, put them into './wheelhouse'
|
# build the wheels, put them into './wheelhouse'
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ python:
|
|||||||
before_install:
|
before_install:
|
||||||
- |
|
- |
|
||||||
if [[ "$TRAVIS_OS_NAME" = windows ]]; then
|
if [[ "$TRAVIS_OS_NAME" = windows ]]; then
|
||||||
choco install python --version 3.8.6
|
choco upgrade python -y --version 3.8.6
|
||||||
export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
export PATH="/c/Python38:/c/Python38/Scripts:$PATH"
|
||||||
# make sure it's on PATH as 'python3'
|
# make sure it's on PATH as 'python3'
|
||||||
ln -s /c/Python38/python.exe /c/Python38/python3.exe
|
ln -s /c/Python38/python.exe /c/Python38/python3.exe
|
||||||
@@ -55,7 +55,7 @@ jobs:
|
|||||||
- stage: deploy
|
- stage: deploy
|
||||||
name: Build and deploy Linux wheels
|
name: Build and deploy Linux wheels
|
||||||
services: docker
|
services: docker
|
||||||
install: python3 -m pip install cibuildwheel==1.9.0
|
install: python3 -m pip install cibuildwheel==1.10.1
|
||||||
script: python3 -m cibuildwheel --output-dir wheelhouse
|
script: python3 -m cibuildwheel --output-dir wheelhouse
|
||||||
after_success: |
|
after_success: |
|
||||||
python3 -m pip install twine
|
python3 -m pip install twine
|
||||||
@@ -65,7 +65,7 @@ jobs:
|
|||||||
name: Build and deploy macOS wheels
|
name: Build and deploy macOS wheels
|
||||||
os: osx
|
os: osx
|
||||||
language: shell
|
language: shell
|
||||||
install: python3 -m pip install cibuildwheel==1.9.0
|
install: python3 -m pip install cibuildwheel==1.10.1
|
||||||
script: python3 -m cibuildwheel --output-dir wheelhouse
|
script: python3 -m cibuildwheel --output-dir wheelhouse
|
||||||
after_success: |
|
after_success: |
|
||||||
python3 -m pip install twine
|
python3 -m pip install twine
|
||||||
@@ -75,7 +75,7 @@ jobs:
|
|||||||
name: Build and deploy Windows wheels
|
name: Build and deploy Windows wheels
|
||||||
os: windows
|
os: windows
|
||||||
language: shell
|
language: shell
|
||||||
install: python3 -m pip install cibuildwheel==1.9.0
|
install: python3 -m pip install cibuildwheel==1.10.1
|
||||||
script: python3 -m cibuildwheel --output-dir wheelhouse
|
script: python3 -m cibuildwheel --output-dir wheelhouse
|
||||||
after_success: |
|
after_success: |
|
||||||
python3 -m pip install twine
|
python3 -m pip install twine
|
||||||
|
|||||||
+6
-1
@@ -25,13 +25,18 @@ nav:
|
|||||||
- changelog.md
|
- changelog.md
|
||||||
|
|
||||||
markdown_extensions:
|
markdown_extensions:
|
||||||
- fenced_code
|
- md_in_html
|
||||||
- toc:
|
- toc:
|
||||||
permalink: True
|
permalink: True
|
||||||
- attr_list
|
- attr_list
|
||||||
- admonition
|
- admonition
|
||||||
- pymdownx.magiclink:
|
- pymdownx.magiclink:
|
||||||
repo_url_shortener: True
|
repo_url_shortener: True
|
||||||
|
- pymdownx.highlight:
|
||||||
|
# use highlightjs - it's built-in to the theme
|
||||||
|
use_pygments: False
|
||||||
|
- pymdownx.superfences
|
||||||
|
|
||||||
plugins:
|
plugins:
|
||||||
- include-markdown
|
- include-markdown
|
||||||
|
- search
|
||||||
|
|||||||
+2
-1
@@ -8,4 +8,5 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
line-length = 120
|
line-length = 120
|
||||||
target-version = ['py36']
|
target-version = ['py36', 'py37', 'py38']
|
||||||
|
skip-string-normalization = true
|
||||||
|
|||||||
@@ -1,39 +1,48 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
|
|
||||||
name = cibuildwheel
|
name = cibuildwheel
|
||||||
version = 1.9.0
|
version = 1.10.1
|
||||||
description = Build Python wheels on CI with minimal configuration.
|
description = Build Python wheels on CI with minimal configuration.
|
||||||
long_description = file: README.md
|
long_description = file: README.md
|
||||||
long_description_content_type = text/markdown
|
long_description_content_type = text/markdown
|
||||||
|
url = https://github.com/joerick/cibuildwheel
|
||||||
author = Joe Rickerby
|
author = Joe Rickerby
|
||||||
author_email = joerick@mac.com
|
author_email = joerick@mac.com
|
||||||
url = https://github.com/joerick/cibuildwheel
|
|
||||||
license = BSD
|
license = BSD
|
||||||
|
license_file = LICENSE
|
||||||
classifiers =
|
classifiers =
|
||||||
|
Development Status :: 5 - Production/Stable
|
||||||
Intended Audience :: Developers
|
Intended Audience :: Developers
|
||||||
|
License :: OSI Approved :: BSD License
|
||||||
Natural Language :: English
|
Natural Language :: English
|
||||||
Programming Language :: Python :: 3
|
Programming Language :: Python :: 3
|
||||||
Development Status :: 5 - Production/Stable
|
Programming Language :: Python :: 3 :: Only
|
||||||
License :: OSI Approved :: BSD License
|
Programming Language :: Python :: 3.6
|
||||||
|
Programming Language :: Python :: 3.7
|
||||||
|
Programming Language :: Python :: 3.8
|
||||||
|
Programming Language :: Python :: 3.9
|
||||||
Programming Language :: Python :: Implementation :: CPython
|
Programming Language :: Python :: Implementation :: CPython
|
||||||
Topic :: Software Development :: Build Tools
|
Topic :: Software Development :: Build Tools
|
||||||
|
keywords = ci,wheel,packaging,pypi,travis,appveyor,macos,linux,windows
|
||||||
project_urls =
|
project_urls =
|
||||||
Changelog=https://github.com/joerick/cibuildwheel#changelog
|
Changelog=https://github.com/joerick/cibuildwheel#changelog
|
||||||
Documentation=https://cibuildwheel.readthedocs.io/
|
Documentation=https://cibuildwheel.readthedocs.io/
|
||||||
keywords = ci,wheel,packaging,pypi,travis,appveyor,macos,linux,windows
|
|
||||||
|
|
||||||
[options]
|
[options]
|
||||||
packages = find:
|
packages = find:
|
||||||
zip_safe = False
|
|
||||||
include_package_data = True
|
|
||||||
python_requires = >=3.6
|
|
||||||
install_requires =
|
install_requires =
|
||||||
bashlex!=0.13
|
bashlex!=0.13
|
||||||
toml
|
|
||||||
certifi
|
|
||||||
bracex
|
bracex
|
||||||
|
certifi
|
||||||
packaging
|
packaging
|
||||||
typing_extensions; python_version < '3.8'
|
toml
|
||||||
|
typing_extensions;python_version < '3.8'
|
||||||
|
python_requires = >=3.6
|
||||||
|
include_package_data = True
|
||||||
|
zip_safe = False
|
||||||
|
|
||||||
|
[options.entry_points]
|
||||||
|
console_scripts =
|
||||||
|
cibuildwheel = cibuildwheel.__main__:main
|
||||||
|
|
||||||
[options.package_data]
|
[options.package_data]
|
||||||
cibuildwheel = resources/*
|
cibuildwheel = resources/*
|
||||||
@@ -42,28 +51,26 @@ cibuildwheel = resources/*
|
|||||||
include =
|
include =
|
||||||
cibuildwheel
|
cibuildwheel
|
||||||
|
|
||||||
[options.entry_points]
|
|
||||||
console_scripts =
|
|
||||||
cibuildwheel = cibuildwheel.__main__:main
|
|
||||||
|
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = E501,W503,E741,E226,B950
|
ignore = E501,W503,E741,E226,B950
|
||||||
select = C,E,F,W,B,B9
|
select = C,E,F,W,B,B9
|
||||||
application-import-names = cibuildwheel
|
application-import-names = cibuildwheel
|
||||||
exclude =
|
exclude =
|
||||||
cibuildwheel/resources/,
|
cibuildwheel/resources/,
|
||||||
dist/,
|
dist/,
|
||||||
build/,
|
build/,
|
||||||
.git/,
|
.git/,
|
||||||
env/,
|
env/,
|
||||||
env2/,
|
env2/,
|
||||||
env??/,
|
env??/,
|
||||||
.venv/,
|
.venv/,
|
||||||
site/
|
site/
|
||||||
|
|
||||||
[tool:pytest]
|
[tool:pytest]
|
||||||
junit_family=xunit2
|
junit_family = xunit2
|
||||||
|
testpaths =
|
||||||
|
test
|
||||||
|
unit_test
|
||||||
|
|
||||||
[mypy]
|
[mypy]
|
||||||
python_version = 3.7
|
python_version = 3.7
|
||||||
@@ -110,5 +117,5 @@ ignore_missing_imports = True
|
|||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
|
|
||||||
[tool:isort]
|
[tool:isort]
|
||||||
profile=black
|
profile = black
|
||||||
multi_line_output=3
|
multi_line_output = 3
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from setuptools import setup
|
|||||||
|
|
||||||
extras = {
|
extras = {
|
||||||
"docs": [
|
"docs": [
|
||||||
"mkdocs-include-markdown-plugin==2.1.1",
|
"mkdocs-include-markdown-plugin==2.8.0",
|
||||||
"mkdocs==1.0.4",
|
"mkdocs==1.0.4",
|
||||||
"pymdown-extensions",
|
"pymdown-extensions",
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ def test(tmp_path):
|
|||||||
# write python version information to a temporary file, this is
|
# write python version information to a temporary file, this is
|
||||||
# checked in setup.py
|
# checked in setup.py
|
||||||
'CIBW_BEFORE_ALL': before_all_command,
|
'CIBW_BEFORE_ALL': before_all_command,
|
||||||
'CIBW_BEFORE_ALL_LINUX': before_all_command + ''' && python -c "import sys; assert sys.version_info >= (3, 6)"''',
|
'CIBW_BEFORE_ALL_LINUX': f'{before_all_command} && python -c "import sys; assert sys.version_info >= (3, 6)"',
|
||||||
'CIBW_ENVIRONMENT': "TEST_VAL='123'"
|
'CIBW_ENVIRONMENT': "TEST_VAL='123'"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from . import test_projects, utils
|
|||||||
|
|
||||||
project_with_before_build_asserts = test_projects.new_c_project(
|
project_with_before_build_asserts = test_projects.new_c_project(
|
||||||
setup_py_add=textwrap.dedent(r'''
|
setup_py_add=textwrap.dedent(r'''
|
||||||
import sys, os
|
import os
|
||||||
|
|
||||||
# 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.
|
||||||
|
|||||||
@@ -40,11 +40,10 @@ VERSION_REGEX = r'([\w-]+)==([^\s]+)'
|
|||||||
def get_versions_from_constraint_file(constraint_file):
|
def get_versions_from_constraint_file(constraint_file):
|
||||||
constraint_file_text = constraint_file.read_text(encoding='utf8')
|
constraint_file_text = constraint_file.read_text(encoding='utf8')
|
||||||
|
|
||||||
versions = {}
|
return {
|
||||||
for package, version in re.findall(VERSION_REGEX, constraint_file_text):
|
package: version
|
||||||
versions[package] = version
|
for package, version in re.findall(VERSION_REGEX, constraint_file_text)
|
||||||
|
}
|
||||||
return versions
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('python_version', ['2.7', '3.5', '3.6', '3.8'])
|
@pytest.mark.parametrize('python_version', ['2.7', '3.5', '3.6', '3.8'])
|
||||||
@@ -52,8 +51,8 @@ def test_pinned_versions(tmp_path, python_version):
|
|||||||
if utils.platform == 'linux':
|
if utils.platform == 'linux':
|
||||||
pytest.skip('linux doesn\'t pin individual tool versions, it pins manylinux images instead')
|
pytest.skip('linux doesn\'t pin individual tool versions, it pins manylinux images instead')
|
||||||
|
|
||||||
if utils.IS_WINDOWS_RUNNING_ON_TRAVIS and python_version == '2.7':
|
if utils.platform == 'windows' and python_version == '2.7':
|
||||||
pytest.skip('Windows + Travis CI requires a workaround')
|
pytest.skip('Windows requires a workaround')
|
||||||
|
|
||||||
is_running_on_macos_11_or_later = (
|
is_running_on_macos_11_or_later = (
|
||||||
utils.platform == 'macos' and utils.get_macos_version() >= (10, 16)
|
utils.platform == 'macos' and utils.get_macos_version() >= (10, 16)
|
||||||
@@ -91,7 +90,7 @@ def test_pinned_versions(tmp_path, python_version):
|
|||||||
build_environment[env_name] = constraint_versions[package]
|
build_environment[env_name] = constraint_versions[package]
|
||||||
|
|
||||||
cibw_environment_option = ' '.join(
|
cibw_environment_option = ' '.join(
|
||||||
[f'{k}={v}' for k, v in build_environment.items()]
|
f'{k}={v}' for k, v in build_environment.items()
|
||||||
)
|
)
|
||||||
|
|
||||||
# build and test the wheels
|
# build and test the wheels
|
||||||
@@ -124,7 +123,7 @@ def test_dependency_constraints_file(tmp_path, python_version):
|
|||||||
if utils.platform == 'linux':
|
if utils.platform == 'linux':
|
||||||
pytest.skip('linux doesn\'t pin individual tool versions, it pins manylinux images instead')
|
pytest.skip('linux doesn\'t pin individual tool versions, it pins manylinux images instead')
|
||||||
|
|
||||||
if utils.IS_WINDOWS_RUNNING_ON_TRAVIS and python_version == '2.7':
|
if utils.platform == 'windows' and python_version == '2.7':
|
||||||
pytest.skip('Windows + Travis CI requires a workaround')
|
pytest.skip('Windows + Travis CI requires a workaround')
|
||||||
|
|
||||||
project_dir = tmp_path / 'project'
|
project_dir = tmp_path / 'project'
|
||||||
@@ -154,7 +153,7 @@ def test_dependency_constraints_file(tmp_path, python_version):
|
|||||||
build_environment[env_name] = version
|
build_environment[env_name] = version
|
||||||
|
|
||||||
cibw_environment_option = ' '.join(
|
cibw_environment_option = ' '.join(
|
||||||
[f'{k}={v}' for k, v in build_environment.items()]
|
f'{k}={v}' for k, v in build_environment.items()
|
||||||
)
|
)
|
||||||
|
|
||||||
# build and test the wheels
|
# build and test the wheels
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from . import test_projects, utils
|
|||||||
|
|
||||||
dockcross_only_project = test_projects.new_c_project(
|
dockcross_only_project = test_projects.new_c_project(
|
||||||
setup_py_add=textwrap.dedent(r'''
|
setup_py_add=textwrap.dedent(r'''
|
||||||
import os, sys
|
import os
|
||||||
|
|
||||||
# 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
|
||||||
@@ -31,10 +31,10 @@ def test(tmp_path):
|
|||||||
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
|
actual_wheels = utils.cibuildwheel_run(project_dir, add_env={
|
||||||
'CIBW_MANYLINUX_X86_64_IMAGE': 'dockcross/manylinux2010-x64',
|
'CIBW_MANYLINUX_X86_64_IMAGE': 'dockcross/manylinux2010-x64',
|
||||||
'CIBW_MANYLINUX_I686_IMAGE': 'dockcross/manylinux2010-x86',
|
'CIBW_MANYLINUX_I686_IMAGE': 'dockcross/manylinux2010-x86',
|
||||||
'CIBW_SKIP': 'pp* cp39-*',
|
'CIBW_SKIP': 'pp* cp27-* cp39-*',
|
||||||
})
|
})
|
||||||
|
|
||||||
# also check that we got the right wheels built
|
# also check that we got the right wheels built
|
||||||
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
|
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0')
|
||||||
if '-pp' not in w and '-cp39-' not in w]
|
if '-pp' not in w and '-cp39-' not in w and '-cp27-' not in w]
|
||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ ALL_MACOS_WHEELS = (
|
|||||||
|
|
||||||
|
|
||||||
def get_xcode_version() -> Tuple[int, int]:
|
def get_xcode_version() -> Tuple[int, int]:
|
||||||
output = subprocess.check_output(
|
output = subprocess.run(
|
||||||
['xcodebuild', '-version'],
|
['xcodebuild', '-version'],
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
)
|
check=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
).stdout
|
||||||
lines = output.splitlines()
|
lines = output.splitlines()
|
||||||
_, version_str = lines[0].split()
|
_, version_str = lines[0].split()
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ from . import test_projects, utils
|
|||||||
project_with_manylinux_symbols = test_projects.new_c_project(
|
project_with_manylinux_symbols = test_projects.new_c_project(
|
||||||
spam_c_top_level_add=textwrap.dedent(r'''
|
spam_c_top_level_add=textwrap.dedent(r'''
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#if !defined(__GLIBC_PREREQ)
|
#if !defined(__GLIBC_PREREQ)
|
||||||
#error "Must run on a glibc linux environment"
|
#error "Must run on a glibc linux environment"
|
||||||
@@ -19,19 +22,21 @@ project_with_manylinux_symbols = test_projects.new_c_project(
|
|||||||
#endif
|
#endif
|
||||||
'''),
|
'''),
|
||||||
spam_c_function_add=textwrap.dedent(r'''
|
spam_c_function_add=textwrap.dedent(r'''
|
||||||
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 17) /* manylinux2014 is glibc 2.17 */
|
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 24)
|
||||||
// secure_getenv is only available in manylinux2014, ensuring
|
// nextupf is only available in manylinux_2_24+
|
||||||
// that only a manylinux2014 wheel is produced
|
sts = (int)nextupf(0.0F);
|
||||||
secure_getenv("NON_EXISTING_ENV_VARIABLE");
|
#elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 17) /* manylinux2014 is glibc 2.17 */
|
||||||
|
// secure_getenv is only available in manylinux2014+
|
||||||
|
sts = (int)(intptr_t)secure_getenv("NON_EXISTING_ENV_VARIABLE");
|
||||||
#elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10) /* manylinux2010 is glibc 2.12 */
|
#elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10) /* manylinux2010 is glibc 2.12 */
|
||||||
// malloc_info is only available on manylinux2010+
|
// malloc_info is only available on manylinux2010+
|
||||||
malloc_info(0, stdout);
|
sts = malloc_info(0, stdout);
|
||||||
#endif
|
#endif
|
||||||
'''),
|
'''),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('manylinux_image', ['manylinux1', 'manylinux2010', 'manylinux2014'])
|
@pytest.mark.parametrize('manylinux_image', ['manylinux1', 'manylinux2010', 'manylinux2014', 'manylinux_2_24'])
|
||||||
def test(manylinux_image, tmp_path):
|
def test(manylinux_image, tmp_path):
|
||||||
if utils.platform != 'linux':
|
if utils.platform != 'linux':
|
||||||
pytest.skip('the docker test is only relevant to the linux build')
|
pytest.skip('the docker test is only relevant to the linux build')
|
||||||
@@ -46,7 +51,7 @@ def test(manylinux_image, tmp_path):
|
|||||||
# CFLAGS environment variable is necessary to fail on 'malloc_info' (on manylinux1) during compilation/linking,
|
# CFLAGS environment variable is necessary to fail on 'malloc_info' (on manylinux1) during compilation/linking,
|
||||||
# rather than when dynamically loading the Python
|
# rather than when dynamically loading the Python
|
||||||
add_env = {
|
add_env = {
|
||||||
'CIBW_ENVIRONMENT': 'CFLAGS="$CFLAGS -Werror=implicit-function-declaration"',
|
'CIBW_ENVIRONMENT': 'CFLAGS="$CFLAGS -O0 -Werror=implicit-function-declaration"',
|
||||||
'CIBW_MANYLINUX_X86_64_IMAGE': manylinux_image,
|
'CIBW_MANYLINUX_X86_64_IMAGE': manylinux_image,
|
||||||
'CIBW_MANYLINUX_I686_IMAGE': manylinux_image,
|
'CIBW_MANYLINUX_I686_IMAGE': manylinux_image,
|
||||||
'CIBW_MANYLINUX_PYPY_X86_64_IMAGE': manylinux_image,
|
'CIBW_MANYLINUX_PYPY_X86_64_IMAGE': manylinux_image,
|
||||||
@@ -57,14 +62,14 @@ def test(manylinux_image, tmp_path):
|
|||||||
if manylinux_image == 'manylinux1':
|
if manylinux_image == 'manylinux1':
|
||||||
# We don't have a manylinux1 image for PyPy
|
# We don't have a manylinux1 image for PyPy
|
||||||
add_env['CIBW_SKIP'] = 'pp*'
|
add_env['CIBW_SKIP'] = 'pp*'
|
||||||
elif manylinux_image == 'manylinux2014':
|
elif manylinux_image in {'manylinux2014', 'manylinux_2_24'}:
|
||||||
# We don't have a manylinux2014 image for PyPy (yet?)
|
# We don't have a manylinux2014 / 'manylinux_2_24' image for PyPy (yet?)
|
||||||
add_env['CIBW_SKIP'] = 'cp27* pp*' # Python 2.7 not available on manylinux2014
|
add_env['CIBW_SKIP'] = 'cp27* pp*' # Python 2.7 not available on manylinux2014 / 'manylinux_2_24'
|
||||||
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
|
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
|
||||||
|
|
||||||
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0', manylinux_versions=[manylinux_image])]
|
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0', manylinux_versions=[manylinux_image])]
|
||||||
if manylinux_image == 'manylinux2014':
|
if manylinux_image in {'manylinux2014', 'manylinux_2_24'}:
|
||||||
expected_wheels = [w for w in expected_wheels if '-cp27' not in w]
|
expected_wheels = [w for w in expected_wheels if '-cp27' not in w]
|
||||||
if manylinux_image in ['manylinux1', 'manylinux2014']:
|
if manylinux_image in {'manylinux1', 'manylinux2014', 'manylinux_2_24'}:
|
||||||
expected_wheels = [w for w in expected_wheels if '-pp' not in w]
|
expected_wheels = [w for w in expected_wheels if '-pp' not in w]
|
||||||
assert set(actual_wheels) == set(expected_wheels)
|
assert set(actual_wheels) == set(expected_wheels)
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ basic_project = test_projects.new_c_project(
|
|||||||
setup_py_add=textwrap.dedent(
|
setup_py_add=textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
# Will fail if PEP 518 does work
|
# Will fail if PEP 518 does work
|
||||||
import sys
|
|
||||||
import requests
|
import requests
|
||||||
if sys.version_info < (3, 6, 0):
|
if sys.version_info < (3, 6, 0):
|
||||||
assert requests.__version__ == "2.22.0", "Requests found but wrong version ({0})".format(requests.__version__)
|
assert requests.__version__ == "2.22.0", "Requests found but wrong version ({0})".format(requests.__version__)
|
||||||
|
|||||||
@@ -34,11 +34,11 @@ def main():
|
|||||||
|
|
||||||
if options.open:
|
if options.open:
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
subprocess.check_call(['open', '--', project_dir])
|
subprocess.run(['open', '--', project_dir], check=True)
|
||||||
elif sys.platform == 'linux2':
|
elif sys.platform == 'linux2':
|
||||||
subprocess.check_call(['xdg-open', '--', project_dir])
|
subprocess.run(['xdg-open', '--', project_dir], check=True)
|
||||||
elif sys.platform == 'win32':
|
elif sys.platform == 'win32':
|
||||||
subprocess.check_call(['explorer', project_dir])
|
subprocess.run(['explorer', project_dir], check=True)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
+10
-1
@@ -60,12 +60,21 @@ MOD_INIT(spam)
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
SETUP_PY_TEMPLATE = r'''
|
SETUP_PY_TEMPLATE = r'''
|
||||||
|
import sys
|
||||||
from setuptools import setup, Extension
|
from setuptools import setup, Extension
|
||||||
|
|
||||||
{{ setup_py_add }}
|
{{ setup_py_add }}
|
||||||
|
|
||||||
|
libraries = []
|
||||||
|
if sys.platform.startswith('linux'):
|
||||||
|
libraries.extend(['m', 'c'])
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
ext_modules=[Extension('spam', sources=['spam.c'])],
|
ext_modules=[Extension(
|
||||||
|
'spam',
|
||||||
|
sources=['spam.c'],
|
||||||
|
libraries=libraries,
|
||||||
|
)],
|
||||||
{{ setup_py_setup_args_add | indent(4) }}
|
{{ setup_py_setup_args_add | indent(4) }}
|
||||||
)
|
)
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from . import test_projects, utils
|
|||||||
project_with_ssl_tests = test_projects.new_c_project(
|
project_with_ssl_tests = test_projects.new_c_project(
|
||||||
setup_py_add=textwrap.dedent(r'''
|
setup_py_add=textwrap.dedent(r'''
|
||||||
import ssl
|
import ssl
|
||||||
import sys
|
|
||||||
|
|
||||||
if sys.version_info[0] == 2:
|
if sys.version_info[0] == 2:
|
||||||
from urllib2 import urlopen
|
from urllib2 import urlopen
|
||||||
|
|||||||
+19
-19
@@ -12,7 +12,18 @@ import sys
|
|||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
|
|
||||||
IS_WINDOWS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows'
|
platform: str
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
|
||||||
# Python 2 does not have a tempfile.TemporaryDirectory context manager
|
# Python 2 does not have a tempfile.TemporaryDirectory context manager
|
||||||
@@ -31,11 +42,13 @@ def cibuildwheel_get_build_identifiers(project_path, env=None):
|
|||||||
Returns the list of build identifiers that cibuildwheel will try to build
|
Returns the list of build identifiers that cibuildwheel will try to build
|
||||||
for the current platform.
|
for the current platform.
|
||||||
'''
|
'''
|
||||||
cmd_output = subprocess.check_output(
|
cmd_output = subprocess.run(
|
||||||
[sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers', str(project_path)],
|
[sys.executable, '-m', 'cibuildwheel', '--print-build-identifiers', str(project_path)],
|
||||||
universal_newlines=True,
|
universal_newlines=True,
|
||||||
env=env,
|
env=env,
|
||||||
)
|
check=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
).stdout
|
||||||
|
|
||||||
return cmd_output.strip().split('\n')
|
return cmd_output.strip().split('\n')
|
||||||
|
|
||||||
@@ -64,10 +77,11 @@ def cibuildwheel_run(project_path, package_dir='.', env=None, add_env=None, outp
|
|||||||
env.update(add_env)
|
env.update(add_env)
|
||||||
|
|
||||||
with TemporaryDirectoryIfNone(output_dir) as _output_dir:
|
with TemporaryDirectoryIfNone(output_dir) as _output_dir:
|
||||||
subprocess.check_call(
|
subprocess.run(
|
||||||
[sys.executable, '-m', 'cibuildwheel', '--output-dir', str(_output_dir), str(package_dir)],
|
[sys.executable, '-m', 'cibuildwheel', '--output-dir', str(_output_dir), str(package_dir)],
|
||||||
env=env,
|
env=env,
|
||||||
cwd=project_path,
|
cwd=project_path,
|
||||||
|
check=True,
|
||||||
)
|
)
|
||||||
wheels = os.listdir(_output_dir)
|
wheels = os.listdir(_output_dir)
|
||||||
return wheels
|
return wheels
|
||||||
@@ -88,7 +102,7 @@ def _get_arm64_macosx_deployment_target(macosx_deployment_target: str) -> str:
|
|||||||
|
|
||||||
def expected_wheels(package_name, package_version, manylinux_versions=None,
|
def expected_wheels(package_name, package_version, manylinux_versions=None,
|
||||||
macosx_deployment_target='10.9', machine_arch=None, *,
|
macosx_deployment_target='10.9', machine_arch=None, *,
|
||||||
exclude_27=IS_WINDOWS_RUNNING_ON_TRAVIS):
|
exclude_27=platform == 'windows'):
|
||||||
'''
|
'''
|
||||||
Returns a list of expected wheels from a run of cibuildwheel.
|
Returns a list of expected wheels from a run of cibuildwheel.
|
||||||
'''
|
'''
|
||||||
@@ -184,17 +198,3 @@ def get_macos_version():
|
|||||||
'''
|
'''
|
||||||
version_str, _, _ = pm.mac_ver()
|
version_str, _, _ = pm.mac_ver()
|
||||||
return tuple(map(int, version_str.split(".")[:2]))
|
return tuple(map(int, version_str.split(".")[:2]))
|
||||||
|
|
||||||
|
|
||||||
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')
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ def test_binary_output():
|
|||||||
|
|
||||||
data = bytes(output, encoding='utf8', errors='surrogateescape')
|
data = bytes(output, encoding='utf8', errors='surrogateescape')
|
||||||
|
|
||||||
for i in range(0, 512):
|
for i in range(512):
|
||||||
assert data[i] == i % 256
|
assert data[i] == i % 256
|
||||||
|
|
||||||
# check that environment variables can carry binary data, except null characters
|
# check that environment variables can carry binary data, except null characters
|
||||||
|
|||||||
@@ -71,11 +71,13 @@ def test_empty_selector(platform, intercepted_build_args, monkeypatch):
|
|||||||
('x86_64', 'manylinux1', 'quay.io/pypa/manylinux1_x86_64:*'),
|
('x86_64', 'manylinux1', 'quay.io/pypa/manylinux1_x86_64:*'),
|
||||||
('x86_64', 'manylinux2010', 'quay.io/pypa/manylinux2010_x86_64:*'),
|
('x86_64', 'manylinux2010', 'quay.io/pypa/manylinux2010_x86_64:*'),
|
||||||
('x86_64', 'manylinux2014', 'quay.io/pypa/manylinux2014_x86_64:*'),
|
('x86_64', 'manylinux2014', 'quay.io/pypa/manylinux2014_x86_64:*'),
|
||||||
|
('x86_64', 'manylinux_2_24', 'quay.io/pypa/manylinux_2_24_x86_64:*'),
|
||||||
('x86_64', 'custom_image', 'custom_image'),
|
('x86_64', 'custom_image', 'custom_image'),
|
||||||
('i686', None, 'quay.io/pypa/manylinux2010_i686:*'),
|
('i686', None, 'quay.io/pypa/manylinux2010_i686:*'),
|
||||||
('i686', 'manylinux1', 'quay.io/pypa/manylinux1_i686:*'),
|
('i686', 'manylinux1', 'quay.io/pypa/manylinux1_i686:*'),
|
||||||
('i686', 'manylinux2010', 'quay.io/pypa/manylinux2010_i686:*'),
|
('i686', 'manylinux2010', 'quay.io/pypa/manylinux2010_i686:*'),
|
||||||
('i686', 'manylinux2014', 'quay.io/pypa/manylinux2014_i686:*'),
|
('i686', 'manylinux2014', 'quay.io/pypa/manylinux2014_i686:*'),
|
||||||
|
('i686', 'manylinux_2_24', 'quay.io/pypa/manylinux_2_24_i686:*'),
|
||||||
('i686', 'custom_image', 'custom_image'),
|
('i686', 'custom_image', 'custom_image'),
|
||||||
('pypy_x86_64', None, 'pypywheels/manylinux2010-pypy_x86_64:*'),
|
('pypy_x86_64', None, 'pypywheels/manylinux2010-pypy_x86_64:*'),
|
||||||
('pypy_x86_64', 'manylinux1', 'manylinux1'), # Does not exist
|
('pypy_x86_64', 'manylinux1', 'manylinux1'), # Does not exist
|
||||||
@@ -132,7 +134,7 @@ def test_repair_command(repair_command, platform_specific, platform, intercepted
|
|||||||
])
|
])
|
||||||
@pytest.mark.parametrize('platform_specific', [False, True])
|
@pytest.mark.parametrize('platform_specific', [False, True])
|
||||||
def test_environment(environment, platform_specific, platform, intercepted_build_args, monkeypatch):
|
def test_environment(environment, platform_specific, platform, intercepted_build_args, monkeypatch):
|
||||||
env_string = ' '.join([f'{k}={v}' for k, v in environment.items()])
|
env_string = ' '.join(f'{k}={v}' for k, v in environment.items())
|
||||||
if platform_specific:
|
if platform_specific:
|
||||||
monkeypatch.setenv('CIBW_ENVIRONMENT_' + platform.upper(), env_string)
|
monkeypatch.setenv('CIBW_ENVIRONMENT_' + platform.upper(), env_string)
|
||||||
monkeypatch.setenv('CIBW_ENVIRONMENT', 'overwritten')
|
monkeypatch.setenv('CIBW_ENVIRONMENT', 'overwritten')
|
||||||
|
|||||||
@@ -123,12 +123,10 @@ def test_archs_platform_native(platform, intercepted_build_args, monkeypatch):
|
|||||||
main()
|
main()
|
||||||
build_options = intercepted_build_args.args[0]
|
build_options = intercepted_build_args.args[0]
|
||||||
|
|
||||||
if platform == 'linux':
|
if platform in {'linux', 'macos'}:
|
||||||
assert build_options.architectures == {Architecture.x86_64}
|
assert build_options.architectures == {Architecture.x86_64}
|
||||||
elif platform == 'windows':
|
elif platform == 'windows':
|
||||||
assert build_options.architectures == {Architecture.AMD64}
|
assert build_options.architectures == {Architecture.AMD64}
|
||||||
elif platform == 'macos':
|
|
||||||
assert build_options.architectures == {Architecture.x86_64}
|
|
||||||
|
|
||||||
|
|
||||||
def test_archs_platform_auto64(platform, intercepted_build_args, monkeypatch):
|
def test_archs_platform_auto64(platform, intercepted_build_args, monkeypatch):
|
||||||
@@ -137,12 +135,10 @@ def test_archs_platform_auto64(platform, intercepted_build_args, monkeypatch):
|
|||||||
main()
|
main()
|
||||||
build_options = intercepted_build_args.args[0]
|
build_options = intercepted_build_args.args[0]
|
||||||
|
|
||||||
if platform == 'linux':
|
if platform in {'linux', 'macos'}:
|
||||||
assert build_options.architectures == {Architecture.x86_64}
|
assert build_options.architectures == {Architecture.x86_64}
|
||||||
elif platform == 'windows':
|
elif platform == 'windows':
|
||||||
assert build_options.architectures == {Architecture.AMD64}
|
assert build_options.architectures == {Architecture.AMD64}
|
||||||
elif platform == 'macos':
|
|
||||||
assert build_options.architectures == {Architecture.x86_64}
|
|
||||||
|
|
||||||
|
|
||||||
def test_archs_platform_auto32(platform, intercepted_build_args, monkeypatch):
|
def test_archs_platform_auto32(platform, intercepted_build_args, monkeypatch):
|
||||||
|
|||||||
Reference in New Issue
Block a user