Compare commits

...
74 Commits
Author SHA1 Message Date
Joe Rickerby d93547d8be Bump version 2018-05-04 10:04:39 -07:00
Yannick Jadoul a863e21b14 Merge pull request #68 from mayeut/python-update
macOS: update to python 2.7.15
2018-05-04 17:43:36 +02:00
mayeut b4c0150d43 macOS/Windows: Update setuptools 2018-05-04 17:27:33 +02:00
Yannick Jadoul c8019dac1d Merge pull request #67 from mayeut/only-drop-linux-python3.3
Drop python 3.3 support on Linux
2018-05-04 12:12:48 +02:00
mayeut e6fa70a910 Drop python 3.3 support on Linux 2018-05-03 22:05:45 +02:00
mayeut b19e8b76f3 macOS: update to python 2.7.15 2018-05-02 22:01:53 +02:00
Yannick Jadoul 23ab1f780e Merge pull request #61 from YannickJadoul/pip-verbose
Adding an option to make the `pip wheel` invocation more or less verbose
2018-04-30 15:24:19 +02:00
Yannick Jadoul eedcd62753 Renaming util.get_build_verbosity_flag into util.get_build_verbosity_extra_flags 2018-04-30 15:07:56 +02:00
Joe Rickerby 3a4d611da1 Bump version 2018-04-25 23:03:14 +01:00
Joe Rickerby 8877990ec6 Merge pull request #62 from anthrotype/fix-pip-upgrade-windows
windows: upgrade pip with 'python -m pip'
2018-04-25 23:01:58 +01:00
Cosimo Lupo 0cc41fabba windows: upgrade pip with 'python -m pip'
this fixes an "ImportError: cannot import name main" when self-upgrading
pip to latest version 10

