Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8124b14491 | ||
|
|
b3b15f8404 | ||
|
|
9a96910919 | ||
|
|
fce00dd77e | ||
|
|
6da52a544b | ||
|
|
c8037fb237 | ||
|
|
95a81f2216 | ||
|
|
56c9c9864d | ||
|
|
0789842ef0 | ||
|
|
5c47700d31 | ||
|
|
5ef7eeba4d | ||
|
|
bb554acb28 | ||
|
|
ea3c52631f | ||
|
|
b18281867b | ||
|
|
4a0d05df49 | ||
|
|
c1cd99ee4c | ||
|
|
e68400b403 | ||
|
|
2f1f34f693 | ||
|
|
3ef401b19e | ||
|
|
8800ea514b | ||
|
|
f62b9755e1 | ||
|
|
033ba29ec6 | ||
|
|
0627b38402 | ||
|
|
189dc13714 | ||
|
|
793026f3ed | ||
|
|
08b4895b9c | ||
|
|
7c635b4550 | ||
|
|
33433f0b21 | ||
|
|
e3981db2a6 | ||
|
|
1ec652dff8 | ||
|
|
d2394e9a57 | ||
|
|
0b21df216e | ||
|
|
e5b9d1f586 | ||
|
|
9b31b5e6c9 | ||
|
|
1a910257bb | ||
|
|
4f542ca3d4 | ||
|
|
57a2259a00 | ||
|
|
d186b0bbb7 | ||
|
|
57cdb8711c | ||
|
|
7448ca3cf1 | ||
|
|
d93547d8be | ||
|
|
a863e21b14 | ||
|
|
b4c0150d43 | ||
|
|
c8019dac1d | ||
|
|
e6fa70a910 | ||
|
|
b19e8b76f3 | ||
|
|
23ab1f780e | ||
|
|
eedcd62753 | ||
|
|
3a4d611da1 | ||
|
|
8877990ec6 | ||
|
|
0cc41fabba | ||
|
|
0156a9a870 | ||
|
|
460a4d9656 | ||
|
|
8d9d970874 | ||
|
|
c563bca054 | ||
|
|
b47a5c018f | ||
|
|
94e33cd7e3 | ||
|
|
c9c54602ed | ||
|
|
b74333a940 | ||
|
|
4655311a7a | ||
|
|
71503b7143 | ||
|
|
5099d60584 | ||
|
|
2ebde4c078 | ||
|
|
e33b6bed77 | ||
|
|
4d61b08fa3 | ||
|
|
5e009e53c9 | ||
|
|
783a4deec6 | ||
|
|
529e22bfe0 | ||
|
|
418cb9c39d | ||
|
|
99469087ed | ||
|
|
3b847ab0aa |
+11
-25
@@ -5,42 +5,28 @@ matrix:
|
||||
# Linux Python 2
|
||||
- sudo: required
|
||||
language: python
|
||||
services:
|
||||
- docker
|
||||
env:
|
||||
- "PYTHON=python2"
|
||||
python: 2.7
|
||||
services: docker
|
||||
env: PYTHON=python
|
||||
|
||||
# Linux Python 3
|
||||
- sudo: required
|
||||
language: python
|
||||
services:
|
||||
- docker
|
||||
env:
|
||||
- "PYTHON=python3"
|
||||
before_install:
|
||||
- sudo apt-get -qq update
|
||||
- sudo apt-get install -y python3-pip
|
||||
python: 3.4
|
||||
services: docker
|
||||
env: PYTHON=python
|
||||
|
||||
# macOS Python 2
|
||||
- os: osx
|
||||
env:
|
||||
- "PYTHON=python2"
|
||||
env: PYTHON=python2
|
||||
|
||||
# macOS Python 3
|
||||
- os: osx
|
||||
env:
|
||||
- "PYTHON=python3"
|
||||
env: PYTHON=python3
|
||||
before_install:
|
||||
- brew update
|
||||
- brew outdated python || brew upgrade python
|
||||
|
||||
script:
|
||||
- |
|
||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
$PYTHON -m pip install -r requirements-dev.txt
|
||||
$PYTHON ./bin/run_tests.py
|
||||
else
|
||||
# linux test requires root to clean up the wheelhouse (docker runs as root)
|
||||
sudo $PYTHON -m pip install -r requirements-dev.txt
|
||||
sudo $PYTHON ./bin/run_tests.py
|
||||
fi
|
||||
install: $PYTHON -m pip install -r requirements-dev.txt
|
||||
|
||||
script: $PYTHON ./bin/run_tests.py
|
||||
|
||||
@@ -15,10 +15,13 @@ What does it do?
|
||||
| | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit |
|
||||
|---|---|---|---|---|---|
|
||||
| Python 2.7 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Python 3.3 | | ✅ | ✅ | ✅ | ✅ |
|
||||
| Python 3.3 | | | | ⚠️ | ⚠️ |
|
||||
| Python 3.4 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
|
||||
<small>[⚠️=deprecated]</small>
|
||||
|
||||
- Builds manylinux, macOS and Windows (32 and 64bit) wheels using Travis CI and Appveyor
|
||||
- Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate)
|
||||
@@ -49,7 +52,7 @@ Usage
|
||||
env: PIP=pip2
|
||||
|
||||
script:
|
||||
- $PIP install cibuildwheel==0.7.1
|
||||
- $PIP install cibuildwheel==0.9.4
|
||||
- cibuildwheel --output-dir wheelhouse
|
||||
```
|
||||
|
||||
@@ -59,7 +62,7 @@ Usage
|
||||
|
||||
```
|
||||
build_script:
|
||||
- pip install cibuildwheel==0.7.1
|
||||
- pip install cibuildwheel==0.9.4
|
||||
- cibuildwheel --output-dir wheelhouse
|
||||
artifacts:
|
||||
- path: "wheelhouse\\*.whl"
|
||||
@@ -82,6 +85,7 @@ All being well, you should get wheels delivered to you in a few minutes.
|
||||
|---|---|---|
|
||||
| **Target wheels** | `CIBW_PLATFORM` | Override the auto-detected target platform |
|
||||
| | `CIBW_SKIP` | Skip certain Python versions |
|
||||
| **Build parameters** | `CIBW_BUILD_VERBOSITY` | Increase or decrease the output of `pip wheel` |
|
||||
| **Build environment** | `CIBW_ENVIRONMENT` | Set environment variables needed during the build |
|
||||
| | `CIBW_BEFORE_BUILD` | Execute a shell command preparing each wheel's build |
|
||||
| | `CIBW_MANYLINUX1_X86_64_IMAGE` | Specify an alternative manylinx1 x86_64 docker image |
|
||||
@@ -151,7 +155,7 @@ Space-separated list of builds to skip. Each build has an identifier like `cp27-
|
||||
|
||||
The format is `python_tag-platform_tag`. The tags are as defined in [PEP 0425](https://www.python.org/dev/peps/pep-0425/#details).
|
||||
|
||||
Python tags look like `cp27` `cp34` `cp35` `cp36`
|
||||
Python tags look like `cp27` `cp34` `cp35` `cp36` `cp37`
|
||||
|
||||
Platform tags look like `macosx_10_6_intel` `manylinux1_x86_64` `manylinux1_i686` `win32` `win_amd64`
|
||||
|
||||
@@ -166,6 +170,16 @@ Examples:
|
||||
- Skip Python 3.6 on Linux: `cp36-manylinux*`
|
||||
- Only build on Python 3.6: `cp27-* cp34-* cp35-*`
|
||||
|
||||
| Environment variable: `CIBW_BUILD_VERBOSITY`
|
||||
| ---
|
||||
|
||||
Optional.
|
||||
|
||||
An number from 1 to 3 to increase the level of verbosity (corresponding to invoking pip with `-v`, `-vv`, and `-vvv`), between -1 and -3 (`-q`, `-qq`, and `-qqq`), or just 0 (default verbosity). These flags are useful while debugging a build when the output of the actual build invoked by `pip wheel` is required.
|
||||
|
||||
Platform-specific variants also available:
|
||||
`CIBW_BUILD_VERBOSITY_MACOS` | `CIBW_BUILD_VERBOSITY_WINDOWS` | `CIBW_BUILD_VERBOSITY_LINUX`
|
||||
|
||||
| Environment variable: `CIBW_ENVIRONMENT`
|
||||
| ---
|
||||
|
||||
@@ -194,13 +208,13 @@ Optional.
|
||||
|
||||
A shell command to run before building the wheel. This option allows you to run a command in **each** Python environment before the `pip wheel` command. This is useful if you need to set up some dependency so it's available during the build.
|
||||
|
||||
If dependencies are required to build your wheel (for example if you include a header from a Python module), set this to `{pip} install .`, and the dependencies will be installed automatically by pip. However, this means your package will be built twice - if your package takes a long time to build, you might wish to manually list the dependencies here instead.
|
||||
If dependencies are required to build your wheel (for example if you include a header from a Python module), set this to `pip install .`, and the dependencies will be installed automatically by pip. However, this means your package will be built twice - if your package takes a long time to build, you might wish to manually list the dependencies here instead.
|
||||
|
||||
The active Python binary can be accessed using `{python}`, and pip with `{pip}`. These are useful when you need to write `python3` or `pip3` on a Python 3.x build.
|
||||
The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. `{project}` can be used as a placeholder for the absolute path to the project's root.
|
||||
|
||||
Example: `{pip} install .`
|
||||
Example: `{pip} install pybind11`
|
||||
Example: `yum install -y libffi-dev && {pip} install .`
|
||||
Example: `pip install .`
|
||||
Example: `pip install pybind11`
|
||||
Example: `yum install -y libffi-dev && pip install .`
|
||||
|
||||
Platform-specific variants also available:
|
||||
`CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX`
|
||||
@@ -222,10 +236,15 @@ Example: `dockcross/manylinux-x86`
|
||||
|
||||
Optional.
|
||||
|
||||
Shell command to run tests after the build. The wheel will be installed automatically and available for import from the tests. The project root should be included in the command as "{project}".
|
||||
Shell command to run tests after the build. The wheel will be installed automatically and available for import from the tests. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`.
|
||||
|
||||
On Linux and Mac, the command runs in a shell, so you can write things like `cmd1 && cmd2`.
|
||||
|
||||
Example: `nosetests {project}/tests`
|
||||
|
||||
Platform-specific variants also available:
|
||||
`CIBW_TEST_COMMAND_MACOS` | `CIBW_TEST_COMMAND_WINDOWS` | `CIBW_TEST_COMMAND_LINUX`
|
||||
|
||||
| Environment variable: `CIBW_TEST_REQUIRES`
|
||||
| ---
|
||||
|
||||
@@ -236,6 +255,9 @@ Space-separated list of dependencies required for running the tests.
|
||||
Example: `pytest`
|
||||
Example: `nose==1.3.7 moto==0.4.31`
|
||||
|
||||
Platform-specific variants also available:
|
||||
`CIBW_TEST_REQUIRES_MACOS` | `CIBW_TEST_REQUIRES_WINDOWS` | `CIBW_TEST_REQUIRES_LINUX`
|
||||
|
||||
--
|
||||
|
||||
#### Example YML syntax
|
||||
@@ -306,6 +328,7 @@ Here are some repos that use cibuildwheel.
|
||||
- [websockets](https://github.com/aaugustin/websockets)
|
||||
- [Parselmouth](https://github.com/YannickJadoul/Parselmouth)
|
||||
- [python-admesh](https://github.com/admesh/python-admesh)
|
||||
- [pybase64](https://github.com/mayeut/pybase64)
|
||||
|
||||
> Add repo here! Send a PR.
|
||||
|
||||
@@ -317,58 +340,87 @@ Since `cibuildwheel` runs the wheel through delocate or auditwheel, it will auto
|
||||
Changelog
|
||||
=========
|
||||
|
||||
### 0.9.3
|
||||
|
||||
- 🛠 Update to Python 3.6.6 on macOS (#82)
|
||||
- ✨ Add support for building Python 3.7 wheels on Windows (#76)
|
||||
- ⚠️ Deprecated support for Python 3.3 on Windows.
|
||||
|
||||
### 0.9.2
|
||||
|
||||
- 🛠 Update Python 3.7.0rc1 to 3.7.0 on macOS (#79)
|
||||
|
||||
### 0.9.1
|
||||
|
||||
- 🛠 Removed the need to use `{python}` and `{pip}` in `CIBW_BEFORE_BUILD` statements, by ensuring the correct version is always on the path at `python` and `pip` instead. (#60)
|
||||
- 🛠 We now patch the _ssl module on Python 3.4 and 3.5 so these versions can still make SSL web requests using TLS 1.2 while building. (#71)
|
||||
|
||||
### 0.9.0
|
||||
|
||||
- ✨ Add support for Python 3.7 (#73)
|
||||
|
||||
### 0.8.0
|
||||
|
||||
- ⚠️ Drop support for Python 3.3 on Linux (#67)
|
||||
- 🐛 Fix TLS by updating setuptools (#69)
|
||||
|
||||
### 0.7.1
|
||||
|
||||
- 🐛 macOS: Fix Pip bugs resulting from PyPI TLS 1.2 enforcement
|
||||
- 🐛 macOS: Fix brew Python3 version problems in the CI
|
||||
|
||||
### 0.7.0
|
||||
|
||||
- You can now specify a custom docker image using the `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE` options. (#46)
|
||||
- Fixed a bug where cibuildwheel would download and build a package from PyPI(!) instead of building the package on the local machine. (#51)
|
||||
- ✨ You can now specify a custom docker image using the `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE` options. (#46)
|
||||
- 🐛 Fixed a bug where cibuildwheel would download and build a package from PyPI(!) instead of building the package on the local machine. (#51)
|
||||
|
||||
### 0.6.0
|
||||
|
||||
- On the Linux build, the host filesystem is now accessible via `/host` (#36)
|
||||
- Fixed a bug where setup.py scripts would run the wrong version of Python when running subprocesses on Linux (#35)
|
||||
- ✨ On the Linux build, the host filesystem is now accessible via `/host` (#36)
|
||||
- 🐛 Fixed a bug where setup.py scripts would run the wrong version of Python when running subprocesses on Linux (#35)
|
||||
|
||||
### 0.5.1
|
||||
|
||||
- Fixed a couple of bugs on Python 3.
|
||||
- Added experimental support for Mac builds on [Bitrise.io](https://www.bitrise.io)
|
||||
- 🐛 Fixed a couple of bugs on Python 3.
|
||||
- ✨ Added experimental support for Mac builds on [Bitrise.io](https://www.bitrise.io)
|
||||
|
||||
### 0.5.0
|
||||
|
||||
- `CIBW_ENVIRONMENT` added. You can now set environment variables for each build, even within the Docker container on Linux. This is a big one! (#21)
|
||||
- `CIBW_BEFORE_BUILD` now runs in a system shell on all platforms. You can now do things like `CIBW_BEFORE_BUILD="cmd1 && cmd2"`. (#32)
|
||||
- ✨ `CIBW_ENVIRONMENT` added. You can now set environment variables for each build, even within the Docker container on Linux. This is a big one! (#21)
|
||||
- ✨ `CIBW_BEFORE_BUILD` now runs in a system shell on all platforms. You can now do things like `CIBW_BEFORE_BUILD="cmd1 && cmd2"`. (#32)
|
||||
|
||||
### 0.4.1
|
||||
|
||||
- Fixed a bug on Windows where subprocess' output was hidden (#23)
|
||||
- Fixed a bug on Appveyor where logs would appear in the wrong order due to output buffering (#24, thanks @YannickJadoul!)
|
||||
- 🐛 Fixed a bug on Windows where subprocess' output was hidden (#23)
|
||||
- 🐛 Fixed a bug on Appveyor where logs would appear in the wrong order due to output buffering (#24, thanks @YannickJadoul!)
|
||||
|
||||
### 0.4.0
|
||||
|
||||
- Fixed a bug that was increasing the build time by building the wheel twice. This was a problem for large projects that have a long build time. If you're upgrading and you need the old behaviour, use `CIBW_BEFORE_BUILD={pip} install .`, or install exactly the dependencies you need in `CIBW_BEFORE_BUILD`. See #18.
|
||||
- 🐛 Fixed a bug that was increasing the build time by building the wheel twice. This was a problem for large projects that have a long build time. If you're upgrading and you need the old behaviour, use `CIBW_BEFORE_BUILD={pip} install .`, or install exactly the dependencies you need in `CIBW_BEFORE_BUILD`. See #18.
|
||||
|
||||
### 0.3.0
|
||||
|
||||
- Removed Python 2.6 support on Linux (#12)
|
||||
- ⚠️ Removed Python 2.6 support on Linux (#12)
|
||||
|
||||
### 0.2.1
|
||||
|
||||
11 June 2017
|
||||
|
||||
- Changed the build process to install the package before building the wheel - this allows direct dependencies to be installed first (#9, thanks @tgarc!)
|
||||
- Added Python 3 support for the main process, for systems where Python 3 is the default (#8, thanks @tgarc).
|
||||
- 🛠 Changed the build process to install the package before building the wheel - this allows direct dependencies to be installed first (#9, thanks @tgarc!)
|
||||
- ✨ Added Python 3 support for the main process, for systems where Python 3 is the default (#8, thanks @tgarc).
|
||||
|
||||
### 0.2.0
|
||||
|
||||
13 April 2017
|
||||
|
||||
- Added `CIBW_SKIP` option, letting users explicitly skip a build
|
||||
- Added `CIBW_BEFORE_BUILD` option, letting users run a shell command before the build starts
|
||||
- ✨ Added `CIBW_SKIP` option, letting users explicitly skip a build
|
||||
- ✨ Added `CIBW_BEFORE_BUILD` option, letting users run a shell command before the build starts
|
||||
|
||||
### 0.1.3
|
||||
|
||||
31 March 2017
|
||||
|
||||
- First public release!
|
||||
- 🌟 First public release!
|
||||
|
||||
Contributing
|
||||
============
|
||||
@@ -398,16 +450,22 @@ Maintainers
|
||||
- Joe Rickerby [@joerick](https://github.com/joerick)
|
||||
- Tomas Garcia [@tgarc](https://github.com/tgarc)
|
||||
- Yannick Jadoul [@YannickJadoul](https://github.com/YannickJadoul)
|
||||
- Matthieu Darbois [@mayeut](https://github.com/mayeut)
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
`cibuildwheel` stands on the shoulders of giants. Massive props to-
|
||||
`cibuildwheel` stands on the shoulders of giants.
|
||||
|
||||
- ⭐️ @matthew-brett for [matthew-brett/multibuild](http://github.com/matthew-brett/multibuild) and [matthew-brett/delocate](http://github.com/matthew-brett/delocate)
|
||||
- @PyPA for the manylinux Docker images [pypa/manylinux](https://github.com/pypa/manylinux)
|
||||
- @ogrisel for [wheelhouse-uploader](https://github.com/ogrisel/wheelhouse-uploader) and `run_with_env.cmd`
|
||||
|
||||
Massive props also to-
|
||||
|
||||
- @zfrenchee for [help debugging many issues](https://github.com/joerick/cibuildwheel/issues/2)
|
||||
- @lelit for some great bug reports and [contributions](https://github.com/joerick/cibuildwheel/pull/73)
|
||||
- @mayeut for a [phenomenal PR](https://github.com/joerick/cibuildwheel/pull/71) patching Python itself for better compatibility!
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = '0.7.1'
|
||||
__version__ = '0.9.4'
|
||||
|
||||
@@ -6,7 +6,7 @@ import cibuildwheel.linux, cibuildwheel.windows, cibuildwheel.macos
|
||||
from cibuildwheel.environment import parse_environment, EnvironmentParseError
|
||||
from cibuildwheel.util import BuildSkipper
|
||||
|
||||
def get_option_from_environment(option_name, platform=None):
|
||||
def get_option_from_environment(option_name, platform=None, default=None):
|
||||
'''
|
||||
Returns an option from the environment, optionally scoped by the platform.
|
||||
|
||||
@@ -21,7 +21,7 @@ def get_option_from_environment(option_name, platform=None):
|
||||
if option is not None:
|
||||
return option
|
||||
|
||||
return os.environ.get(option_name)
|
||||
return os.environ.get(option_name, default)
|
||||
|
||||
|
||||
def main():
|
||||
@@ -70,12 +70,18 @@ def main():
|
||||
exit(2)
|
||||
|
||||
output_dir = args.output_dir
|
||||
test_command = os.environ.get('CIBW_TEST_COMMAND', None)
|
||||
test_requires = os.environ.get('CIBW_TEST_REQUIRES', '').split()
|
||||
test_command = get_option_from_environment('CIBW_TEST_COMMAND', platform=platform)
|
||||
test_requires = get_option_from_environment('CIBW_TEST_REQUIRES', platform=platform, default='').split()
|
||||
project_dir = args.project_dir
|
||||
before_build = get_option_from_environment('CIBW_BEFORE_BUILD', platform=platform)
|
||||
build_verbosity = get_option_from_environment('CIBW_BUILD_VERBOSITY', platform=platform, default='')
|
||||
skip_config = os.environ.get('CIBW_SKIP', '')
|
||||
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform) or ''
|
||||
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
|
||||
|
||||
try:
|
||||
build_verbosity = min(3, max(-3, int(build_verbosity)))
|
||||
except ValueError:
|
||||
build_verbosity = 0
|
||||
|
||||
try:
|
||||
environment = parse_environment(environment_config)
|
||||
@@ -118,6 +124,7 @@ def main():
|
||||
test_command=test_command,
|
||||
test_requires=test_requires,
|
||||
before_build=before_build,
|
||||
build_verbosity=build_verbosity,
|
||||
skip=skip,
|
||||
environment=environment,
|
||||
)
|
||||
@@ -164,7 +171,27 @@ def print_preamble(platform, build_options):
|
||||
for option, value in build_options.items():
|
||||
print(' %s: %r' % (option, value))
|
||||
|
||||
warnings = detect_warnings(platform, build_options)
|
||||
if warnings:
|
||||
print('\nWarnings:')
|
||||
for warning in warnings:
|
||||
print(' ' + warning)
|
||||
|
||||
print('\nHere we go!\n')
|
||||
|
||||
def detect_warnings(platform, build_options):
|
||||
warnings = []
|
||||
|
||||
# warn about deprecated {python} and {pip}
|
||||
for option_name in ['test_command', 'before_build']:
|
||||
option_value = build_options.get(option_name)
|
||||
|
||||
if option_value:
|
||||
if '{python}' in option_value or '{pip}' in option_value:
|
||||
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.")
|
||||
|
||||
return warnings
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
+11
-7
@@ -1,7 +1,7 @@
|
||||
from __future__ import print_function
|
||||
import os, subprocess, sys
|
||||
from collections import namedtuple
|
||||
from .util import prepare_command
|
||||
from .util import prepare_command, get_build_verbosity_extra_flags
|
||||
|
||||
try:
|
||||
from shlex import quote as shlex_quote
|
||||
@@ -9,7 +9,7 @@ except ImportError:
|
||||
from pipes import quote as shlex_quote
|
||||
|
||||
|
||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, skip, environment, manylinux1_images):
|
||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, skip, environment, manylinux1_images):
|
||||
try:
|
||||
subprocess.check_call(['docker', '--version'])
|
||||
except:
|
||||
@@ -22,16 +22,16 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
python_configurations = [
|
||||
PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux1_x86_64', path='/opt/python/cp27-cp27mu'),
|
||||
PythonConfiguration(identifier='cp33-manylinux1_x86_64', path='/opt/python/cp33-cp33m'),
|
||||
PythonConfiguration(identifier='cp34-manylinux1_x86_64', path='/opt/python/cp34-cp34m'),
|
||||
PythonConfiguration(identifier='cp35-manylinux1_x86_64', path='/opt/python/cp35-cp35m'),
|
||||
PythonConfiguration(identifier='cp36-manylinux1_x86_64', path='/opt/python/cp36-cp36m'),
|
||||
PythonConfiguration(identifier='cp37-manylinux1_x86_64', path='/opt/python/cp37-cp37m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux1_i686', path='/opt/python/cp27-cp27m'),
|
||||
PythonConfiguration(identifier='cp27-manylinux1_i686', path='/opt/python/cp27-cp27mu'),
|
||||
PythonConfiguration(identifier='cp33-manylinux1_i686', path='/opt/python/cp33-cp33m'),
|
||||
PythonConfiguration(identifier='cp34-manylinux1_i686', path='/opt/python/cp34-cp34m'),
|
||||
PythonConfiguration(identifier='cp35-manylinux1_i686', path='/opt/python/cp35-cp35m'),
|
||||
PythonConfiguration(identifier='cp36-manylinux1_i686', path='/opt/python/cp36-cp36m'),
|
||||
PythonConfiguration(identifier='cp37-manylinux1_i686', path='/opt/python/cp37-cp37m'),
|
||||
]
|
||||
|
||||
# skip builds as required
|
||||
@@ -66,7 +66,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
fi
|
||||
|
||||
# Build that wheel
|
||||
PATH="$PYBIN:$PATH" "$PYBIN/pip" wheel . -w /tmp/built_wheel --no-deps
|
||||
PATH="$PYBIN:$PATH" "$PYBIN/pip" wheel . -w /tmp/built_wheel --no-deps {build_verbosity_flag}
|
||||
built_wheel=(/tmp/built_wheel/*.whl)
|
||||
|
||||
# Delocate the wheel
|
||||
@@ -97,18 +97,22 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
|
||||
# we're all done here; move it to output
|
||||
mv "$delocated_wheel" /output
|
||||
chown {uid}:{gid} "/output/$(basename "$delocated_wheel")"
|
||||
done
|
||||
'''.format(
|
||||
package_name=package_name,
|
||||
pybin_paths=' '.join(c.path+'/bin' for c in platform_configs),
|
||||
test_requires=' '.join(test_requires),
|
||||
test_command=shlex_quote(
|
||||
test_command.format(project='/project') if test_command else ''
|
||||
prepare_command(test_command, project='/project') if test_command else ''
|
||||
),
|
||||
before_build=shlex_quote(
|
||||
prepare_command(before_build, python='python', pip='pip') if before_build else ''
|
||||
prepare_command(before_build, project='/project') if before_build else ''
|
||||
),
|
||||
build_verbosity_flag=' '.join(get_build_verbosity_extra_flags(build_verbosity)),
|
||||
environment_exports='\n'.join(environment.as_shell_commands()),
|
||||
uid=os.getuid(),
|
||||
gid=os.getgid(),
|
||||
)
|
||||
|
||||
docker_process = subprocess.Popen([
|
||||
|
||||
+37
-20
@@ -7,16 +7,17 @@ try:
|
||||
except ImportError:
|
||||
from pipes import quote as shlex_quote
|
||||
|
||||
from .util import prepare_command
|
||||
from .util import prepare_command, get_build_verbosity_extra_flags
|
||||
|
||||
|
||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, skip, environment):
|
||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, skip, environment):
|
||||
PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'url'])
|
||||
python_configurations = [
|
||||
PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.14/python-2.7.14-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.15/python-2.7.15-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.4', identifier='cp34-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.4.4/python-3.4.4-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.5', identifier='cp35-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.6', identifier='cp36-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.6.5/python-3.6.5-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.6', identifier='cp36-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.6.6/python-3.6.6-macosx10.6.pkg'),
|
||||
PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.0/python-3.7.0-macosx10.6.pkg'),
|
||||
]
|
||||
get_pip_url = 'https://bootstrap.pypa.io/get-pip.py'
|
||||
get_pip_script = '/tmp/get-pip.py'
|
||||
@@ -52,26 +53,42 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
call(['curl', '-L', '-o', '/tmp/Python.pkg', config.url])
|
||||
# install
|
||||
call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/'])
|
||||
# patch open ssl
|
||||
if config.version in ('3.4', '3.5'):
|
||||
call(['curl', '-fsSLo', '/tmp/python-patch.tar.gz', 'https://github.com/mayeut/patch-macos-python-openssl/releases/download/v0.1.0/patch-macos-python-%s-openssl-v0.1.0.tar.gz' % config.version])
|
||||
call(['sudo', 'tar', '-C', '/Library/Frameworks/Python.framework/Versions/%s/' % config.version, '-xmf', '/tmp/python-patch.tar.gz'])
|
||||
|
||||
installation_bin_path = '/Library/Frameworks/Python.framework/Versions/{}/bin'.format(config.version)
|
||||
|
||||
# Python bin folders on Mac don't symlink python3 to python, so we do that
|
||||
# so `python` and `pip` always point to the active configuration.
|
||||
if os.path.exists('/tmp/cibw_bin'):
|
||||
shutil.rmtree('/tmp/cibw_bin')
|
||||
os.makedirs('/tmp/cibw_bin')
|
||||
|
||||
if config.version[0] == '3':
|
||||
os.symlink(os.path.join(installation_bin_path, 'python3'), '/tmp/cibw_bin/python')
|
||||
os.symlink(os.path.join(installation_bin_path, 'python3-config'), '/tmp/cibw_bin/python-config')
|
||||
os.symlink(os.path.join(installation_bin_path, 'pip3'), '/tmp/cibw_bin/pip')
|
||||
|
||||
env = os.environ.copy()
|
||||
env['PATH'] = os.pathsep.join([
|
||||
'/Library/Frameworks/Python.framework/Versions/%s/bin' % config.version,
|
||||
'/tmp/cibw_bin',
|
||||
installation_bin_path,
|
||||
env['PATH'],
|
||||
])
|
||||
env = environment.as_dictionary(prev_environment=env)
|
||||
|
||||
python = 'python3' if config.version[0] == '3' else 'python2'
|
||||
pip = 'pip3' if config.version[0] == '3' else 'pip2'
|
||||
|
||||
# check what version we're on
|
||||
call(['which', python], env=env)
|
||||
call([python, '--version'], env=env)
|
||||
call(['which', 'python'], env=env)
|
||||
call(['python', '--version'], env=env)
|
||||
|
||||
# install pip & wheel
|
||||
call([python, get_pip_script, '--no-setuptools', '--no-wheel'], env=env)
|
||||
call([pip, '--version'], env=env)
|
||||
call([pip, 'install', 'wheel'], env=env)
|
||||
call([pip, 'install', 'delocate'], env=env)
|
||||
call(['python', get_pip_script, '--no-setuptools', '--no-wheel'], env=env)
|
||||
call(['pip', '--version'], env=env)
|
||||
call(['pip', 'install', '--upgrade', 'setuptools'], env=env)
|
||||
call(['pip', 'install', 'wheel'], env=env)
|
||||
call(['pip', 'install', 'delocate'], env=env)
|
||||
|
||||
# setup dirs
|
||||
if os.path.exists('/tmp/built_wheel'):
|
||||
@@ -83,11 +100,11 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
|
||||
# run the before_build command
|
||||
if before_build:
|
||||
before_build_prepared = prepare_command(before_build, python=python, pip=pip)
|
||||
before_build_prepared = prepare_command(before_build, project=abs_project_dir)
|
||||
call(before_build_prepared, env=env, shell=True)
|
||||
|
||||
# build the wheel
|
||||
call([pip, 'wheel', abs_project_dir, '-w', '/tmp/built_wheel', '--no-deps'], env=env)
|
||||
call(['pip', 'wheel', abs_project_dir, '-w', '/tmp/built_wheel', '--no-deps'] + get_build_verbosity_extra_flags(build_verbosity), env=env)
|
||||
built_wheel = glob('/tmp/built_wheel/*.whl')[0]
|
||||
|
||||
if built_wheel.endswith('none-any.whl'):
|
||||
@@ -101,17 +118,17 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0]
|
||||
|
||||
# install the wheel
|
||||
call([pip, 'install', delocated_wheel], env=env)
|
||||
call(['pip', 'install', delocated_wheel], env=env)
|
||||
|
||||
# test the wheel
|
||||
if test_requires:
|
||||
call([pip, 'install'] + test_requires, env=env)
|
||||
call(['pip', 'install'] + test_requires, env=env)
|
||||
if test_command:
|
||||
# run the tests from $HOME, with an absolute path in the command
|
||||
# (this ensures that Python runs the tests against the installed wheel
|
||||
# and not the repo code)
|
||||
test_command_absolute = test_command.format(project=abs_project_dir)
|
||||
call(shlex.split(test_command_absolute), cwd=os.environ['HOME'], env=env)
|
||||
test_command_prepared = prepare_command(test_command, project=abs_project_dir)
|
||||
call(test_command_prepared, cwd=os.environ['HOME'], env=env, shell=True)
|
||||
|
||||
# we're all done here; move it to output
|
||||
shutil.move(delocated_wheel, output_dir)
|
||||
|
||||
+15
-7
@@ -1,16 +1,24 @@
|
||||
from fnmatch import fnmatch
|
||||
import warnings
|
||||
|
||||
|
||||
def prepare_command(command, python, pip):
|
||||
def prepare_command(command, project):
|
||||
'''
|
||||
Preprocesses a command by expanding variables like {python} or {pip}.
|
||||
Preprocesses a command by expanding variables like {project}.
|
||||
|
||||
For example, used for the before_build option, where the user would
|
||||
like to run a command like `python setup.py test`. If the command should run on
|
||||
Python 3, the user could write `{python} setup.py test`. This command would expand
|
||||
it out to python2 or python3 as appropriate.
|
||||
For example, used in the test_command option, to specify the path to the
|
||||
tests directory.
|
||||
'''
|
||||
return command.format(python=python, pip=pip)
|
||||
return command.format(python='python', pip='pip', project=project)
|
||||
|
||||
|
||||
def get_build_verbosity_extra_flags(level):
|
||||
if level > 0:
|
||||
return ['-' + level * 'v']
|
||||
elif level < 0:
|
||||
return ['-' + -level * 'q']
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
class BuildSkipper(object):
|
||||
|
||||
+14
-7
@@ -7,10 +7,10 @@ except ImportError:
|
||||
from collections import namedtuple
|
||||
from glob import glob
|
||||
|
||||
from .util import prepare_command, Unbuffered
|
||||
from .util import prepare_command, get_build_verbosity_extra_flags, Unbuffered
|
||||
|
||||
|
||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, skip, environment):
|
||||
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, skip, environment):
|
||||
# Python under AppVeyor/Windows seems to be buffering by default, giving problems interleaving subprocess call output with unflushed calls to 'print'
|
||||
sys.stdout.flush()
|
||||
sys.stdout = Unbuffered(sys.stdout)
|
||||
@@ -40,6 +40,8 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\Python35-x64'),
|
||||
PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\Python36'),
|
||||
PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\Python36-x64'),
|
||||
PythonConfiguration(version='3.7.x', arch="32", identifier='cp37-win32', path='C:\Python37'),
|
||||
PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\Python37-x64'),
|
||||
]
|
||||
|
||||
abs_project_dir = os.path.abspath(project_dir)
|
||||
@@ -50,6 +52,10 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
if skip(config.identifier):
|
||||
print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr)
|
||||
continue
|
||||
|
||||
# check python & pip exist for this configuration
|
||||
assert os.path.exists(os.path.join(config.path, 'python.exe'))
|
||||
assert os.path.exists(os.path.join(config.path, 'Scripts', 'pip.exe'))
|
||||
|
||||
# setup dirs
|
||||
if os.path.exists(built_wheel_dir):
|
||||
@@ -72,17 +78,18 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
shell(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)\"'], env=env)
|
||||
|
||||
# prepare the Python environment
|
||||
shell(['pip', 'install', '--disable-pip-version-check', '--user', '--upgrade', 'pip'],
|
||||
shell(['python', '-m', 'pip', 'install', '--upgrade', 'pip'],
|
||||
env=env)
|
||||
shell(['pip', 'install', '--upgrade', 'setuptools'], env=env)
|
||||
shell(['pip', 'install', 'wheel'], env=env)
|
||||
|
||||
# run the before_build command
|
||||
if before_build:
|
||||
before_build_prepared = prepare_command(before_build, python='python', pip='pip')
|
||||
before_build_prepared = prepare_command(before_build, project=abs_project_dir)
|
||||
shell([before_build_prepared], env=env)
|
||||
|
||||
# build the wheel
|
||||
shell(['pip', 'wheel', abs_project_dir, '-w', built_wheel_dir, '--no-deps'], env=env)
|
||||
shell(['pip', 'wheel', abs_project_dir, '-w', built_wheel_dir, '--no-deps'] + get_build_verbosity_extra_flags(build_verbosity), env=env)
|
||||
built_wheel = glob(built_wheel_dir+'/*.whl')[0]
|
||||
|
||||
# install the wheel
|
||||
@@ -95,8 +102,8 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
|
||||
# run the tests from c:\, with an absolute path in the command
|
||||
# (this ensures that Python runs the tests against the installed wheel
|
||||
# and not the repo code)
|
||||
test_command_absolute = test_command.format(project=abs_project_dir)
|
||||
shell([test_command_absolute], cwd='c:\\', env=env)
|
||||
test_command_prepared = prepare_command(test_command, project=abs_project_dir)
|
||||
shell([test_command_prepared], cwd='c:\\', env=env)
|
||||
|
||||
# we're all done here; move it to output
|
||||
shutil.move(built_wheel, output_dir)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.7.1
|
||||
current_version = 0.9.4
|
||||
commit = True
|
||||
tag = True
|
||||
message = Bump version
|
||||
|
||||
@@ -8,7 +8,7 @@ except ImportError:
|
||||
|
||||
setup(
|
||||
name='cibuildwheel',
|
||||
version='0.7.1',
|
||||
version='0.9.4',
|
||||
install_requires=['bashlex'],
|
||||
description="Build Python wheels on CI with minimal configuration.",
|
||||
long_description='For readme please see http://github.com/joerick/cibuildwheel',
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"CIBW_TEST_REQUIRES": "nose",
|
||||
"CIBW_TEST_COMMAND": "nosetests {project}/test"
|
||||
"CIBW_TEST_COMMAND": "false || nosetests {project}/test",
|
||||
"comment": "The 'false ||' bit is to ensure this command runs in a shell on Mac and Linux",
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "nosetests {project}/test"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"CIBW_BEFORE_BUILD": "{python} -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && {python} -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"",
|
||||
"CIBW_BEFORE_BUILD_WINDOWS": "{python} -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && {python} -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\""
|
||||
"CIBW_BEFORE_BUILD": "python -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"",
|
||||
"CIBW_BEFORE_BUILD_WINDOWS": "python -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && python -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\""
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"CIBW_MANYLINUX1_X86_64_IMAGE": "dockcross/manylinux-x64",
|
||||
"CIBW_MANYLINUX1_I686_IMAGE": "dockcross/manylinux-x86"
|
||||
"CIBW_MANYLINUX1_I686_IMAGE": "dockcross/manylinux-x86",
|
||||
"CIBW_SKIP": "cp37-manylinux*"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import ssl
|
||||
import sys
|
||||
from setuptools import setup, Extension
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
from urllib2 import urlopen
|
||||
else:
|
||||
from urllib.request import urlopen
|
||||
|
||||
if sys.version_info[0:2] == (3, 3):
|
||||
data = urlopen('https://www.nist.gov')
|
||||
else:
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
|
||||
data = urlopen('https://www.nist.gov', context=context)
|
||||
|
||||
setup(
|
||||
name="spam",
|
||||
ext_modules=[Extension('spam', sources=['spam.c'])],
|
||||
version="0.1.0",
|
||||
)
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject *
|
||||
spam_system(PyObject *self, PyObject *args)
|
||||
{
|
||||
const char *command;
|
||||
int sts;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s", &command))
|
||||
return NULL;
|
||||
sts = system(command);
|
||||
return PyLong_FromLong(sts);
|
||||
}
|
||||
|
||||
/* Module initialization */
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
#define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void)
|
||||
#define MOD_DEF(m, name, doc, methods, module_state_size) \
|
||||
static struct PyModuleDef moduledef = { \
|
||||
PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \
|
||||
m = PyModule_Create(&moduledef);
|
||||
#define MOD_RETURN(m) return m;
|
||||
#else
|
||||
#define MOD_INIT(name) PyMODINIT_FUNC init##name(void)
|
||||
#define MOD_DEF(m, name, doc, methods, module_state_size) \
|
||||
m = Py_InitModule3(name, methods, doc);
|
||||
#define MOD_RETURN(m) return;
|
||||
#endif
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
{"system", (PyCFunction)spam_system, METH_VARARGS,
|
||||
"Execute a shell command."},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
MOD_INIT(spam)
|
||||
{
|
||||
PyObject* m;
|
||||
|
||||
MOD_DEF(m,
|
||||
"spam",
|
||||
"Example module",
|
||||
module_methods,
|
||||
-1)
|
||||
|
||||
MOD_RETURN(m)
|
||||
}
|
||||
Reference in New Issue
Block a user