From e194dad0da3962c0271de80c7cdc0a2dac751ea2 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Wed, 14 Aug 2019 18:29:15 +0200 Subject: [PATCH 01/22] Alternative proposal to generalize manylinux builds and support manylinux2010 --- cibuildwheel/__main__.py | 14 +++++++++++--- cibuildwheel/linux.py | 32 +++++++++++++++++--------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 516f0d69..68c3ff65 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -141,11 +141,19 @@ def main(): ) 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) + # TODO Check CIBW_MANYLINUX1_X86_64_IMAGE and CIBW_MANYLINUX1_I686_IMAGE environment variables and error if they exist + # TODO Check CIBW_BUILD and CIBW_SKIP for "manylinux1" and error if present + # TODO Add documentation on CIBW_ENVIRONMENT and possibility of AUDITWHEEL_PLAT if not defined by custom manylinux image + manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', '2010') + manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', '') + + default_manylinux_images_x86_64 = {'1': 'quay.io/pypa/manylinux1_x86_64', + '2010': 'quay.io/pypa/manylinux2010_x86_64'} + default_manylinux_images_i686 = {'1': 'quay.io/pypa/manylinux1_i686'} build_options.update( - manylinux1_images={'x86_64': manylinux1_x86_64_image, 'i686': manylinux1_i686_image}, + manylinux_images={'x86_64': default_manylinux_images_x86_64.get(manylinux_x86_64_image) or manylinux_x86_64_image, + 'i686': default_manylinux_images_i686.get(manylinux_i686_image) or manylinux_i686_image}, ) elif platform == 'macos': pass diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index ddcec627..c56a4472 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -12,25 +12,25 @@ except ImportError: def get_python_configurations(build_selector): PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path']) 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='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='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'), + PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'), + PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'), + PythonConfiguration(identifier='cp34-manylinux_x86_64', path='/opt/python/cp34-cp34m'), + PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'), + PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'), + PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'), + PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'), + PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'), + PythonConfiguration(identifier='cp34-manylinux_i686', path='/opt/python/cp34-cp34m'), + PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'), + PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'), + PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'), ] # skip builds as required return [c for c in python_configurations if build_selector(c.identifier)] -def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment, manylinux1_images): +def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment, manylinux_images): try: subprocess.check_call(['docker', '--version']) except: @@ -42,11 +42,13 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef python_configurations = get_python_configurations(build_selector) platforms = [ - ('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'), + ('manylinux_x86_64', manylinux_images['x86_64']), + ('manylinux_i686', manylinux_images['i686']), ] for platform_tag, docker_image in platforms: + if not docker_image: + continue platform_configs = [c for c in python_configurations if c.identifier.endswith(platform_tag)] if not platform_configs: continue From 7cadc6374a4d2bfe9f5bace433dd933735d0d223 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Wed, 14 Aug 2019 19:19:53 +0200 Subject: [PATCH 02/22] Fixing tests failing because of new manylinux2010 default --- test/shared/utils.py | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/test/shared/utils.py b/test/shared/utils.py index 0284dd4a..2fa3db1f 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -42,25 +42,35 @@ def cibuildwheel_run(project_path, env=None, add_env=None): ) -def expected_wheels(package_name, package_version): +def expected_wheels(package_name, package_version, manylinux_version='2010'): ''' Returns a list of expected wheels from a run of cibuildwheel. ''' if platform == 'linux': - templates = [ - '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', - ] + if manylinux_version == '2010': + templates = [ + '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl', + ] + elif manylinux_version == '1': + templates = [ + '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', + ] elif platform == 'windows': templates = [ '{package_name}-{package_version}-cp27-cp27m-win32.whl', From 7978247fa722def160641fb82aec745a1e769e69 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sat, 17 Aug 2019 23:43:30 +0200 Subject: [PATCH 03/22] Fixing tests still failing as manylinux1 wheels are also produced by auditwheel --- test/shared/utils.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/test/shared/utils.py b/test/shared/utils.py index 2fa3db1f..63f4c557 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -42,28 +42,23 @@ def cibuildwheel_run(project_path, env=None, add_env=None): ) -def expected_wheels(package_name, package_version, manylinux_version='2010'): +def expected_wheels(package_name, package_version, manylinux_versions={'1_x86_64', '2010_x86_64'}): ''' Returns a list of expected wheels from a run of cibuildwheel. ''' if platform == 'linux': - if manylinux_version == '2010': - templates = [ - '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp35-cp35m-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl', - ] - elif manylinux_version == '1': - templates = [ + templates = [] + if '1_x86_64' in manylinux_versions: + templates += [ '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp34-cp34m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', + ] + if '1_i686' in manylinux_versions: + templates += [ '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', @@ -71,6 +66,15 @@ def expected_wheels(package_name, package_version, manylinux_version='2010'): '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', ] + if '2010_x86_64' in manylinux_versions: + templates += [ + '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl', + ] elif platform == 'windows': templates = [ '{package_name}-{package_version}-cp27-cp27m-win32.whl', From 54dd72de6647ebeb62c88c2ad8aeab4dc2893430 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sat, 17 Aug 2019 23:49:35 +0200 Subject: [PATCH 04/22] Copying all created manylinux wheels to the output directory --- cibuildwheel/linux.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index c56a4472..d125ca69 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -120,7 +120,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef fi # we're all done here; move it to output - mv "$delocated_wheel" /output + mv "${{delocated_wheel[@]}}" /output chown {uid}:{gid} "/output/$(basename "$delocated_wheel")" done '''.format( From 27517cd8a085371c210e6b88141aae289603fd91 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Sun, 18 Aug 2019 00:42:35 +0200 Subject: [PATCH 05/22] Updating test 06_docker_images to use new CIBW_MANYLINUX_*_IMAGE options --- test/06_docker_images/cibuildwheel_test.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index a5448485..fda6ed49 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -8,11 +8,13 @@ def test(): pytest.skip('the docker test is only relevant to the linux build') utils.cibuildwheel_run(project_dir, add_env={ - 'CIBW_MANYLINUX1_X86_64_IMAGE': 'dockcross/manylinux-x64', - 'CIBW_MANYLINUX1_I686_IMAGE': 'dockcross/manylinux-x86', + 'CIBW_MANYLINUX_X86_64_IMAGE': 'dockcross/manylinux2010-x64', + 'CIBW_MANYLINUX_I686_IMAGE': 'dockcross/manylinux1-x86', + 'CIBW_BEFORE_BUILD': '/opt/python/cp36-cp36m/bin/pip install -U auditwheel', # Currently necessary on dockcross images to get auditwheel 2.1 supporting AUDITWHEEL_PLAT + 'CIBW_ENVIRONMENT': 'AUDITWHEEL_PLAT=`if [ $(uname -i) == "x86_64" ]; then echo "manylinux2010_x86_64"; else echo "manylinux1_i686"; fi`', }) # also check that we got the right wheels built - expected_wheels = utils.expected_wheels('spam', '0.1.0') + expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_versions={'1_x86_64', '2010_x86_64', '1_i686'}) actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) From 4571262803aea6744e69d30c020087003fd3d690 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Tue, 20 Aug 2019 17:43:45 +0200 Subject: [PATCH 06/22] Adapting Linux bash script for multiple output wheels from auditwheel --- cibuildwheel/linux.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index d125ca69..573a150c 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -64,9 +64,9 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef for PYBIN in {pybin_paths}; do # Setup rm -rf /tmp/built_wheel - rm -rf /tmp/delocated_wheel + rm -rf /tmp/delocated_wheels mkdir /tmp/built_wheel - mkdir /tmp/delocated_wheel + mkdir /tmp/delocated_wheels if [ ! -z {before_build} ]; then PATH="$PYBIN:$PATH" sh -c {before_build} @@ -81,11 +81,11 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef # the first element if [[ "$built_wheel" == *none-any.whl ]]; then # pure python wheel - just copy - mv "$built_wheel" /tmp/delocated_wheel + mv "$built_wheel" /tmp/delocated_wheels else - auditwheel repair "$built_wheel" -w /tmp/delocated_wheel + auditwheel repair "$built_wheel" -w /tmp/delocated_wheels fi - delocated_wheel=(/tmp/delocated_wheel/*.whl) + delocated_wheels=(/tmp/delocated_wheels/*.whl) if [ ! -z {test_command} ]; then # Set up a virtual environment to install and test from, to make sure @@ -102,7 +102,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef echo "Running tests using `which python`" # Install the wheel we just built - pip install "$delocated_wheel"{test_extras} + pip install "${{delocated_wheels[0]}}"{test_extras} # Install any requirements to run the tests if [ ! -z "{test_requires}" ]; then @@ -120,8 +120,8 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef fi # we're all done here; move it to output - mv "${{delocated_wheel[@]}}" /output - chown {uid}:{gid} "/output/$(basename "$delocated_wheel")" + mv "${{delocated_wheels[@]}}" /output + for delocated_wheel in "${{delocated_wheels[@]}}"; do chown {uid}:{gid} "/output/$(basename "$delocated_wheel")"; done done '''.format( pybin_paths=' '.join(c.path+'/bin' for c in platform_configs), From 4536b23a1d737d4e0c1ad4ab69b79a21c539381b Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Thu, 22 Aug 2019 15:06:03 +0200 Subject: [PATCH 07/22] Adding test accessing manylinux2010-only ABI --- .../cibuildwheel_test.py | 20 +++++++ test/08_manylinux2010_only/setup.py | 7 +++ test/08_manylinux2010_only/spam.c | 57 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 test/08_manylinux2010_only/cibuildwheel_test.py create mode 100644 test/08_manylinux2010_only/setup.py create mode 100644 test/08_manylinux2010_only/spam.c diff --git a/test/08_manylinux2010_only/cibuildwheel_test.py b/test/08_manylinux2010_only/cibuildwheel_test.py new file mode 100644 index 00000000..392ec459 --- /dev/null +++ b/test/08_manylinux2010_only/cibuildwheel_test.py @@ -0,0 +1,20 @@ +import os, pytest +import utils + +def test(): + project_dir = os.path.dirname(__file__) + + if utils.platform != 'linux': + pytest.skip('the docker test is only relevant to the linux build') + + # build the wheels + # CFLAGS environment veriable is ecessary to fail on 'malloc_info' (on manylinux1) during compilation/linking, + # rather than when dynamically loading the Python + utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_ENVIRONMENT': 'CFLAGS="$CFLAGS -Werror=implicit-function-declaration"', + }) + + # also check that we got the right wheels + expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_versions={'2010_x86_64'}) + actual_wheels = os.listdir('wheelhouse') + assert set(actual_wheels) == set(expected_wheels) diff --git a/test/08_manylinux2010_only/setup.py b/test/08_manylinux2010_only/setup.py new file mode 100644 index 00000000..866fa22c --- /dev/null +++ b/test/08_manylinux2010_only/setup.py @@ -0,0 +1,7 @@ +from setuptools import setup, Extension + +setup( + name="spam", + ext_modules=[Extension('spam', sources=['spam.c'])], + version="0.1.0", +) diff --git a/test/08_manylinux2010_only/spam.c b/test/08_manylinux2010_only/spam.c new file mode 100644 index 00000000..0e50eba9 --- /dev/null +++ b/test/08_manylinux2010_only/spam.c @@ -0,0 +1,57 @@ +#include +#if defined(__linux__) +#include +#endif + +static PyObject * +spam_system(PyObject *self, PyObject *args) +{ + const char *command; + int sts = 0; + + if (!PyArg_ParseTuple(args, "s", &command)) + return NULL; + +#if defined(__linux__) + sts = malloc_info(0, stdout); +#endif + if (sts == 0) { + 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) +} From 179148b0e528f56dce6b499a4432e26084f8c903 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Tue, 27 Aug 2019 16:03:09 +0200 Subject: [PATCH 08/22] Updated preset values for CIBW_MANYLINUX_*_IMAGE, fixed skip message in 08_manylinux2010_only test, and added clarifying comment on multiple wheels in Linux bash script --- cibuildwheel/__main__.py | 9 ++++++--- cibuildwheel/linux.py | 5 +++++ test/06_docker_images/cibuildwheel_test.py | 4 ++-- test/08_manylinux2010_only/cibuildwheel_test.py | 2 +- test/shared/utils.py | 8 ++++---- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 68c3ff65..0ad6b425 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -147,9 +147,12 @@ def main(): manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', '2010') manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', '') - default_manylinux_images_x86_64 = {'1': 'quay.io/pypa/manylinux1_x86_64', - '2010': 'quay.io/pypa/manylinux2010_x86_64'} - default_manylinux_images_i686 = {'1': 'quay.io/pypa/manylinux1_i686'} + manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', 'manylinux2010') + manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', '') + + default_manylinux_images_x86_64 = {'manylinux1': 'quay.io/pypa/manylinux1_x86_64', + 'manylinux2010': 'quay.io/pypa/manylinux2010_x86_64'} + default_manylinux_images_i686 = {'manylinux1': 'quay.io/pypa/manylinux1_i686'} build_options.update( manylinux_images={'x86_64': default_manylinux_images_x86_64.get(manylinux_x86_64_image) or manylinux_x86_64_image, diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 573a150c..84b16e48 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -102,6 +102,11 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef echo "Running tests using `which python`" # Install the wheel we just built + # Note: If auditwheel produced two wheels, it's because the earlier produced wheel + # conforms to multiple manylinux standards. These multiple versions of the wheel are + # functionally the same, differing only in name, wheel metadata, and possibly include + # different external shared libraries. so it doesn't matter which one we run the tests on. + # Let's just pick the first one. pip install "${{delocated_wheels[0]}}"{test_extras} # Install any requirements to run the tests diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index fda6ed49..c586151b 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -5,7 +5,7 @@ def test(): project_dir = os.path.dirname(__file__) if utils.platform != 'linux': - pytest.skip('the docker test is only relevant to the linux build') + pytest.skip('the test is only relevant to the linux build') utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_MANYLINUX_X86_64_IMAGE': 'dockcross/manylinux2010-x64', @@ -15,6 +15,6 @@ def test(): }) # also check that we got the right wheels built - expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_versions={'1_x86_64', '2010_x86_64', '1_i686'}) + expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_versions={'manylinux1_x86_64', 'manylinux2010_x86_64', 'manylinux1_i686'}) actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/08_manylinux2010_only/cibuildwheel_test.py b/test/08_manylinux2010_only/cibuildwheel_test.py index 392ec459..814a364b 100644 --- a/test/08_manylinux2010_only/cibuildwheel_test.py +++ b/test/08_manylinux2010_only/cibuildwheel_test.py @@ -15,6 +15,6 @@ def test(): }) # also check that we got the right wheels - expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_versions={'2010_x86_64'}) + expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_versions={'manylinux2010_x86_64'}) actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/shared/utils.py b/test/shared/utils.py index 63f4c557..d4ea60a5 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -42,13 +42,13 @@ def cibuildwheel_run(project_path, env=None, add_env=None): ) -def expected_wheels(package_name, package_version, manylinux_versions={'1_x86_64', '2010_x86_64'}): +def expected_wheels(package_name, package_version, manylinux_versions={'manylinux1_x86_64', 'manylinux2010_x86_64'}): ''' Returns a list of expected wheels from a run of cibuildwheel. ''' if platform == 'linux': templates = [] - if '1_x86_64' in manylinux_versions: + if 'manylinux1_x86_64' in manylinux_versions: templates += [ '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', @@ -57,7 +57,7 @@ def expected_wheels(package_name, package_version, manylinux_versions={'1_x86_64 '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', ] - if '1_i686' in manylinux_versions: + if 'manylinux1_i686' in manylinux_versions: templates += [ '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', @@ -66,7 +66,7 @@ def expected_wheels(package_name, package_version, manylinux_versions={'1_x86_64 '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', ] - if '2010_x86_64' in manylinux_versions: + if 'manylinux2010_x86_64' in manylinux_versions: templates += [ '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', From 1220fbbd4bb97faacdb123068ca69f33c3c317a5 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Fri, 30 Aug 2019 18:31:02 +0200 Subject: [PATCH 09/22] Adding detection of old CIBW_MANYLINUX1_*_IMAGE options and manylinux1-* build identifiers in CIBW_BUILD and CIBW_SKIP --- cibuildwheel/__main__.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 0ad6b425..8112629b 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -54,6 +54,8 @@ def main(): args = parser.parse_args() + detect_obsolete_options() + if args.platform != 'auto': platform = args.platform else: @@ -141,11 +143,7 @@ def main(): ) if platform == 'linux': - # TODO Check CIBW_MANYLINUX1_X86_64_IMAGE and CIBW_MANYLINUX1_I686_IMAGE environment variables and error if they exist - # TODO Check CIBW_BUILD and CIBW_SKIP for "manylinux1" and error if present # TODO Add documentation on CIBW_ENVIRONMENT and possibility of AUDITWHEEL_PLAT if not defined by custom manylinux image - manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', '2010') - manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', '') manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', 'manylinux2010') manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', '') @@ -181,6 +179,26 @@ def main(): raise Exception('Unsupported platform') +def detect_obsolete_options(): + # Check the old 'MANYLINUX1_*_IMAGE' options + for (deprecated, alternative) in [('CIBW_MANYLINUX1_X86_64_IMAGE', 'CIBW_MANYLINUX_X86_64_IMAGE'), + ('CIBW_MANYLINUX1_I686_IMAGE', 'CIBW_MANYLINUX_I686_IMAGE')]: + if deprecated in os.environ: + print("'{}' has been deprecated, and will be removed in a future release. Use the option '{}' instead.".format(deprecated, alternative)) + if alternative not in os.environ: + print("Using value of option '{}' as replacement for '{}'".format(deprecated, alternative)) + os.environ[alternative] = os.environ[deprecated] + else: + print("Option '{}' is not empty. Please unset '{}'".format(alternative, deprecated)) + exit(2) + + # Check for 'manylinux1' in the 'CIBW_BUILD' and 'CIBW_SKIP' options + for deprecated in ['CIBW_BUILD', 'CIBW_SKIP']: + if deprecated in os.environ and 'manylinux1' in os.environ[deprecated]: + print("Build identifiers with 'manylinux1' been deprecated. Replacing all occurences of 'manylinux1' by 'manylinux' in the option '{}'".format(deprecated)) + os.environ[deprecated] = os.environ[deprecated].replace('manylinux1', 'manylinux') + + def print_preamble(platform, build_options): print(textwrap.dedent(''' _ _ _ _ _ _ _ From c6f13828132fd250715dd6c816cda392ba66b19e Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Mon, 16 Sep 2019 12:48:15 +0200 Subject: [PATCH 10/22] Making manylinux1 still the default for manylinux_i686 builds --- cibuildwheel/__main__.py | 2 +- cibuildwheel/linux.py | 2 -- test/01_basic/cibuildwheel_test.py | 5 +++- test/06_docker_images/cibuildwheel_test.py | 2 +- .../cibuildwheel_test.py | 4 +++- test/shared/utils.py | 24 +++++++++---------- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 8112629b..fb79c9fb 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -146,7 +146,7 @@ def main(): # TODO Add documentation on CIBW_ENVIRONMENT and possibility of AUDITWHEEL_PLAT if not defined by custom manylinux image manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', 'manylinux2010') - manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', '') + manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', 'manylinux1') default_manylinux_images_x86_64 = {'manylinux1': 'quay.io/pypa/manylinux1_x86_64', 'manylinux2010': 'quay.io/pypa/manylinux2010_x86_64'} diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 84b16e48..233f1f02 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -47,8 +47,6 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef ] for platform_tag, docker_image in platforms: - if not docker_image: - continue platform_configs = [c for c in python_configurations if c.identifier.endswith(platform_tag)] if not platform_configs: continue diff --git a/test/01_basic/cibuildwheel_test.py b/test/01_basic/cibuildwheel_test.py index 93c67829..32da2c6f 100644 --- a/test/01_basic/cibuildwheel_test.py +++ b/test/01_basic/cibuildwheel_test.py @@ -17,6 +17,9 @@ def test(): def test_build_identifiers(): # check that the number of expected wheels matches the number of build # identifiers - expected_wheels = utils.expected_wheels('spam', '0.1.0') + # after adding CIBW_MANYLINUX_IMAGE to support manylinux2010, there + # can be multiple wheels for each wheel, though, so we need to limit + # the expected wheels + expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_x86_64_versions={'manylinux2010'}, manylinux_i686_versions={'manylinux1'}) build_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) assert len(expected_wheels) == len(build_identifiers) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index c586151b..f1ef516c 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -15,6 +15,6 @@ def test(): }) # also check that we got the right wheels built - expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_versions={'manylinux1_x86_64', 'manylinux2010_x86_64', 'manylinux1_i686'}) + expected_wheels = utils.expected_wheels('spam', '0.1.0') actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/08_manylinux2010_only/cibuildwheel_test.py b/test/08_manylinux2010_only/cibuildwheel_test.py index 814a364b..203e1fbe 100644 --- a/test/08_manylinux2010_only/cibuildwheel_test.py +++ b/test/08_manylinux2010_only/cibuildwheel_test.py @@ -12,9 +12,11 @@ def test(): # rather than when dynamically loading the Python utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_ENVIRONMENT': 'CFLAGS="$CFLAGS -Werror=implicit-function-declaration"', + 'CIBW_SKIP': '*-manylinux_i686', }) # also check that we got the right wheels - expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_versions={'manylinux2010_x86_64'}) + expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0', manylinux_x86_64_versions={'manylinux2010'}) + if '-manylinux1_i686' not in w] actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/shared/utils.py b/test/shared/utils.py index d4ea60a5..3edba2ee 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -42,13 +42,13 @@ def cibuildwheel_run(project_path, env=None, add_env=None): ) -def expected_wheels(package_name, package_version, manylinux_versions={'manylinux1_x86_64', 'manylinux2010_x86_64'}): +def expected_wheels(package_name, package_version, manylinux_x86_64_versions={'manylinux1', 'manylinux2010'}, manylinux_i686_versions={'manylinux1'}): ''' Returns a list of expected wheels from a run of cibuildwheel. ''' if platform == 'linux': templates = [] - if 'manylinux1_x86_64' in manylinux_versions: + if 'manylinux1' in manylinux_x86_64_versions: templates += [ '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', @@ -57,16 +57,7 @@ def expected_wheels(package_name, package_version, manylinux_versions={'manylinu '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', ] - if 'manylinux1_i686' in manylinux_versions: - templates += [ - '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', - ] - if 'manylinux2010_x86_64' in manylinux_versions: + if 'manylinux2010' in manylinux_x86_64_versions: templates += [ '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', @@ -75,6 +66,15 @@ def expected_wheels(package_name, package_version, manylinux_versions={'manylinu '{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl', ] + if 'manylinux1' in manylinux_i686_versions: + templates += [ + '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', + ] elif platform == 'windows': templates = [ '{package_name}-{package_version}-cp27-cp27m-win32.whl', From 2e0dc40e3f15dcf18f81df9673c6492826cdc415 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Wed, 16 Oct 2019 00:30:17 +0200 Subject: [PATCH 11/22] Adding manylinux2010_i686 image and simplifying tests' utils.expected_wheels() --- cibuildwheel/__main__.py | 5 +- test/01_basic/cibuildwheel_test.py | 3 +- test/06_docker_images/cibuildwheel_test.py | 3 +- .../cibuildwheel_test.py | 5 +- test/shared/utils.py | 56 +++++++++---------- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index fb79c9fb..fd68da10 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -146,11 +146,12 @@ def main(): # TODO Add documentation on CIBW_ENVIRONMENT and possibility of AUDITWHEEL_PLAT if not defined by custom manylinux image manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', 'manylinux2010') - manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', 'manylinux1') + manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', 'manylinux2010') default_manylinux_images_x86_64 = {'manylinux1': 'quay.io/pypa/manylinux1_x86_64', 'manylinux2010': 'quay.io/pypa/manylinux2010_x86_64'} - default_manylinux_images_i686 = {'manylinux1': 'quay.io/pypa/manylinux1_i686'} + default_manylinux_images_i686 = {'manylinux1': 'quay.io/pypa/manylinux1_i686', + 'manylinux2010': 'quay.io/pypa/manylinux2010_i686'} build_options.update( manylinux_images={'x86_64': default_manylinux_images_x86_64.get(manylinux_x86_64_image) or manylinux_x86_64_image, diff --git a/test/01_basic/cibuildwheel_test.py b/test/01_basic/cibuildwheel_test.py index 32da2c6f..998b55de 100644 --- a/test/01_basic/cibuildwheel_test.py +++ b/test/01_basic/cibuildwheel_test.py @@ -20,6 +20,7 @@ def test_build_identifiers(): # after adding CIBW_MANYLINUX_IMAGE to support manylinux2010, there # can be multiple wheels for each wheel, though, so we need to limit # the expected wheels - expected_wheels = utils.expected_wheels('spam', '0.1.0', manylinux_x86_64_versions={'manylinux2010'}, manylinux_i686_versions={'manylinux1'}) + expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') + if not '-manylinux' in w or '-manylinux1' in w] build_identifiers = utils.cibuildwheel_get_build_identifiers(project_dir) assert len(expected_wheels) == len(build_identifiers) diff --git a/test/06_docker_images/cibuildwheel_test.py b/test/06_docker_images/cibuildwheel_test.py index f1ef516c..9067bc0f 100644 --- a/test/06_docker_images/cibuildwheel_test.py +++ b/test/06_docker_images/cibuildwheel_test.py @@ -15,6 +15,7 @@ def test(): }) # also check that we got the right wheels built - expected_wheels = utils.expected_wheels('spam', '0.1.0') + expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') + if '-manylinux2010_i686' not in w] actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/08_manylinux2010_only/cibuildwheel_test.py b/test/08_manylinux2010_only/cibuildwheel_test.py index 203e1fbe..dab763e7 100644 --- a/test/08_manylinux2010_only/cibuildwheel_test.py +++ b/test/08_manylinux2010_only/cibuildwheel_test.py @@ -12,11 +12,10 @@ def test(): # rather than when dynamically loading the Python utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_ENVIRONMENT': 'CFLAGS="$CFLAGS -Werror=implicit-function-declaration"', - 'CIBW_SKIP': '*-manylinux_i686', }) # also check that we got the right wheels - expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0', manylinux_x86_64_versions={'manylinux2010'}) - if '-manylinux1_i686' not in w] + expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') + if not '-manylinux' in w or '-manylinux2010' in w] actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/shared/utils.py b/test/shared/utils.py index 3edba2ee..86cb198a 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -42,39 +42,37 @@ def cibuildwheel_run(project_path, env=None, add_env=None): ) -def expected_wheels(package_name, package_version, manylinux_x86_64_versions={'manylinux1', 'manylinux2010'}, manylinux_i686_versions={'manylinux1'}): +def expected_wheels(package_name, package_version): ''' Returns a list of expected wheels from a run of cibuildwheel. ''' if platform == 'linux': - templates = [] - if 'manylinux1' in manylinux_x86_64_versions: - templates += [ - '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', - ] - if 'manylinux2010' in manylinux_x86_64_versions: - templates += [ - '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp35-cp35m-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl', - ] - if 'manylinux1' in manylinux_i686_versions: - templates += [ - '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', - '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', - ] + templates = [ + '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp27-cp27m-manylinux2010_i686.whl', + '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_i686.whl', + '{package_name}-{package_version}-cp34-cp34m-manylinux2010_i686.whl', + '{package_name}-{package_version}-cp35-cp35m-manylinux2010_i686.whl', + '{package_name}-{package_version}-cp36-cp36m-manylinux2010_i686.whl', + '{package_name}-{package_version}-cp37-cp37m-manylinux2010_i686.whl', + ] elif platform == 'windows': templates = [ '{package_name}-{package_version}-cp27-cp27m-win32.whl', From 31d89377dad77ef07de1a9b8fb8accddc47c35e5 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Wed, 16 Oct 2019 01:26:15 +0200 Subject: [PATCH 12/22] Updated README with new CIBW_MANYLINUX_*_IMAGE options --- README.md | 31 +++++++++++++++++++------------ cibuildwheel/__main__.py | 2 -- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index cec3816e..c14b3ad3 100644 --- a/README.md +++ b/README.md @@ -221,8 +221,8 @@ All being well, you should get wheels delivered to you in a few minutes. | **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 | +| | `CIBW_MANYLINUX_X86_64_IMAGE` | Specify an alternative manylinux x86_64 docker image | +| | `CIBW_MANYLINUX_I686_IMAGE` | Specify an alternative manylinux 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 | | | `CIBW_TEST_EXTRAS` | Install Python dependencies before running the tests using ``extras_require``| @@ -231,10 +231,10 @@ A more detailed description of the options, the allowed values, and some example ### 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: +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 [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. Note that this is not available on CircleCI due to their Docker policies. -- 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. +- Alternative dockers images can be specified with the `CIBW_MANYLINUX_X86_64_IMAGE` and `CIBW_MANYLINUX_I686_IMAGE` options to allow for a custom, preconfigured build environment for the Linux builds. See [below](#options) for more details. Options @@ -291,17 +291,19 @@ For `linux` you need Docker running, on Mac or Linux. For `macos`, you need a Ma Optional. -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. +Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux_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). +The format is `python_tag-platform_tag`. The tags are similar but not identical to the ones defined in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details). 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` +Platform tags look like `macosx_10_6_intel` `manylinux_x86_64` `manylinux_i686` `win32` `win_amd64` -You can also use shell-style globbing syntax (as per `fnmatch`) +You can also use shell-style globbing syntax (as per `fnmatch`). + +The list of supported and currently selected build identifiers can be retrieved by passing the `--print-build-identifiers` flag to `cibuildwheel`. Examples: - Only build on Python 3.6: `CIBW_BUILD`:`cp36-*` @@ -311,7 +313,7 @@ Examples: - 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` +- Only build on Python 3 and skip 32-bit builds: `CIBW_BUILD`:`cp3?-*` and `CIBW_SKIP`:`*-win32 *-manylinux_i686` *** @@ -370,15 +372,20 @@ Platform-specific variants also available: *** -| Environment variables: `CIBW_MANYLINUX1_X86_64_IMAGE` and `CIBW_MANYLINUX1_I686_IMAGE` +| Environment variables: `CIBW_MANYLINUX_X86_64_IMAGE` and `CIBW_MANYLINUX_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). +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) and [`quay.io/pypa/manylinux2010_i686`](https://quay.io/pypa/manylinux2010_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). +The value of this option can either be set to `manylinux1` or `manylinux2010` to use the [official `manylinux` images](https://github.com/pypa/manylinux), or any other valid Docker image name. +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- or manylinux2010-compatible in order to produce valid `manylinux1`/`manylinux2010` wheels (see https://github.com/pypa/manylinux, [PEP 513](https://www.python.org/dev/peps/pep-0513/), and [PEP 571](https://www.python.org/dev/peps/pep-0571/) for more details). + +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="manylinux2010_$(uname -m)"`). + +Example: `manylinux1` Example: `dockcross/manylinux-x64` Example: `dockcross/manylinux-x86` diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index fd68da10..847b608a 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -143,8 +143,6 @@ def main(): ) if platform == 'linux': - # TODO Add documentation on CIBW_ENVIRONMENT and possibility of AUDITWHEEL_PLAT if not defined by custom manylinux image - manylinux_x86_64_image = os.environ.get('CIBW_MANYLINUX_X86_64_IMAGE', 'manylinux2010') manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', 'manylinux2010') From bbecbe43ec58aed84c57872c0228b0a00301ae4c Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Sun, 20 Oct 2019 20:45:25 +0100 Subject: [PATCH 13/22] Add failing test check --- test/02_test/cibuildwheel_test.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/02_test/cibuildwheel_test.py b/test/02_test/cibuildwheel_test.py index 54973573..99324e87 100644 --- a/test/02_test/cibuildwheel_test.py +++ b/test/02_test/cibuildwheel_test.py @@ -1,4 +1,5 @@ -import os +import os, subprocess +import pytest import utils def test(): @@ -35,3 +36,16 @@ def test_extras_require(): expected_wheels = utils.expected_wheels('spam', '0.1.0') actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) + + +def test_failing_test(): + '''Ensure a failing test causes cibuildwheel to error out and exit''' + project_dir = os.path.dirname(__file__) + + with pytest.raises(subprocess.CalledProcessError): + utils.cibuildwheel_run(project_dir, add_env={ + 'CIBW_TEST_COMMAND': 'false', + }) + + assert len(os.listdir('wheelhouse')) + From 80974e5b39b3158bb0676a9d6f038b9daf4ad788 Mon Sep 17 00:00:00 2001 From: Grzegorz Bokota Date: Wed, 23 Oct 2019 22:53:10 +0200 Subject: [PATCH 14/22] Build Python wheels for windows on travis (#160) * upgrade for windows on travis * Install python on travis windows, update readme, update tests * update readme, travis config and clean code * install python inside cibuildwheel run * use register to get python path * fixes from review * fix pip version * use nuget for instal python * clean code * Update cibuildwheel/windows.py Co-Authored-By: Joe Rickerby * fixes from review * Final bits of tidy up --- .travis.yml | 9 +++++ README.md | 25 ++++++++++--- cibuildwheel/__main__.py | 2 ++ cibuildwheel/windows.py | 78 +++++++++++++++++++++++++++++++--------- test/shared/utils.py | 8 +++-- 5 files changed, 98 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index a38e2362..e96e532c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,6 +27,15 @@ matrix: - brew update - brew outdated python || brew upgrade python + - os: windows + language: shell + before_install: + - choco install python3 --version 3.6.8 --no-progress -y + install: + - C:\\Python36\\python -m pip install -r requirements-dev.txt + script: + - C:\\Python36\\python ./bin/run_tests.py + install: $PYTHON -m pip install -r requirements-dev.txt script: $PYTHON ./bin/run_tests.py diff --git a/README.md b/README.md index c14b3ad3..7016ae4c 100644 --- a/README.md +++ b/README.md @@ -14,13 +14,15 @@ What does it do? | | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit | |---|---|---|---|---|---| -| Python 2.7 | ✅ | ✅ | ✅ | ✅ | ✅ | -| Python 3.4 | ✅ | ✅ | ✅ | ✅* | ✅* | +| Python 2.7 | ✅ | ✅ | ✅ | ✅² | ✅² | +| Python 3.4 | ✅ | ✅ | ✅ | ✅¹²| ✅¹²| | Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ | | Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ | | Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ | -> \* Not supported on Azure Pipelines +> ¹ Not supported on Azure Pipelines +> +> ² Not supported on Travis - Builds manylinux, macOS and Windows (32 and 64bit) wheels using Azure Pipelines, Travis CI, AppVeyor, and CircleCI - Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate) @@ -34,7 +36,7 @@ Usage | | Linux | macOS | Windows | |-----------------|-------|-------|---------| | Azure Pipelines | ✅ | ✅ | ✅ | -| Travis CI | ✅ | ✅ | | +| Travis CI | ✅ | ✅ | ✅ | | AppVeyor | | | ✅ | | CircleCI | ✅ | ✅ | | @@ -101,11 +103,12 @@ jobs: Travis CI + - To build Linux and Mac wheels on Travis CI, create a `.travis.yml` file in your repo. - ``` + ```yaml language: python matrix: @@ -123,6 +126,18 @@ jobs: - cibuildwheel --output-dir wheelhouse ``` + To build on Windows too, add this matrix entry: + ```yaml + - os: windows + language: shell + before_install: + - choco install python3 --version 3.6.8 --no-progress -y + env: + - PATH=/c/Python36:/c/Python36/Scripts:$PATH + ``` + + Note that building Windows Python 2.7 wheels on Travis is unsupported. + Then setup a deployment method by following the [Travis CI deployment docs](https://docs.travis-ci.com/user/deployment/), or see [Delivering to PyPI](#delivering-to-pypi) below. diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 847b608a..67d90827 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -65,6 +65,8 @@ def main(): platform = 'linux' elif os.environ.get('TRAVIS_OS_NAME') == 'osx': platform = 'macos' + elif os.environ.get('TRAVIS_OS_NAME') == 'windows': + platform = 'windows' elif 'APPVEYOR' in os.environ: platform = 'windows' elif 'BITRISE_BUILD_NUMBER' in os.environ: diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index a25dab69..da929bcc 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -1,12 +1,18 @@ from __future__ import print_function -import os, tempfile, subprocess, shutil +import os, tempfile, subprocess, shutil, sys from collections import namedtuple from glob import glob +try: + from shlex import quote as shlex_quote +except ImportError: + from pipes import quote as shlex_quote + from .util import prepare_command, get_build_verbosity_extra_flags IS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache') +IS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows' def get_python_path(config): if IS_RUNNING_ON_AZURE: @@ -22,6 +28,12 @@ def get_python_path(config): return glob(path_pattern)[0] except IndexError: raise Exception('Could not find a Python install at ' + path_pattern) + elif IS_RUNNING_ON_TRAVIS: + if config.version == "3.4.x": + return config.path + else: + nuget_args = get_nuget_args(config) + return os.path.join(nuget_args[-1], nuget_args[0] + "." + config.nuget_version, "tools") else: # Assume we're running on AppVeyor major, minor = config.version.split('.')[:2] @@ -32,32 +44,49 @@ def get_python_path(config): ) +def get_nuget_args(configuration): + if configuration.nuget_version is None: + return None + python_name = "python" if configuration.version[0] == '3' else "python2" + if configuration.arch == "32": + python_name = python_name + "x86" + return [python_name, "-Version", configuration.nuget_version, "-OutputDirectory", "C:/python"] + def get_python_configurations(build_selector): - PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path']) + PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path', "nuget_version"]) python_configurations = [ - PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\Python27'), - PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\Python27-x64'), - PythonConfiguration(version='3.4.x', arch="32", identifier='cp34-win32', path='C:\Python34'), - PythonConfiguration(version='3.4.x', arch="64", identifier='cp34-win_amd64', path='C:\Python34-x64'), - PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\Python35'), - 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'), + PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\\Python27', nuget_version="2.7.16"), + PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\\Python27-x64', nuget_version="2.7.16"), + PythonConfiguration(version='3.4.x', arch="32", identifier='cp34-win32', path='C:\\Python34', nuget_version=None), + PythonConfiguration(version='3.4.x', arch="64", identifier='cp34-win_amd64', path='C:\\Python34-x64', nuget_version=None), + PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\\Python35', nuget_version="3.5.4"), + PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\\Python35-x64', nuget_version="3.5.4"), + PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\\Python36', nuget_version="3.6.8"), + PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\\Python36-x64', nuget_version="3.6.8"), + PythonConfiguration(version='3.7.x', arch="32", identifier='cp37-win32', path='C:\\Python37', nuget_version="3.7.4"), + PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\\Python37-x64', nuget_version="3.7.4") ] if IS_RUNNING_ON_AZURE: # Python 3.4 isn't supported on Azure. # See https://github.com/Microsoft/azure-pipelines-tasks/issues/9674 python_configurations = [c for c in python_configurations if c.version != '3.4.x'] + + if IS_RUNNING_ON_TRAVIS: + # cannot install VCForPython27.msi which is needed for compiling C software + # try with (and similar): msiexec /i VCForPython27.msi ALLUSERS=1 ACCEPT=YES /passive + # no easy and stable way fo installing python 3.4 + python_configurations = [c for c in python_configurations if c.version != '2.7.x' and c.version != '3.4.x'] + + # skip builds as required + python_configurations = [c for c in python_configurations if build_selector(c.identifier)] + + return python_configurations - # skip builds as required - return [c for c in python_configurations if build_selector(c.identifier)] def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment): - if IS_RUNNING_ON_AZURE: + if IS_RUNNING_ON_AZURE or IS_RUNNING_ON_TRAVIS: def shell(args, env=None, cwd=None): print('+ ' + ' '.join(args)) args = ['cmd', '/E:ON', '/V:ON', '/C'] + args @@ -77,10 +106,21 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef temp_dir = tempfile.mkdtemp(prefix='cibuildwheel') built_wheel_dir = os.path.join(temp_dir, 'built_wheel') - python_configurations = get_python_configurations(build_selector) + if IS_RUNNING_ON_TRAVIS: + # instal nuget as best way for provide python + shell(["choco", "install", "nuget.commandline"]) + # get pip fo this installation which not have. + get_pip_url = 'https://bootstrap.pypa.io/get-pip.py' + get_pip_script = 'C:\\get-pip.py' + shell(['curl', '-L', '-o', get_pip_script, get_pip_url]) + python_configurations = get_python_configurations(build_selector) for config in python_configurations: config_python_path = get_python_path(config) + if IS_RUNNING_ON_TRAVIS and config.nuget_version is not None and not os.path.exists(config_python_path): + shell(["nuget", "install"] + get_nuget_args(config)) + if not os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe')): + shell([os.path.join(config_python_path, 'python.exe'), get_pip_script ]) # check python & pip exist for this configuration assert os.path.exists(os.path.join(config_python_path, 'python.exe')) @@ -107,8 +147,12 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef shell(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)\"'], env=env) # prepare the Python environment - shell(['python', '-m', 'pip', 'install', '--upgrade', 'pip'], + if config.version == "3.4.x": + shell(['python', '-m', 'pip', 'install', 'pip==19.1.1'], env=env) + else: + shell(['python', '-m', 'pip', 'install', '--upgrade', 'pip'], + env=env) shell(['pip', 'install', '--upgrade', 'setuptools'], env=env) shell(['pip', 'install', 'wheel'], env=env) diff --git a/test/shared/utils.py b/test/shared/utils.py index 86cb198a..78f09050 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -6,7 +6,8 @@ This file is added to the PYTHONPATH in the test runner at bin/run_test.py. import subprocess, sys, os -IS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache') +IS_WINDOWS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache') +IS_WINDOWS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows' def cibuildwheel_get_build_identifiers(project_path, env=None): @@ -97,9 +98,12 @@ def expected_wheels(package_name, package_version): else: raise Exception('unsupported platform') - if IS_RUNNING_ON_AZURE: + if IS_WINDOWS_RUNNING_ON_AZURE: # Python 3.4 isn't supported on Azure. templates = [t for t in templates if '-cp34-' not in t] + if IS_WINDOWS_RUNNING_ON_TRAVIS: + # Python 2.7 and 3.4 isn't supported on Travis. + templates = [t for t in templates if '-cp27-' not in t and '-cp34-' not in t] return [filename.format(package_name=package_name, package_version=package_version) for filename in templates] From 5eab3620c9ad953922a8962f521be1ee8c0b1e87 Mon Sep 17 00:00:00 2001 From: mayeut Date: Tue, 15 Oct 2019 21:40:00 +0200 Subject: [PATCH 15/22] Update CPython 2.7 from 2.7.16 to 2.7.17 & 3.7 from 3.7.4 to 3.7.5 on macOS --- cibuildwheel/macos.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 2709cc1a..7378f142 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -14,11 +14,11 @@ from .util import prepare_command, get_build_verbosity_extra_flags def get_python_configurations(build_selector): 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.16/python-2.7.16-macosx10.6.pkg'), + PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.17/python-2.7.17-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.8/python-3.6.8-macosx10.6.pkg'), - PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.4/python-3.7.4-macosx10.6.pkg'), + PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.5/python-3.7.5-macosx10.6.pkg'), ] # skip builds as required @@ -152,7 +152,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef # and not the repo code) test_command_prepared = prepare_command(test_command, project=abs_project_dir) call(test_command_prepared, cwd=os.environ['HOME'], env=virtualenv_env, shell=True) - + # clean up shutil.rmtree(venv_dir) From 8c9345fa1f5cef0a3c2842f5e2da18b774325d57 Mon Sep 17 00:00:00 2001 From: Yannick Jadoul Date: Thu, 24 Oct 2019 14:00:28 +0200 Subject: [PATCH 16/22] Updated line of README mistakenly claiming Windows is not supported on Travis CI --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7016ae4c..6cbf21b3 100644 --- a/README.md +++ b/README.md @@ -31,12 +31,12 @@ What does it do? Usage ----- -`cibuildwheel` currently works **Travis CI** and **CircleCI** to build Linux and Mac wheels, and **AppVeyor** to build Windows wheels. **Azure Pipelines** supports all three. +`cibuildwheel` currently works on **Travis CI** and **Azure Pipelines** to build wheels for all three supported platforms (Linux, macOS, Windows). On **CircleCI** Linux and macOS wheels can be built, and on **AppVeyor** Windows is supported. | | Linux | macOS | Windows | |-----------------|-------|-------|---------| | Azure Pipelines | ✅ | ✅ | ✅ | -| Travis CI | ✅ | ✅ | ✅ | +| Travis CI | ✅ | ✅ | ✅ | | AppVeyor | | | ✅ | | CircleCI | ✅ | ✅ | | From 892c7b4d9c1b204ea1b17def5f3dc253c8d5ba3f Mon Sep 17 00:00:00 2001 From: mayeut Date: Sat, 26 Oct 2019 14:44:42 +0200 Subject: [PATCH 17/22] Update .travis.yml --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e96e532c..a4cb2b79 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,9 +23,6 @@ matrix: # macOS Python 3 - os: osx env: PYTHON=python3 - before_install: - - brew update - - brew outdated python || brew upgrade python - os: windows language: shell From bb0cad404bbf3a032e52863717a8426875e55979 Mon Sep 17 00:00:00 2001 From: mayeut Date: Sat, 28 Sep 2019 19:24:16 +0200 Subject: [PATCH 18/22] Drop python 3.4 Python 3.4 reached the end of its life on 16 March 2019. It's about time to drop support for Python 3.4. --- .travis.yml | 2 +- README.md | 69 ++++++++++++------------- cibuildwheel/linux.py | 2 - cibuildwheel/macos.py | 3 +- cibuildwheel/windows.py | 14 ++--- test/04_build_skip/cibuildwheel_test.py | 6 +-- test/shared/utils.py | 22 +++----- 7 files changed, 47 insertions(+), 71 deletions(-) diff --git a/.travis.yml b/.travis.yml index a4cb2b79..8ddfbf0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ matrix: # Linux Python 3 - sudo: required language: python - python: 3.4 + python: 3.5 services: docker env: PYTHON=python diff --git a/README.md b/README.md index 6cbf21b3..64266b0c 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,12 @@ What does it do? | | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit | |---|---|---|---|---|---| -| Python 2.7 | ✅ | ✅ | ✅ | ✅² | ✅² | -| Python 3.4 | ✅ | ✅ | ✅ | ✅¹²| ✅¹²| +| Python 2.7 | ✅ | ✅ | ✅ | ✅¹ | ✅¹ | | Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ | | Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ | | Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ | -> ¹ Not supported on Azure Pipelines -> -> ² Not supported on Travis +> ¹ Not supported on Travis - Builds manylinux, macOS and Windows (32 and 64bit) wheels using Azure Pipelines, Travis CI, AppVeyor, and CircleCI - Bundles shared library dependencies on Linux and macOS through [auditwheel](https://github.com/pypa/auditwheel) and [delocate](https://github.com/matthew-brett/delocate) @@ -58,7 +55,7 @@ Usage jobs: - job: linux pool: {vmImage: 'Ubuntu-16.04'} - steps: + steps: - task: UsePythonVersion@0 - bash: | python -m pip install --upgrade pip @@ -68,7 +65,7 @@ jobs: inputs: {pathtoPublish: 'wheelhouse'} - job: macos pool: {vmImage: 'macOS-10.13'} - steps: + steps: - task: UsePythonVersion@0 - bash: | python -m pip install --upgrade pip @@ -78,7 +75,7 @@ jobs: inputs: {pathtoPublish: 'wheelhouse'} - job: windows pool: {vmImage: 'vs2017-win2016'} - steps: + steps: - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x86}} - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x64}} - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x86}} @@ -110,7 +107,7 @@ jobs: ```yaml language: python - + matrix: include: - sudo: required @@ -126,7 +123,7 @@ jobs: - cibuildwheel --output-dir wheelhouse ``` - To build on Windows too, add this matrix entry: + To build on Windows too, add this matrix entry: ```yaml - os: windows language: shell @@ -147,7 +144,7 @@ jobs: - + - To build Linux and Mac wheels on CircleCI, create a `.circleci/config.yml` file in your repo, ``` @@ -213,14 +210,14 @@ jobs: - path: "wheelhouse\\*.whl" name: Wheels ``` - + AppVeyor will store the built wheels for you - you can access them from the project console. Alternatively, you may want to store them in the same place as the Travis CI build. See [AppVeyor deployment docs](https://www.appveyor.com/docs/deployment/) for more info, or see [Delivering to PyPI](#delivering-to-pypi) below. - + - Commit those files, enable building of your repo on Travis CI and AppVeyor, and push. -All being well, you should get wheels delivered to you in a few minutes. +All being well, you should get wheels delivered to you in a few minutes. > ⚠️ Got an error? Check the [checklist](#it-didnt-work) below. @@ -259,7 +256,7 @@ Options usage: cibuildwheel [-h] [--platform {auto,linux,macos,windows}] [--output-dir OUTPUT_DIR] [--print-build-identifiers] [project_dir] - + Build wheels for all the platforms. positional arguments: @@ -306,13 +303,13 @@ For `linux` you need Docker running, on Mac or Linux. For `macos`, you need a Ma Optional. -Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux_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. +Space-separated list of builds to build and skip. Each build has an identifier like `cp27-manylinux_x86_64` or `cp35-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 similar but not identical to the ones defined in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details). -Python tags look like `cp27` `cp34` `cp35` `cp36` `cp37` +Python tags look like `cp27` `cp35` `cp36` `cp37` Platform tags look like `macosx_10_6_intel` `manylinux_x86_64` `manylinux_i686` `win32` `win_amd64` @@ -326,7 +323,7 @@ Examples: - 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 2.7 and Python 3.5: `CIBW_SKIP`:`cp27-* 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 *-manylinux_i686` @@ -355,10 +352,10 @@ You must set this variable to pass variables to Linux builds (since they execute You can use `$PATH` syntax to insert other variables, or the `$(pwd)` syntax to insert the output of other shell commands. -Example: `CFLAGS="-g -Wall" CXXFLAGS="-Wall"` -Example: `PATH=$PATH:/usr/local/bin` -Example: `BUILD_TIME="$(date)"` -Example: `PIP_EXTRA_INDEX_URL="https://pypi.myorg.com/simple"` +Example: `CFLAGS="-g -Wall" CXXFLAGS="-Wall"` +Example: `PATH=$PATH:/usr/local/bin` +Example: `BUILD_TIME="$(date)"` +Example: `PIP_EXTRA_INDEX_URL="https://pypi.myorg.com/simple"` Platform-specific variants also available: `CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX` @@ -378,11 +375,11 @@ If dependencies are required to build your wheel (for example if you include a h 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: `pip install .` +Example: `pip install pybind11` Example: `yum install -y libffi-dev && pip install .` -Platform-specific variants also available: +Platform-specific variants also available: `CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX` *** @@ -400,8 +397,8 @@ Beware to specify a valid Docker image that can be used in the same way as the o 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="manylinux2010_$(uname -m)"`). -Example: `manylinux1` -Example: `dockcross/manylinux-x64` +Example: `manylinux1` +Example: `dockcross/manylinux-x64` Example: `dockcross/manylinux-x86` *** @@ -413,7 +410,7 @@ Optional. 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`. +On Linux and Mac, the command runs in a shell, so you can write things like `cmd1 && cmd2`. Example: `nosetests {project}/tests` @@ -429,7 +426,7 @@ Optional. Space-separated list of dependencies required for running the tests. -Example: `pytest` +Example: `pytest` Example: `nose==1.3.7 moto==0.4.31` Platform-specific variants also available: @@ -480,13 +477,13 @@ After you've built your wheels, you'll probably want to deliver them to PyPI. On your development machine, do the following... ```bash -# Clear out your 'dist' folder. +# Clear out your 'dist' folder. rm -rf dist # Make a source distribution python setup.py sdist # 🏃🏻 -# Go and download your wheel files from wherever you put them. Put +# Go and download your wheel files from wherever you put them. Put # them all into the 'dist' folder. # Upload using 'twine' (you may need to 'pip install twine') @@ -518,7 +515,7 @@ If your wheel didn't compile, check the list below for some debugging tips. Working examples ---------------- -Here are some repos that use cibuildwheel. +Here are some repos that use cibuildwheel. - [pyinstrument_cext](https://github.com/joerick/pyinstrument_cext) - [websockets](https://github.com/aaugustin/websockets) @@ -536,7 +533,7 @@ Here are some repos that use cibuildwheel. Legal note ---------- -Since `cibuildwheel` runs the wheel through delocate or auditwheel, it might automatically bundle dynamically linked libraries from the build machine. +Since `cibuildwheel` runs the wheel through delocate or auditwheel, it might automatically bundle dynamically linked libraries from the build machine. It helps ensure that the library can run without any dependencies outside of the pip toolchain. @@ -568,7 +565,7 @@ _26 May 2019_ - ✨ Add support for building on Azure pipelines! This lets you build all Linux, Mac and Windows wheels on one service, so it promises to be the - easiest to set up! Check out the quickstart in the docs, or + easiest to set up! Check out the quickstart in the docs, or [cibuildwheel-azure-example](https://github.com/joerick/cibuildwheel-azure-example) for an example project. (#126, #132) - 🛠 Internal change - the end-to-end test projects format was updated, so we @@ -708,7 +705,7 @@ _11 June 2017_ _13 April 2017_ -- ✨ Added `CIBW_SKIP` option, letting users explicitly skip a build +- ✨ 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 @@ -750,7 +747,7 @@ Maintainers Credits ------- -`cibuildwheel` stands on the shoulders of giants. +`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) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 233f1f02..239ef5cb 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -14,13 +14,11 @@ def get_python_configurations(build_selector): python_configurations = [ PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'), PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'), - PythonConfiguration(identifier='cp34-manylinux_x86_64', path='/opt/python/cp34-cp34m'), PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'), PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'), PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'), PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'), PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'), - PythonConfiguration(identifier='cp34-manylinux_i686', path='/opt/python/cp34-cp34m'), PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'), PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'), PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'), diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 7378f142..3016037d 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -15,7 +15,6 @@ def get_python_configurations(build_selector): 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.17/python-2.7.17-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.8/python-3.6.8-macosx10.6.pkg'), PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.5/python-3.7.5-macosx10.6.pkg'), @@ -58,7 +57,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef # install call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/']) # patch open ssl - if config.version in ('3.4', '3.5'): + if config.version == '3.5': call(['curl', '-fsSLo', '/tmp/python-patch.tar.gz', 'https://github.com/mayeut/patch-macos-python-openssl/releases/download/v1.0.2t/patch-macos-python-%s-openssl-v1.0.2t.tar.gz' % config.version]) call(['sudo', 'tar', '-C', '/Library/Frameworks/Python.framework/Versions/%s/' % config.version, '-xmf', '/tmp/python-patch.tar.gz']) diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index da929bcc..7f7eaae2 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -57,8 +57,6 @@ def get_python_configurations(build_selector): python_configurations = [ PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\\Python27', nuget_version="2.7.16"), PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\\Python27-x64', nuget_version="2.7.16"), - PythonConfiguration(version='3.4.x', arch="32", identifier='cp34-win32', path='C:\\Python34', nuget_version=None), - PythonConfiguration(version='3.4.x', arch="64", identifier='cp34-win_amd64', path='C:\\Python34-x64', nuget_version=None), PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\\Python35', nuget_version="3.5.4"), PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\\Python35-x64', nuget_version="3.5.4"), PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\\Python36', nuget_version="3.6.8"), @@ -67,20 +65,14 @@ def get_python_configurations(build_selector): PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\\Python37-x64', nuget_version="3.7.4") ] - if IS_RUNNING_ON_AZURE: - # Python 3.4 isn't supported on Azure. - # See https://github.com/Microsoft/azure-pipelines-tasks/issues/9674 - python_configurations = [c for c in python_configurations if c.version != '3.4.x'] - if IS_RUNNING_ON_TRAVIS: # cannot install VCForPython27.msi which is needed for compiling C software # try with (and similar): msiexec /i VCForPython27.msi ALLUSERS=1 ACCEPT=YES /passive - # no easy and stable way fo installing python 3.4 - python_configurations = [c for c in python_configurations if c.version != '2.7.x' and c.version != '3.4.x'] + python_configurations = [c for c in python_configurations if c.version != '2.7.x'] # skip builds as required python_configurations = [c for c in python_configurations if build_selector(c.identifier)] - + return python_configurations @@ -109,7 +101,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef if IS_RUNNING_ON_TRAVIS: # instal nuget as best way for provide python shell(["choco", "install", "nuget.commandline"]) - # get pip fo this installation which not have. + # get pip fo this installation which not have. get_pip_url = 'https://bootstrap.pypa.io/get-pip.py' get_pip_script = 'C:\\get-pip.py' shell(['curl', '-L', '-o', get_pip_script, get_pip_url]) diff --git a/test/04_build_skip/cibuildwheel_test.py b/test/04_build_skip/cibuildwheel_test.py index 98333fd2..764874a2 100644 --- a/test/04_build_skip/cibuildwheel_test.py +++ b/test/04_build_skip/cibuildwheel_test.py @@ -7,11 +7,11 @@ def test(): # build the wheels utils.cibuildwheel_run(project_dir, add_env={ 'CIBW_BUILD': 'cp3?-*', - 'CIBW_SKIP': 'cp34-*', + 'CIBW_SKIP': 'cp37-*', }) - # check that we got the right wheels. There should be no 2.7 or 3.4. + # check that we got the right wheels. There should be no 2.7 or 3.7. expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0') - if ('-cp3' in w) and ('-cp34' not in w)] + if ('-cp3' in w) and ('-cp37' not in w)] actual_wheels = os.listdir('wheelhouse') assert set(actual_wheels) == set(expected_wheels) diff --git a/test/shared/utils.py b/test/shared/utils.py index 78f09050..2a96df61 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -26,14 +26,14 @@ def cibuildwheel_get_build_identifiers(project_path, env=None): def cibuildwheel_run(project_path, env=None, add_env=None): ''' - Runs cibuildwheel as a subprocess, building the project at project_path. - + Runs cibuildwheel as a subprocess, building the project at project_path. + Uses the current Python interpreter. Configure settings using env. ''' if env is None: env = os.environ.copy() - + if add_env is not None: env.update(add_env) @@ -51,25 +51,21 @@ def expected_wheels(package_name, package_version): templates = [ '{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp35-cp35m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux1_i686.whl', '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', '{package_name}-{package_version}-cp27-cp27m-manylinux2010_i686.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_i686.whl', - '{package_name}-{package_version}-cp34-cp34m-manylinux2010_i686.whl', '{package_name}-{package_version}-cp35-cp35m-manylinux2010_i686.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux2010_i686.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux2010_i686.whl', @@ -77,12 +73,10 @@ def expected_wheels(package_name, package_version): elif platform == 'windows': templates = [ '{package_name}-{package_version}-cp27-cp27m-win32.whl', - '{package_name}-{package_version}-cp34-cp34m-win32.whl', '{package_name}-{package_version}-cp35-cp35m-win32.whl', '{package_name}-{package_version}-cp36-cp36m-win32.whl', '{package_name}-{package_version}-cp37-cp37m-win32.whl', '{package_name}-{package_version}-cp27-cp27m-win_amd64.whl', - '{package_name}-{package_version}-cp34-cp34m-win_amd64.whl', '{package_name}-{package_version}-cp35-cp35m-win_amd64.whl', '{package_name}-{package_version}-cp36-cp36m-win_amd64.whl', '{package_name}-{package_version}-cp37-cp37m-win_amd64.whl', @@ -90,21 +84,17 @@ def expected_wheels(package_name, package_version): elif platform == 'macos': templates = [ '{package_name}-{package_version}-cp27-cp27m-macosx_10_6_intel.whl', - '{package_name}-{package_version}-cp34-cp34m-macosx_10_6_intel.whl', '{package_name}-{package_version}-cp35-cp35m-macosx_10_6_intel.whl', '{package_name}-{package_version}-cp36-cp36m-macosx_10_6_intel.whl', '{package_name}-{package_version}-cp37-cp37m-macosx_10_6_intel.whl', ] else: raise Exception('unsupported platform') - - if IS_WINDOWS_RUNNING_ON_AZURE: - # Python 3.4 isn't supported on Azure. - templates = [t for t in templates if '-cp34-' not in t] + if IS_WINDOWS_RUNNING_ON_TRAVIS: # Python 2.7 and 3.4 isn't supported on Travis. - templates = [t for t in templates if '-cp27-' not in t and '-cp34-' not in t] - + templates = [t for t in templates if '-cp27-' not in t] + return [filename.format(package_name=package_name, package_version=package_version) for filename in templates] From 58048b4bb11ab8714fb33a5694cad1b1c09bfbce Mon Sep 17 00:00:00 2001 From: mayeut Date: Sun, 3 Nov 2019 13:38:40 +0100 Subject: [PATCH 19/22] Remove trailing-spaces from README.md Also replace double-space by a backslash to show intent of a line-break. --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 64266b0c..840113f6 100644 --- a/README.md +++ b/README.md @@ -352,10 +352,10 @@ You must set this variable to pass variables to Linux builds (since they execute You can use `$PATH` syntax to insert other variables, or the `$(pwd)` syntax to insert the output of other shell commands. -Example: `CFLAGS="-g -Wall" CXXFLAGS="-Wall"` -Example: `PATH=$PATH:/usr/local/bin` -Example: `BUILD_TIME="$(date)"` -Example: `PIP_EXTRA_INDEX_URL="https://pypi.myorg.com/simple"` +Example: `CFLAGS="-g -Wall" CXXFLAGS="-Wall"`\ +Example: `PATH=$PATH:/usr/local/bin`\ +Example: `BUILD_TIME="$(date)"`\ +Example: `PIP_EXTRA_INDEX_URL="https://pypi.myorg.com/simple"`\ Platform-specific variants also available: `CIBW_ENVIRONMENT_MACOS` | `CIBW_ENVIRONMENT_WINDOWS` | `CIBW_ENVIRONMENT_LINUX` @@ -375,11 +375,11 @@ If dependencies are required to build your wheel (for example if you include a h 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: `pip install .`\ +Example: `pip install pybind11`\ Example: `yum install -y libffi-dev && pip install .` -Platform-specific variants also available: +Platform-specific variants also available:\ `CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX` *** @@ -397,8 +397,8 @@ Beware to specify a valid Docker image that can be used in the same way as the o 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="manylinux2010_$(uname -m)"`). -Example: `manylinux1` -Example: `dockcross/manylinux-x64` +Example: `manylinux1`\ +Example: `dockcross/manylinux-x64`\ Example: `dockcross/manylinux-x86` *** @@ -426,7 +426,7 @@ Optional. Space-separated list of dependencies required for running the tests. -Example: `pytest` +Example: `pytest`\ Example: `nose==1.3.7 moto==0.4.31` Platform-specific variants also available: From f2ef7a61696e0e4ff332f5a981f7c9f231840925 Mon Sep 17 00:00:00 2001 From: mayeut Date: Sat, 26 Oct 2019 01:09:19 +0200 Subject: [PATCH 20/22] Always use nuget to install python on Windows --- azure-pipelines.yml | 17 ++----- cibuildwheel/windows.py | 105 +++++++++++++++++----------------------- test/shared/utils.py | 4 +- 3 files changed, 52 insertions(+), 74 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5a9e501c..6d67dfbb 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,7 +1,7 @@ jobs: - job: linux - pool: {vmImage: 'Ubuntu-16.04'} - steps: + pool: {vmImage: 'Ubuntu-18.04'} + steps: - task: UsePythonVersion@0 - bash: | python -m pip install -r requirements-dev.txt @@ -9,7 +9,7 @@ jobs: - job: macos pool: {vmImage: 'macOS-10.13'} - steps: + steps: - task: UsePythonVersion@0 - bash: | python -m pip install -r requirements-dev.txt @@ -17,15 +17,8 @@ jobs: - job: windows pool: {vmImage: 'vs2017-win2016'} - steps: - - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.6', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.6', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.7', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.7', architecture: x64}} + steps: + - task: UsePythonVersion@0 - script: choco install vcpython27 -f -y displayName: Install Visual C++ for Python 2.7 - bash: | diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index 7f7eaae2..d37d7509 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -8,67 +8,48 @@ try: except ImportError: from pipes import quote as shlex_quote +try: + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen + from .util import prepare_command, get_build_verbosity_extra_flags IS_RUNNING_ON_AZURE = os.path.exists('C:\\hostedtoolcache') IS_RUNNING_ON_TRAVIS = os.environ.get('TRAVIS_OS_NAME') == 'windows' + def get_python_path(config): - if IS_RUNNING_ON_AZURE: - # We can't hard-code the paths because on Azure, we don't know which - # bugfix release of Python we are getting so we need to check which - # ones exist. We just use the first one that is found since there should - # only be one. - path_pattern = 'C:\\hostedtoolcache\\windows\\Python\\{version}\\{arch}'.format( - version=config.version.replace('x', '*'), - arch='x86' if config.arch == '32' else 'x64' - ) - try: - return glob(path_pattern)[0] - except IndexError: - raise Exception('Could not find a Python install at ' + path_pattern) - elif IS_RUNNING_ON_TRAVIS: - if config.version == "3.4.x": - return config.path - else: - nuget_args = get_nuget_args(config) - return os.path.join(nuget_args[-1], nuget_args[0] + "." + config.nuget_version, "tools") - else: - # Assume we're running on AppVeyor - major, minor = config.version.split('.')[:2] - return 'C:\\Python{major}{minor}{arch}'.format( - major=major, - minor=minor, - arch = '-x64' if config.arch == '64' else '' - ) + nuget_args = get_nuget_args(config) + return os.path.join(nuget_args[-1], nuget_args[0] + "." + config.version, "tools") def get_nuget_args(configuration): - if configuration.nuget_version is None: - return None python_name = "python" if configuration.version[0] == '3' else "python2" if configuration.arch == "32": python_name = python_name + "x86" - return [python_name, "-Version", configuration.nuget_version, "-OutputDirectory", "C:/python"] + return [python_name, "-Version", configuration.version, "-OutputDirectory", "C:/python"] def get_python_configurations(build_selector): - PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier', 'path', "nuget_version"]) + PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'arch', 'identifier']) python_configurations = [ - PythonConfiguration(version='2.7.x', arch="32", identifier='cp27-win32', path='C:\\Python27', nuget_version="2.7.16"), - PythonConfiguration(version='2.7.x', arch="64", identifier='cp27-win_amd64', path='C:\\Python27-x64', nuget_version="2.7.16"), - PythonConfiguration(version='3.5.x', arch="32", identifier='cp35-win32', path='C:\\Python35', nuget_version="3.5.4"), - PythonConfiguration(version='3.5.x', arch="64", identifier='cp35-win_amd64', path='C:\\Python35-x64', nuget_version="3.5.4"), - PythonConfiguration(version='3.6.x', arch="32", identifier='cp36-win32', path='C:\\Python36', nuget_version="3.6.8"), - PythonConfiguration(version='3.6.x', arch="64", identifier='cp36-win_amd64', path='C:\\Python36-x64', nuget_version="3.6.8"), - PythonConfiguration(version='3.7.x', arch="32", identifier='cp37-win32', path='C:\\Python37', nuget_version="3.7.4"), - PythonConfiguration(version='3.7.x', arch="64", identifier='cp37-win_amd64', path='C:\\Python37-x64', nuget_version="3.7.4") + PythonConfiguration(version='2.7.17', arch="32", identifier='cp27-win32'), + PythonConfiguration(version='2.7.17', arch="64", identifier='cp27-win_amd64'), + PythonConfiguration(version='3.5.4', arch="32", identifier='cp35-win32'), + PythonConfiguration(version='3.5.4', arch="64", identifier='cp35-win_amd64'), + PythonConfiguration(version='3.6.8', arch="32", identifier='cp36-win32'), + PythonConfiguration(version='3.6.8', arch="64", identifier='cp36-win_amd64'), + PythonConfiguration(version='3.7.5', arch="32", identifier='cp37-win32'), + PythonConfiguration(version='3.7.5', arch="64", identifier='cp37-win_amd64'), + PythonConfiguration(version='3.8.0', arch="32", identifier='cp38-win32'), + PythonConfiguration(version='3.8.0', arch="64", identifier='cp38-win_amd64'), ] if IS_RUNNING_ON_TRAVIS: # 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 c.version != '2.7.x'] + python_configurations = [c for c in python_configurations if not c.version.startswith('2.7.')] # skip builds as required python_configurations = [c for c in python_configurations if build_selector(c.identifier)] @@ -78,11 +59,20 @@ def get_python_configurations(build_selector): def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, environment): + def simple_shell(args, env=None, cwd=None): + print('+ ' + ' '.join(args)) + args = ['cmd', '/E:ON', '/V:ON', '/C'] + args + return subprocess.check_call(' '.join(args), env=env, cwd=cwd) + def download(url, dest): + print('+ Download ' + url + ' to ' + dest) + response = urlopen(url) + try: + with open(dest, 'wb') as file: + file.write(response.read()) + finally: + response.close() if IS_RUNNING_ON_AZURE or IS_RUNNING_ON_TRAVIS: - def shell(args, env=None, cwd=None): - print('+ ' + ' '.join(args)) - args = ['cmd', '/E:ON', '/V:ON', '/C'] + args - return subprocess.check_call(' '.join(args), env=env, cwd=cwd) + shell = simple_shell else: run_with_env = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'appveyor_run_with_env.cmd')) @@ -98,21 +88,19 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef temp_dir = tempfile.mkdtemp(prefix='cibuildwheel') built_wheel_dir = os.path.join(temp_dir, 'built_wheel') - if IS_RUNNING_ON_TRAVIS: - # instal nuget as best way for provide python - shell(["choco", "install", "nuget.commandline"]) - # get pip fo this installation which not have. - get_pip_url = 'https://bootstrap.pypa.io/get-pip.py' - get_pip_script = 'C:\\get-pip.py' - shell(['curl', '-L', '-o', get_pip_script, get_pip_url]) + # install nuget as best way to provide python + nuget = 'C:\\nuget.exe' + download('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', nuget) + # get pip fo this installation which not have. + get_pip_script = 'C:\\get-pip.py' + download('https://bootstrap.pypa.io/get-pip.py', get_pip_script) python_configurations = get_python_configurations(build_selector) for config in python_configurations: config_python_path = get_python_path(config) - if IS_RUNNING_ON_TRAVIS and config.nuget_version is not None and not os.path.exists(config_python_path): - shell(["nuget", "install"] + get_nuget_args(config)) - if not os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe')): - shell([os.path.join(config_python_path, 'python.exe'), get_pip_script ]) + simple_shell([nuget, "install"] + get_nuget_args(config)) + if not os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe')): + simple_shell([os.path.join(config_python_path, 'python.exe'), get_pip_script ]) # check python & pip exist for this configuration assert os.path.exists(os.path.join(config_python_path, 'python.exe')) @@ -139,12 +127,7 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef shell(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)\"'], env=env) # prepare the Python environment - if config.version == "3.4.x": - shell(['python', '-m', 'pip', 'install', 'pip==19.1.1'], - env=env) - else: - shell(['python', '-m', 'pip', 'install', '--upgrade', 'pip'], - env=env) + shell(['python', '-m', 'pip', 'install', '--upgrade', 'pip'], env=env) shell(['pip', 'install', '--upgrade', 'setuptools'], env=env) shell(['pip', 'install', 'wheel'], env=env) diff --git a/test/shared/utils.py b/test/shared/utils.py index 2a96df61..94aa96d3 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -76,10 +76,12 @@ def expected_wheels(package_name, package_version): '{package_name}-{package_version}-cp35-cp35m-win32.whl', '{package_name}-{package_version}-cp36-cp36m-win32.whl', '{package_name}-{package_version}-cp37-cp37m-win32.whl', + '{package_name}-{package_version}-cp38-cp38-win32.whl', '{package_name}-{package_version}-cp27-cp27m-win_amd64.whl', '{package_name}-{package_version}-cp35-cp35m-win_amd64.whl', '{package_name}-{package_version}-cp36-cp36m-win_amd64.whl', '{package_name}-{package_version}-cp37-cp37m-win_amd64.whl', + '{package_name}-{package_version}-cp38-cp38-win_amd64.whl', ] elif platform == 'macos': templates = [ @@ -92,7 +94,7 @@ def expected_wheels(package_name, package_version): raise Exception('unsupported platform') if IS_WINDOWS_RUNNING_ON_TRAVIS: - # Python 2.7 and 3.4 isn't supported on Travis. + # Python 2.7 isn't supported on Travis. templates = [t for t in templates if '-cp27-' not in t] return [filename.format(package_name=package_name, package_version=package_version) From 104dcf1d3716687634f8f37e0609a27ec1eede57 Mon Sep 17 00:00:00 2001 From: mayeut Date: Sat, 2 Nov 2019 10:25:25 +0100 Subject: [PATCH 21/22] Add python 3.8 support --- README.md | 12 +++--------- cibuildwheel/linux.py | 2 ++ cibuildwheel/macos.py | 1 + test/shared/utils.py | 5 +++++ 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 840113f6..591cb073 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ What does it do? | Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ | | Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ | | Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ | +| Python 3.8 | ✅ | ✅ | ✅ | ✅ | ✅ | > ¹ Not supported on Travis @@ -76,14 +77,7 @@ jobs: - job: windows pool: {vmImage: 'vs2017-win2016'} steps: - - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '2.7', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.5', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.6', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.6', architecture: x64}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.7', architecture: x86}} - - {task: UsePythonVersion@0, inputs: {versionSpec: '3.7', architecture: x64}} + - task: UsePythonVersion@0 - script: choco install vcpython27 -f -y displayName: Install Visual C++ for Python 2.7 - bash: | @@ -309,7 +303,7 @@ When both options are specified, both conditions are applied and only builds wit The format is `python_tag-platform_tag`. The tags are similar but not identical to the ones defined in [PEP 425](https://www.python.org/dev/peps/pep-0425/#details). -Python tags look like `cp27` `cp35` `cp36` `cp37` +Python tags look like `cp27` `cp35` `cp36` `cp37` `cp38` Platform tags look like `macosx_10_6_intel` `manylinux_x86_64` `manylinux_i686` `win32` `win_amd64` diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 239ef5cb..ad666f45 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -17,11 +17,13 @@ def get_python_configurations(build_selector): PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'), PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'), PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'), + PythonConfiguration(identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'), PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'), PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'), PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'), PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'), PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'), + PythonConfiguration(identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'), ] # skip builds as required diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 3016037d..25bf78a7 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -18,6 +18,7 @@ def get_python_configurations(build_selector): 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.8/python-3.6.8-macosx10.6.pkg'), PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.5/python-3.7.5-macosx10.6.pkg'), + PythonConfiguration(version='3.8', identifier='cp38-macosx_10_9_x86_64', url='https://www.python.org/ftp/python/3.8.0/python-3.8.0-macosx10.9.pkg'), ] # skip builds as required diff --git a/test/shared/utils.py b/test/shared/utils.py index 94aa96d3..d4e9c9c6 100644 --- a/test/shared/utils.py +++ b/test/shared/utils.py @@ -54,21 +54,25 @@ def expected_wheels(package_name, package_version): '{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl', + '{package_name}-{package_version}-cp38-cp38-manylinux1_x86_64.whl', '{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp35-cp35m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux2010_x86_64.whl', + '{package_name}-{package_version}-cp38-cp38-manylinux2010_x86_64.whl', '{package_name}-{package_version}-cp27-cp27m-manylinux1_i686.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux1_i686.whl', '{package_name}-{package_version}-cp35-cp35m-manylinux1_i686.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux1_i686.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux1_i686.whl', + '{package_name}-{package_version}-cp38-cp38-manylinux1_i686.whl', '{package_name}-{package_version}-cp27-cp27m-manylinux2010_i686.whl', '{package_name}-{package_version}-cp27-cp27mu-manylinux2010_i686.whl', '{package_name}-{package_version}-cp35-cp35m-manylinux2010_i686.whl', '{package_name}-{package_version}-cp36-cp36m-manylinux2010_i686.whl', '{package_name}-{package_version}-cp37-cp37m-manylinux2010_i686.whl', + '{package_name}-{package_version}-cp38-cp38-manylinux2010_i686.whl', ] elif platform == 'windows': templates = [ @@ -89,6 +93,7 @@ def expected_wheels(package_name, package_version): '{package_name}-{package_version}-cp35-cp35m-macosx_10_6_intel.whl', '{package_name}-{package_version}-cp36-cp36m-macosx_10_6_intel.whl', '{package_name}-{package_version}-cp37-cp37m-macosx_10_6_intel.whl', + '{package_name}-{package_version}-cp38-cp38-macosx_10_9_x86_64.whl', ] else: raise Exception('unsupported platform') From 05ab66cf97e06dcee1ab446126c8fe2a661e20e0 Mon Sep 17 00:00:00 2001 From: mayeut Date: Mon, 4 Nov 2019 22:40:49 +0100 Subject: [PATCH 22/22] Fix documentation for macOS python 3.8 --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 591cb073..4b31c086 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,13 @@ Python wheels are great. Building them across **Mac, Linux, Windows**, on **mult What does it do? ---------------- -| | macOS 10.6+ | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit | -|---|---|---|---|---|---| -| Python 2.7 | ✅ | ✅ | ✅ | ✅¹ | ✅¹ | -| Python 3.5 | ✅ | ✅ | ✅ | ✅ | ✅ | -| Python 3.6 | ✅ | ✅ | ✅ | ✅ | ✅ | -| Python 3.7 | ✅ | ✅ | ✅ | ✅ | ✅ | -| Python 3.8 | ✅ | ✅ | ✅ | ✅ | ✅ | +| | macOS 10.6+ intel | macOS 10.9+ x86_64 | manylinux i686 | manylinux x86_64 | Windows 32bit | Windows 64bit | +|---|---|---|---|---|---|---| +| Python 2.7 | ✅ | | ✅ | ✅ | ✅¹ | ✅¹ | +| Python 3.5 | ✅ | | ✅ | ✅ | ✅ | ✅ | +| Python 3.6 | ✅ | | ✅ | ✅ | ✅ | ✅ | +| Python 3.7 | ✅ | | ✅ | ✅ | ✅ | ✅ | +| Python 3.8 | | ✅ | ✅ | ✅ | ✅ | ✅ | > ¹ Not supported on Travis @@ -305,7 +305,7 @@ The format is `python_tag-platform_tag`. The tags are similar but not identical Python tags look like `cp27` `cp35` `cp36` `cp37` `cp38` -Platform tags look like `macosx_10_6_intel` `manylinux_x86_64` `manylinux_i686` `win32` `win_amd64` +Platform tags look like `macosx_10_6_intel` `macosx_10_9_x86_64` `manylinux_x86_64` `manylinux_i686` `win32` `win_amd64` You can also use shell-style globbing syntax (as per `fnmatch`). @@ -314,6 +314,7 @@ The list of supported and currently selected build identifiers can be retrieved Examples: - 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 3.8 on the Mac: `CIBW_SKIP`:`cp38-macosx_10_9_x86_64` - 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`