Merge pull request #101 from YannickJadoul/cibw-build

Adding CIBW_BUILD option
This commit is contained in:
Joe Rickerby
2018-09-23 21:31:42 +01:00
committed by GitHub
14 changed files with 113 additions and 44 deletions
+14 -10
View File
@@ -131,6 +131,7 @@ All being well, you should get wheels delivered to you in a few minutes.
| | Option | |
|---|---|---|
| **Target wheels** | `CIBW_PLATFORM` | Override the auto-detected target platform |
| | `CIBW_BUILD` | Build only certain Python versions |
| | `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 |
@@ -197,12 +198,14 @@ For `linux` you need Docker running, on Mac or Linux. For `macos`, you need a Ma
***
| Environment variable: `CIBW_SKIP`
| Environment variables: `CIBW_BUILD` and `CIBW_SKIP`
| ---
Optional.
Space-separated list of builds to skip. Each build has an identifier like `cp27-manylinux1_x86_64` or `cp34-macosx_10_6_intel` - you can list ones to skip here and `cibuildwheel` won't try to build them.
Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux1_x86_64` or `cp34-macosx_10_6_intel` - you can list specific ones to build and `cibuildwheel` will only build those, and/or list ones to skip and `cibuildwheel` won't try to build them.
When both options are specified, both conditions are applied and only builds with a tag that matches `CIBW_BUILD` and does not match `CIBW_SKIP` will be built.
The format is `python_tag-platform_tag`. The tags are as defined in [PEP 0425](https://www.python.org/dev/peps/pep-0425/#details).
@@ -213,15 +216,16 @@ Platform tags look like `macosx_10_6_intel` `manylinux1_x86_64` `manylinux1_i686
You can also use shell-style globbing syntax (as per `fnmatch`)
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-*`
- Only build on Python 3.6: `CIBW_BUILD`:`cp36-*`
- Skip building on Python 2.7 on the Mac: `CIBW_SKIP`:`cp27-macosx_10_6_intel`
- Skip building on Python 2.7 on all platforms: `CIBW_SKIP`:`cp27-*`
- Skip Python 2.7 on Windows: `CIBW_SKIP`:`cp27-win*`
- Skip Python 2.7 on 32-bit Windows: `CIBW_SKIP`:`cp27-win32`
- Skip Python 3.4 and Python 3.5: `CIBW_SKIP`:`cp34-* cp35-*`
- Skip Python 3.6 on Linux: `CIBW_SKIP`:`cp36-manylinux*`
- Only build on Python 3 and skip 32-bit builds: `CIBW_BUILD`:`cp3?-*` and `CIBW_SKIP`:`*-win32 *-manylinux1_i686`
***
**
| Environment variable: `CIBW_BUILD_VERBOSITY`
| ---
+1 -1
View File
@@ -22,7 +22,7 @@ def single_run(test_project):
print('%s built successfully. %i wheels built.' % (test_project, len(wheels)))
# check some wheels were actually built
assert len(wheels) >= 4
assert len(wheels) >= 3
# clean up
shutil.rmtree('wheelhouse')
+4 -4
View File
@@ -4,7 +4,7 @@ import argparse, os, subprocess, sys, textwrap
import cibuildwheel
import cibuildwheel.linux, cibuildwheel.windows, cibuildwheel.macos
from cibuildwheel.environment import parse_environment, EnvironmentParseError
from cibuildwheel.util import BuildSkipper, Unbuffered
from cibuildwheel.util import BuildSelector, Unbuffered
def get_option_from_environment(option_name, platform=None, default=None):
'''
@@ -83,7 +83,7 @@ def main():
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', '')
build_config, skip_config = os.environ.get('CIBW_BUILD', '*'), os.environ.get('CIBW_SKIP', '')
environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='')
try:
@@ -99,7 +99,7 @@ def main():
traceback.print_exc(None, sys.stderr)
exit(2)
skip = BuildSkipper(skip_config)
build_selector = BuildSelector(build_config, skip_config)
# Add CIBUILDWHEEL environment variable
# This needs to be passed on to the docker container in linux.py
@@ -134,7 +134,7 @@ def main():
test_requires=test_requires,
before_build=before_build,
build_verbosity=build_verbosity,
skip=skip,
build_selector=build_selector,
environment=environment,
)
+2 -2
View File
@@ -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, build_verbosity, skip, environment, manylinux1_images):
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment, manylinux1_images):
try:
subprocess.check_call(['docker', '--version'])
except:
@@ -36,7 +36,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
]
# skip builds as required
python_configurations = [c for c in python_configurations if not skip(c.identifier)]
python_configurations = [c for c in python_configurations if build_selector(c.identifier)]
platforms = [
('manylinux1_x86_64', manylinux1_images.get('x86_64') or 'quay.io/pypa/manylinux1_x86_64'),
+2 -2
View File
@@ -10,7 +10,7 @@ except ImportError:
from .util import prepare_command, get_build_verbosity_extra_flags
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, skip, environment):
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, 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.15/python-2.7.15-macosx10.6.pkg'),
@@ -42,7 +42,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
call(['curl', '-L', '-o', get_pip_script, get_pip_url])
for config in python_configurations:
if skip(config.identifier):
if not build_selector(config.identifier):
print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr)
continue
+8 -5
View File
@@ -21,15 +21,18 @@ def get_build_verbosity_extra_flags(level):
return []
class BuildSkipper(object):
def __init__(self, skip_config):
self.patterns = skip_config.split()
class BuildSelector(object):
def __init__(self, build_config, skip_config):
self.build_patterns = build_config.split()
self.skip_patterns = skip_config.split()
def __call__(self, build_id):
return any(fnmatch(build_id, pattern) for pattern in self.patterns)
def match_any(patterns):
return any(fnmatch(build_id, pattern) for pattern in patterns)
return match_any(self.build_patterns) and not match_any(self.skip_patterns)
def __repr__(self):
return 'BuildSkipper(%r)' % ' '.join(self.patterns)
return 'BuildSelector({!r} - {!r})'.format(' '.join(self.build_patterns), ' '.join(self.skip_patterns))
# Taken from https://stackoverflow.com/a/107717
+2 -2
View File
@@ -10,7 +10,7 @@ from glob import glob
from .util import prepare_command, get_build_verbosity_extra_flags
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, skip, environment):
def build(project_dir, package_name, output_dir, test_command, test_requires, before_build, build_verbosity, build_selector, environment):
# run_with_env is a cmd file that sets the right environment variables to
run_with_env = os.path.join(tempfile.gettempdir(), 'appveyor_run_with_env.cmd')
if not os.path.exists(run_with_env):
@@ -45,7 +45,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be
built_wheel_dir = os.path.join(temp_dir, 'built_wheel')
for config in python_configurations:
if skip(config.identifier):
if not build_selector(config.identifier):
print('cibuildwheel: Skipping build %s' % config.identifier, file=sys.stderr)
continue
+4
View File
@@ -0,0 +1,4 @@
{
"CIBW_BUILD": "cp3?-*",
"CIBW_SKIP": "cp34-*"
}
+15
View File
@@ -0,0 +1,15 @@
from setuptools import setup, Extension
import sys
if sys.argv[-1] != '--name':
# explode if run on Python 2.7 or Python 3.3 (these should be skipped)
if sys.version_info[0:2] == (2, 7):
raise Exception('Python 2.7 should not be built')
if sys.version_info[0:2] == (3, 4):
raise Exception('Python 3.4 should be skipped')
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
-3
View File
@@ -1,3 +0,0 @@
{
"CIBW_SKIP": "cp26-* cp33-*"
}
-15
View File
@@ -1,15 +0,0 @@
from setuptools import setup, Extension
import sys
if sys.argv[-1] != '--name':
# explode if run on Python 2.6 or Python 3.3 (these should be skipped)
if sys.version_info[0:2] == (2, 6):
raise Exception('Python 2.6 should be skipped')
if sys.version_info[0:2] == (3, 3):
raise Exception('Python 3.3 should be skipped')
setup(
name="spam",
ext_modules=[Extension('spam', sources=['spam.c'])],
version="0.1.0",
)
+61
View File
@@ -0,0 +1,61 @@
from cibuildwheel.util import BuildSelector
def test_build():
build_selector = BuildSelector(build_config="cp3?-* *-manylinux1*", skip_config="")
assert build_selector('cp27-manylinux1_x86_64')
assert build_selector('cp36-manylinux1_x86_64')
assert build_selector('cp37-manylinux1_x86_64')
assert build_selector('cp27-manylinux1_i686')
assert build_selector('cp36-manylinux1_i686')
assert build_selector('cp37-manylinux1_i686')
assert not build_selector('cp27-macosx_10_6_intel')
assert build_selector('cp36-macosx_10_6_intel')
assert build_selector('cp37-macosx_10_6_intel')
assert not build_selector('cp27-win32')
assert build_selector('cp36-win32')
assert build_selector('cp37-win32')
assert not build_selector('cp27-win_amd64')
assert build_selector('cp36-win_amd64')
assert build_selector('cp37-win_amd64')
def test_skip():
build_selector = BuildSelector(build_config="*", skip_config="cp27-* cp3?-manylinux1_i686 cp36-win* *-win32")
assert not build_selector('cp27-manylinux1_x86_64')
assert build_selector('cp36-manylinux1_x86_64')
assert build_selector('cp37-manylinux1_x86_64')
assert not build_selector('cp27-manylinux1_i686')
assert not build_selector('cp36-manylinux1_i686')
assert not build_selector('cp37-manylinux1_i686')
assert not build_selector('cp27-macosx_10_6_intel')
assert build_selector('cp36-macosx_10_6_intel')
assert build_selector('cp37-macosx_10_6_intel')
assert not build_selector('cp27-win32')
assert not build_selector('cp36-win32')
assert not build_selector('cp37-win32')
assert not build_selector('cp27-win_amd64')
assert not build_selector('cp36-win_amd64')
assert build_selector('cp37-win_amd64')
def test_build_and_skip():
build_selector = BuildSelector(build_config="cp36-* cp37-macosx* *-manylinux1*", skip_config="cp27-* cp37-manylinux1_i686")
assert not build_selector('cp27-manylinux1_x86_64')
assert build_selector('cp36-manylinux1_x86_64')
assert build_selector('cp37-manylinux1_x86_64')
assert not build_selector('cp27-manylinux1_i686')
assert build_selector('cp36-manylinux1_i686')
assert not build_selector('cp37-manylinux1_i686')
assert not build_selector('cp27-macosx_10_6_intel')
assert build_selector('cp36-macosx_10_6_intel')
assert build_selector('cp37-macosx_10_6_intel')
assert not build_selector('cp27-win32')
assert build_selector('cp36-win32')
assert not build_selector('cp37-win32')
assert not build_selector('cp27-win_amd64')
assert build_selector('cp36-win_amd64')
assert not build_selector('cp37-win_amd64')