see https://github.com/pypa/pip/issues/5240#issuecomment-382989420
2018-04-20 10:48:42 +01:00
Yannick Jadoul 8d9d970874 Fixing empty verbosity flag argument to subprocess.check_call 2018-04-08 21:51:19 +02:00
Yannick Jadoul c563bca054 Adding an to make the pip wheel invocation more or less verbose 2018-04-08 21:37:40 +02:00
Joe Rickerby 71503b7143 Merge pull request #59 from YannickJadoul/prepare-test-command
Replacing {python} and {pip} in CIBW_TEST_COMMAND (and {project} in C…
2018-04-08 18:06:30 +01:00
Yannick Jadoul e33b6bed77 Replacing leftover test_command.format(...) by prepare_command(test_command, ...) in linux.py 2018-04-08 16:50:10 +02:00
Yannick Jadoul 99469087ed Replacing {python} and {pip} in CIBW_TEST_COMMAND (and {project} in CIBW_BEFORE_BUILD) for consistency 2018-04-07 23:57:58 +02:00
Joe Rickerby 3b847ab0aa Changelog updated 2018-04-02 15:50:59 +01:00
Joe Rickerby 7f51b1d8e7 Bump version 2018-04-02 15:49:39 +01:00
Joe Rickerby 7f77aa86b1 Merge pull request #57 from mayeut/macos-update
macOS: Fix Pip bugs resulting from PyPI TLS 1.2 enforcement
macOS: Fix brew python version
2018-04-02 15:48:57 +01:00
mayeut 47873a9175 Use latest pip on macos 2018-03-31 13:19:12 +02:00
mayeut c38a33381d Update python versions on macos 2018-03-31 13:19:00 +02:00
mayeut 121f7cc678 Fix macos python3 test 2018-03-31 12:36:59 +02:00
Joe Rickerby d6361c0e31 Update changelog 2018-01-07 18:10:27 +00:00
Joe Rickerby ffb48a61cb Bump version 2018-01-07 18:04:52 +00:00
Joe Rickerby d16c63ad95 Merge pull request #46 from YannickJadoul/alternative-docker-images
Option for alternative docker images for manylinux1
2018-01-07 18:02:23 +00:00
Joe Rickerby d16d81e207 Update minimal config example
pip2 and language: generic is required on mac for travis to work.

Fixes #48
2018-01-07 17:58:21 +00:00
Joe Rickerby e5c7bb416d Merge pull request #51 from YannickJadoul/single-subdir-project-fix
Fixing confusion between subdirectory and PyPI projectin call to `pip wheel <subdir>`
2018-01-04 22:31:51 +00:00
Yannick Jadoul a85b535d83 Fixing confusion between subdirectory and PyPI projectin call to pip wheel <subdir> 2017-12-30 13:27:55 +01:00
Yannick Jadoul 9013a7783f Adding a check for Linux to test 06_docker_images's check for the '/dockcross' directory 2017-12-29 13:42:08 +01:00
Joe Rickerby 08194a1db9 Add check for running inside the dockcross image 2017-12-24 12:53:10 +00:00
Joe Rickerby a9e05a596a Update README.md
Add extra examples of CIBW_SKIP as discussed in #47
2017-12-21 15:54:21 +00:00
Yannick Jadoul e40f9b2345 Added documentation on CIBW_MANYLINUX1_..._IMAGE options to the README 2017-11-19 23:59:24 +01:00
Yannick Jadoul 65dccc46b2 Disabling skipping of all macos/windows tests for 06_docker_images 2017-11-19 23:18:55 +01:00
Yannick Jadoul d247743713 Adding platform-specific arguments (for manylinux1 images) 2017-11-19 23:18:10 +01:00
Yannick Jadoul 4e0b3c0f31 First try at implementing optionsfor allowing different manylinux1 docker images 2017-10-29 11:47:38 +01:00
Joe Rickerby 6bbef964c9 Update changelog 2017-10-09 19:26:45 +01:00
Joe Rickerby ede818944e Bump version 2017-10-09 19:09:26 +01:00
Joe Rickerby 9c73dd2ac7 Merge pull request #42 from hroncok/patch-2
Add python-admesh to the list of working examples
2017-10-09 19:05:22 +01:00
Miro Hrončok 5f7c019392 Add python-admesh to the list of working examples 2017-09-20 18:09:30 +02:00
Joe Rickerby cd9eeb72e5 Merge pull request #34 from joerick/faster-mac-ci
Faster builds on Mac
2017-09-19 20:12:39 +01:00
Joe Rickerby d075c731b6 Merge pull request #36 from YannickJadoul/linux-docker-host-mount
Adding extra mount / to /host on docker invocation for linux wheels
2017-09-19 20:11:09 +01:00
Joe Rickerby 8fa41df67d Fix a couple typos 2017-09-19 20:09:59 +01:00
Joe Rickerby 0e849c2bcf Merge pull request #37 from joerick/readme-repos-parselmouth
Added the Parselmouth project to the projects using cibuildwheel in the README
2017-09-19 12:20:53 +01:00
Joe Rickerby 212fa34d9d Merge pull request #38 from hroncok/patch-1
It's manylinux1_i686, not manylinux1_i386
2017-09-19 12:20:37 +01:00
Miro Hrončok cb73b18bce It's manylinux1_i686, not manylinux1_i386 2017-09-18 23:59:46 +02:00
Yannick Jadoul 1730d6fd0b Adding notes on Linux builds in Docker 2017-09-16 23:03:14 +02:00
Joe Rickerby 1e9067272d Merge pull request #35 from YannickJadoul/linux-python-bin-path
Adding $PYBIN to path when calling pip wheel
2017-09-16 10:04:13 +01:00
Yannick Jadoul b0afaf33c2 Added the Parselmouth project to the projects using cibuildwheel in the README 2017-09-14 10:54:01 +02:00
Yannick Jadoul d0e5a4bb3c Adding extra mount / to /host on docker invocation for linux wheels 2017-09-13 22:56:06 +02:00
Yannick Jadoul 4dc8bf447f Adding $PYBIN to path when calling pip wheel 2017-09-12 12:37:51 +02:00
Joe Rickerby 9a6a7d3375 Python 3 faster builds too 2017-09-11 10:51:30 +01:00
Joe Rickerby 719ad30d05 Update changelog 2017-09-10 22:52:21 +01:00
Joe Rickerby d549a1301f Bump version 2017-09-10 22:46:27 +01:00
Joe Rickerby adef5445f7 Merge pull request #25 from joerick/python3-ci
Add CI runs for Python3 as well as Python2
2017-09-10 22:42:48 +01:00
Joe Rickerby 666c10465a Speed up mac CI by only installing python if it's not already installed 2017-09-10 22:40:49 +01:00
Joe Rickerby e486a6551d Merge pull request #33 from YannickJadoul/readme-summary
Adding an overview of available options
2017-09-10 22:22:33 +01:00
Joe Rickerby 53b4ea5125 Maybe bitrise will run the macos builds! 2017-09-10 22:02:36 +01:00
Joe Rickerby a7f81b3c58 Use language: generic for Mac builds on Travis
https://github.com/travis-ci/travis-ci/issues/2312
2017-09-10 21:29:01 +01:00
Yannick Jadoul 52dba1cc83 Updating README with overview of available customizations 2017-09-08 00:15:11 +02:00
Joe Rickerby 986d56279e Update changelog 2017-09-07 23:06:08 +01:00
Joe Rickerby e413863531 Fix running command nodes on python 3 2017-09-07 22:38:52 +01:00
Joe Rickerby f4eafa901b Ignore some venv locations 2017-09-07 22:38:32 +01:00
Joe Rickerby 0cd8228db1 Use same python interpreter for running pytest 2017-09-07 21:59:04 +01:00
Joe Rickerby 510a6ce84a Only install python3 pip when doing that build 2017-09-07 21:50:48 +01:00
Joe Rickerby 7420e2a924 Use apt to install pip 2017-09-07 21:45:43 +01:00
Joe Rickerby 1cd65ccbb6 Add ensurepip for Linux build to ensure setuptools/pip are installed 2017-09-07 18:58:08 +01:00
Joe Rickerby 857644e391 Merge branch 'master' into python3-ci
* master: (28 commits)
  Update README to combine environment sections
  Update README
  os.path.samefile is not available on windows.
  Add shell-style execution on the Mac
  Use os.path.samefile to get around filename case insensitivity
  Add test for before_build executing in a shell
  Fix some linter warnings
  Add CIBW_ENVIRONMENT to README and reorder options
  Fix empty env string case
  Fix string splitting for the env string
  Making call from run_tests to run_test subprocess.check_call
  Fixing 'ValueError: Attempted relative import in non-package'
  Update README.md
  Reducing code duplication in bin/run_test.py and bin/run_tests.py
  Semicolons need quoting
  Ignore vscode project settings
  Windows uses a different pathsep so have to use that in the test
  Make shell evals work and add tests for that
  Use parse_environment in the main code
  Run the unit tests in CI
  ...

# Conflicts:
#	.travis.yml
#	appveyor.yml
#	run_tests.py
2017-09-07 18:55:33 +01:00
Joe Rickerby 4922c8c4ec Merge commit '92304597bd06531c0139db9dd8766562f38cf19e' into python3-ci
* commit '92304597bd06531c0139db9dd8766562f38cf19e':
  Replacing unbuffered 'os.fdopen' by proxy object to have a unbuffered stdout solution for Windows and AppVeyor that works on Python 3
2017-09-01 13:51:49 +01:00
Joe Rickerby 267e566c43 Add language: python to the travis build 2017-09-01 13:49:39 +01:00
Yannick Jadoul 92304597bd Replacing unbuffered 'os.fdopen' by proxy object to have a unbuffered stdout solution for Windows and AppVeyor that works on Python 3 2017-08-17 22:06:23 +02:00
Joe Rickerby 6abacb46e4 Run the tests with the same interpreter that runs run_tests.py 2017-08-14 23:37:06 +01:00
Joe Rickerby f07979ec23 Actually fix syntax error 2017-08-14 23:23:15 +01:00
Joe Rickerby e66ab50909 Fix syntax error 2017-08-14 23:20:41 +01:00
Joe Rickerby 037cda5ef3 Add Python 3 CI runners 2017-08-14 23:19:39 +01:00
18 changed files with 314 additions and 59 deletions
+3
View File
@@ -85,7 +85,10 @@ celerybeat-schedule
# virtualenv
.venv
venv/
venv3/
ENV/
env/
env3/
# Spyder project settings
.spyderproject
+33 -4
View File
@@ -1,17 +1,46 @@
language: generic
matrix:
include:
# Linux Python 2
- sudo: required
language: python
services:
- docker
env:
- "PYTHON=python2"
# 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
# macOS Python 2
- os: osx
env:
- "PYTHON=python2"
# macOS Python 3
- os: osx
env:
- "PYTHON=python3"
before_install:
- brew update
- brew outdated python || brew upgrade python
script:
- |
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
pip install -r requirements-dev.txt
python ./bin/run_tests.py
$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 pip install -r requirements-dev.txt
sudo python ./bin/run_tests.py
sudo $PYTHON -m pip install -r requirements-dev.txt
sudo $PYTHON ./bin/run_tests.py
fi
+93 -9
View File
@@ -15,7 +15,7 @@ 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 | ✅ | ✅ | ✅ | ✅ | ✅ |
@@ -36,15 +36,20 @@ Usage
- Create a `.travis.yml` file in your repo.
```
language: python
matrix:
include:
- sudo: required
services:
- docker
env: PIP=pip
- os: osx
language: generic
env: PIP=pip2
script:
- pip install cibuildwheel==0.5.0
- $PIP install cibuildwheel==0.8.0
- cibuildwheel --output-dir wheelhouse
```
@@ -54,7 +59,7 @@ Usage
```
build_script:
- pip install cibuildwheel==0.5.0
- pip install cibuildwheel==0.8.0
- cibuildwheel --output-dir wheelhouse
artifacts:
- path: "wheelhouse\\*.whl"
@@ -69,6 +74,31 @@ All being well, you should get wheels delivered to you in a few minutes.
> ⚠️ Got an error? Check the [checklist](#it-didnt-work) below.
### Configuration overview
`cibuildwheel` allows for easy customization of the various phases of the build process demonstrated above:
| | Option | |
|---|---|---|
| **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 |
| | `CIBW_MANYLINUX1_I686_IMAGE` | Specify an alternative manylinux1 i686 docker image |
| **Tests** | `CIBW_TEST_COMMAND` | Execute a shell command to test all built wheels |
| | `CIBW_TEST_REQUIRES` | Install Python dependencies before running the tests |
A more detailed description of the options, the allowed values, and some examples can be found in the [Options](#options) section.
### Linux builds on Docker
Linux wheels are built in the [`manylinux1` docker images](https://github.com/pypa/manylinux) to provide binary compatible wheels on Linux, according to [PEP 513](https://www.python.org/dev/peps/pep-0513/). Because of this, when building with `cibuildwheel` on Linux, a few things should be taken into account:
- Progams and libraries cannot be installed on the Travis CI Ubuntu host with `apt-get`, but can be installed inside of the Docker image using `yum` or manually. The same goes for environment variables that are potentially needed to customize the wheel building. `cibuildwheel` supports this by providing the `CIBW_ENVIRONMENT` and `CIBW_BEFORE_BUILD` options to setup the build environment inside the running Docker image. See [below](#options) for details on these options.
- The project directory is mounted in the running Docker instance as `/project`, the output directory for the wheels as `/output`. In general, this is handled transparently by `cibuildwheel`. For a more finegrained level of control however, the root of the host file system is mounted as `/host`, allowing for example to access shared files, caches, etc. on the host file system.
- Alternative dockers images can be specified with the `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE` options to allow for a custom, preconfigured build environment for the Linux builds. See [below](#options) for more details.
Options
-------
@@ -124,13 +154,28 @@ The format is `python_tag-platform_tag`. The tags are as defined in [PEP 0425](h
Python tags look like `cp27` `cp34` `cp35` `cp36`
Platform tags look like `macosx_10_6_intel` `manylinux1_x86_64` `manylinux1_i386` `win32` `win_amd64`
Platform tags look like `macosx_10_6_intel` `manylinux1_x86_64` `manylinux1_i686` `win32` `win_amd64`
You can also use shell-style globbing syntax (as per `fnmatch`)
Example: `cp27-macosx_10_6_intel` (don't build on Python 2 on Mac)
Example: `cp27-win*` (don't build on Python 2.7 on Windows)
Example: `cp34-* cp35-*` (don't build on Python 3.4 or Python 3.5)
Examples:
- Skip building on Python 2.7 on the Mac: `cp27-macosx_10_6_intel`
- Skip building on Python 2.7 on all platforms: `cp27-*`
- Skip Python 2.7 on Windows: `cp27-win*`
- Skip Python 2.7 on 32bit Windows: `cp27-win32`
- Skip Python 3.4 and Python 3.5: `cp34-* cp35-*`
- 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`
| ---
@@ -162,7 +207,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), 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}`. These are useful when you need to write `python3` or `pip3` on a Python 3.x build. `{project}` can be used as a placeholder for the absolute path to the project's root.
Example: `{pip} install .`
Example: `{pip} install pybind11`
@@ -171,12 +216,24 @@ 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`
| Environment variables: `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE`
| ---
Optional.
An alternative docker image to be used for building [`manylinux1`](https://github.com/pypa/manylinux) wheels. `cibuildwheel` will then pull these instead of the official images, [`quay.io/pypa/manylinux1_x86_64`](https://quay.io/pypa/manylinux1_i686) and [`quay.io/pypa/manylinux1_i686`](https://quay.io/pypa/manylinux1_i686).
Beware to specify a valid docker image that can be used the same as the official, default docker images: all necessary Python and pip versions need to be present in `/opt/python/`, and the `auditwheel` tool needs to be present for `cibuildwheel` to work. Apart from that, the architecture and relevant shared system libraries need to be manylinux1-compatible in order to produce valid `manylinux1` wheels (see https://github.com/pypa/manylinux and [PEP 513](https://www.python.org/dev/peps/pep-0513/) for more details).
Example: `dockcross/manylinux-x64`
Example: `dockcross/manylinux-x86`
| Environment variable: `CIBW_TEST_COMMAND`
| ---
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. Just like in the `CIBW_BEFORE_BUILD` option, `{python}`, `{pip}`, and `{project}` will respectively be replaced by the Python executable, the pip executable, and the absolute project directory.
Example: `nosetests {project}/tests`
@@ -258,6 +315,8 @@ Here are some repos that use cibuildwheel.
- [pyinstrument_cext](https://github.com/joerick/pyinstrument_cext)
- [websockets](https://github.com/aaugustin/websockets)
- [Parselmouth](https://github.com/YannickJadoul/Parselmouth)
- [python-admesh](https://github.com/admesh/python-admesh)
> Add repo here! Send a PR.
@@ -269,6 +328,31 @@ Since `cibuildwheel` runs the wheel through delocate or auditwheel, it will auto
Changelog
=========
### 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)
### 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)
### 0.5.1
- 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)
### 0.4.1
- Fixed a bug on Windows where subprocess' output was hidden (#23)
+7 -2
View File
@@ -1,5 +1,10 @@
environment:
matrix:
- PYTHON: "C:\\Python27\\python.exe"
- PYTHON: "C:\\Python35\\python.exe"
build_script:
- pip install -r requirements-dev.txt
- "%PYTHON% -m pip install -r requirements-dev.txt"
# the '-u' flag is required so the output is in the correct order.
# See https://github.com/joerick/cibuildwheel/pull/24 for more info.
- python -u ./bin/run_tests.py
- "%PYTHON% -u ./bin/run_tests.py"
+1 -1
View File
@@ -17,7 +17,7 @@ def single_run(test_project):
project_env = {str(k): str(v) for k, v in project_env.items()} # unicode not allowed in env
env.update(project_env)
print('Building %s with environment %s' % (test_project, project_env))
subprocess.check_call(['cibuildwheel', test_project], env=env)
subprocess.check_call([sys.executable, '-m', 'cibuildwheel', test_project], env=env)
wheels = glob('wheelhouse/*.whl')
print('%s built successfully. %i wheels built.' % (test_project, len(wheels)))
+1 -1
View File
@@ -10,7 +10,7 @@ if __name__ == '__main__':
### run the unit tests
subprocess.check_call(['python', '-m', 'pytest', 'unit_test'])
subprocess.check_call([sys.executable, '-m', 'pytest', 'unit_test'])
### run the integration tests
+1 -1
View File
@@ -1 +1 @@
__version__ = '0.5.0'
__version__ = '0.8.0'
+21
View File
@@ -59,6 +59,8 @@ def main():
platform = 'macos'
elif 'APPVEYOR' in os.environ:
platform = 'windows'
elif 'BITRISE_BUILD_NUMBER' in os.environ:
platform = 'macos'
else:
print('cibuildwheel: Unable to detect platform. cibuildwheel should run on your CI server, '
'Travis CI and Appveyor are supported. You can run on your development '
@@ -72,9 +74,15 @@ def main():
test_requires = os.environ.get('CIBW_TEST_REQUIRES', '').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) or ''
skip_config = os.environ.get('CIBW_SKIP', '')
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform) or ''
try:
build_verbosity = min(3, max(-3, int(build_verbosity)))
except ValueError:
build_verbosity = 0
try:
environment = parse_environment(environment_config)
except (EnvironmentParseError, ValueError) as e:
@@ -116,10 +124,23 @@ def main():
test_command=test_command,
test_requires=test_requires,
before_build=before_build,
build_verbosity=build_verbosity,
skip=skip,
environment=environment,
)
if platform == 'linux':
manylinux1_x86_64_image = os.environ.get('CIBW_MANYLINUX1_X86_64_IMAGE', None)
manylinux1_i686_image = os.environ.get('CIBW_MANYLINUX1_I686_IMAGE', None)
build_options.update(
manylinux1_images={'x86_64': manylinux1_x86_64_image, 'i686': manylinux1_i686_image},
)
elif platform == 'macos':
pass
elif platform == 'windows':
pass
print_preamble(platform, build_options)
if not os.path.exists(output_dir):
+6 -2
View File
@@ -1,4 +1,4 @@
import subprocess, shlex
import subprocess, shlex, sys
from collections import namedtuple
import bashlex
@@ -60,8 +60,12 @@ def evaluate_word_node(node, context):
def evaluate_command_node(node, context):
words = [evaluate_node(part, context=context) for part in node.parts]
command = ' '.join(words)
return subprocess.check_output(shlex.split(command), env=context.environment)
output = subprocess.check_output(shlex.split(command), env=context.environment)
if sys.version_info[0] >= 3:
return output.decode('utf8', 'replace')
else:
return output
def evaluate_parameter_node(node, context):
return context.environment.get(node.value, '')
+11 -11
View File
@@ -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):
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,13 +22,11 @@ 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='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'),
@@ -38,8 +36,8 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
python_configurations = [c for c in python_configurations if not skip(c.identifier)]
platforms = [
('manylinux1_x86_64', 'quay.io/pypa/manylinux1_x86_64'),
('manylinux1_i686', 'quay.io/pypa/manylinux1_i686'),
('manylinux1_x86_64', manylinux1_images.get('x86_64') or 'quay.io/pypa/manylinux1_x86_64'),
('manylinux1_i686', manylinux1_images.get('i686') or 'quay.io/pypa/manylinux1_i686'),
]
for platform_tag, docker_image in platforms:
@@ -62,11 +60,11 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
mkdir /tmp/delocated_wheel
if [ ! -z {before_build} ]; then
PATH=$PYBIN:$PATH sh -c {before_build}
PATH="$PYBIN:$PATH" sh -c {before_build}
fi
# Build that wheel
"$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
@@ -91,7 +89,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
# Run the tests from a different directory
if [ ! -z {test_command} ]; then
pushd $HOME
PATH=$PYBIN:$PATH sh -c {test_command}
PATH="$PYBIN:$PATH" sh -c {test_command}
popd
fi
@@ -103,11 +101,12 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
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, python='python', pip='pip', 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, python='python', pip='pip', 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()),
)
@@ -120,6 +119,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
'-i',
'-v', '%s:/project' % os.path.abspath(project_dir),
'-v', '%s:/output' % os.path.abspath(output_dir),
'-v', '/:/host',
docker_image,
'/bin/bash'],
stdin=subprocess.PIPE, universal_newlines=True)
+30 -15
View File
@@ -7,17 +7,24 @@ 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.13/python-2.7.13-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.3/python-3.5.3-macosx10.6.pkg'),
PythonConfiguration(version='3.6', identifier='cp36-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.6.0/python-3.6.0-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'),
]
get_pip_url = 'https://bootstrap.pypa.io/get-pip.py'
get_pip_script = '/tmp/get-pip.py'
pkgs_output = subprocess.check_output(['pkgutil', '--pkgs'])
if sys.version_info[0] >= 3:
pkgs_output = pkgs_output.decode('utf8')
installed_system_packages = pkgs_output.splitlines()
def call(args, env=None, cwd=None, shell=False):
# print the command executing for the logs
@@ -28,15 +35,23 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
return subprocess.check_call(args, env=env, cwd=cwd, shell=shell)
abs_project_dir = os.path.abspath(project_dir)
# get latest pip once and for all
call(['curl', '-L', '-o', get_pip_script, get_pip_url])
for config in python_configurations:
if skip(config.identifier):
print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr)
continue
# download the pkg
call(['curl', '-L', '-o', '/tmp/Python.pkg', config.url])
# install
call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/'])
# if this version of python isn't installed, get it from python.org and install
python_package_identifier = 'org.python.Python.PythonFramework-%s' % config.version
if python_package_identifier not in installed_system_packages:
# download the pkg
call(['curl', '-L', '-o', '/tmp/Python.pkg', config.url])
# install
call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/'])
env = os.environ.copy()
env['PATH'] = os.pathsep.join([
@@ -53,8 +68,9 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
call([python, '--version'], env=env)
# install pip & wheel
call([python, '-m', 'ensurepip', '--upgrade'], 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)
@@ -68,11 +84,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, python=python, pip=pip, project=abs_project_dir)
call(before_build_prepared, env=env, shell=True)
# build the wheel
call([pip, 'wheel', 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'):
@@ -95,9 +111,8 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
# 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)
abs_project_dir = os.path.abspath(project_dir)
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, python=python, pip=pip, project=abs_project_dir)
call(shlex.split(test_command_prepared), cwd=os.environ['HOME'], env=env)
# we're all done here; move it to output
shutil.move(delocated_wheel, output_dir)
+28 -2
View File
@@ -1,7 +1,7 @@
from fnmatch import fnmatch
def prepare_command(command, python, pip):
def prepare_command(command, python, pip, project):
'''
Preprocesses a command by expanding variables like {python} or {pip}.
@@ -10,7 +10,16 @@ def prepare_command(command, python, pip):
Python 3, the user could write `{python} setup.py test`. This command would expand
it out to python2 or python3 as appropriate.
'''
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):
@@ -22,3 +31,20 @@ class BuildSkipper(object):
def __repr__(self):
return 'BuildSkipper(%r)' % ' '.join(self.patterns)
# Taken from https://stackoverflow.com/a/107717
class Unbuffered(object):
def __init__(self, stream):
self.stream = stream
def write(self, data):
self.stream.write(data)
self.stream.flush()
def writelines(self, datas):
self.stream.writelines(datas)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
+10 -9
View File
@@ -7,13 +7,13 @@ except ImportError:
from collections import namedtuple
from glob import glob
from .util import prepare_command
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 = os.fdopen(sys.stdout.fileno(), 'w', 0)
sys.stdout = Unbuffered(sys.stdout)
# run_with_env is a cmd file that sets the right environment variables to
run_with_env = os.path.join(tempfile.gettempdir(), 'appveyor_run_with_env.cmd')
@@ -42,6 +42,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\Python36-x64'),
]
abs_project_dir = os.path.abspath(project_dir)
temp_dir = tempfile.mkdtemp(prefix='cibuildwheel')
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
@@ -71,17 +72,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, python='python', pip='pip', project=abs_project_dir)
shell([before_build_prepared], env=env)
# build the wheel
shell(['pip', 'wheel', 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
@@ -94,9 +96,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)
abs_project_dir = os.path.abspath(project_dir)
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, python='python', pip='pip', 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 -1
View File
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.5.0
current_version = 0.8.0
commit = True
tag = True
message = Bump version
+1 -1
View File
@@ -8,7 +8,7 @@ except ImportError:
setup(
name='cibuildwheel',
version='0.5.0',
version='0.8.0',
install_requires=['bashlex'],
description="Build Python wheels on CI with minimal configuration.",
long_description='For readme please see http://github.com/joerick/cibuildwheel',
+4
View File
@@ -0,0 +1,4 @@
{
"CIBW_MANYLINUX1_X86_64_IMAGE": "dockcross/manylinux-x64",
"CIBW_MANYLINUX1_I686_IMAGE": "dockcross/manylinux-x86"
}
+15
View File
@@ -0,0 +1,15 @@
import os, sys
from setuptools import setup, Extension
if sys.argv[-1] != '--name':
# check that we're running in the correct docker image as specified in the
# environment options CIBW_MANYLINUX1_*_IMAGE
if 'linux' in sys.platform and not os.path.exists('/dockcross'):
raise Exception('/dockcross directory not found. Is this test running in the correct docker image?')
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
+48
View File
@@ -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)
}