Add manylinux2014 x86_64/i686 (#215)
This commit is contained in:
@@ -151,9 +151,11 @@ def main():
|
||||
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'}
|
||||
'manylinux2010': 'quay.io/pypa/manylinux2010_x86_64',
|
||||
'manylinux2014': 'quay.io/pypa/manylinux2014_x86_64'}
|
||||
default_manylinux_images_i686 = {'manylinux1': 'quay.io/pypa/manylinux1_i686',
|
||||
'manylinux2010': 'quay.io/pypa/manylinux2010_i686'}
|
||||
'manylinux2010': 'quay.io/pypa/manylinux2010_i686',
|
||||
'manylinux2014': 'quay.io/pypa/manylinux2014_i686'}
|
||||
|
||||
build_options.update(
|
||||
manylinux_images={'x86_64': default_manylinux_images_x86_64.get(manylinux_x86_64_image) or manylinux_x86_64_image,
|
||||
|
||||
+9
-2
@@ -240,12 +240,14 @@ CIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel repair --lib-sdir . -w {dest_dir} {
|
||||
|
||||
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).
|
||||
|
||||
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.
|
||||
The value of this option can either be set to `manylinux1`, `manylinux2010` or `manylinux2014` 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).
|
||||
Beware to specify a valid Docker image that can be used in the same way as the official, default Docker images: all necessary Python and pip versions need to be present in `/opt/python/`, and the `auditwheel` tool needs to be present for `cibuildwheel` to work. Apart from that, the architecture and relevant shared system libraries need to be manylinux1-, manylinux2010- or manylinux2014-compatible in order to produce valid `manylinux1`/`manylinux2010`/`manylinux2014` wheels (see https://github.com/pypa/manylinux, [PEP 513](https://www.python.org/dev/peps/pep-0513/), [PEP 571](https://www.python.org/dev/peps/pep-0571/ and [PEP 599](https://www.python.org/dev/peps/pep-0599/) for more details).
|
||||
|
||||
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)"`).
|
||||
|
||||
Note that `manylinux2014` doesn't support builds with Python 2.7 - when building with `manylinux2014`, skip Python 2.7 using `CIBW_SKIP` (see example below).
|
||||
|
||||
#### Examples
|
||||
|
||||
```yaml
|
||||
@@ -253,6 +255,11 @@ Note that `auditwheel` detects the version of the `manylinux` standard in the Do
|
||||
CIBW_MANYLINUX_X86_64_IMAGE: manylinux1
|
||||
CIBW_MANYLINUX_I686_IMAGE: manylinux1
|
||||
|
||||
# build using the manylinux2014 image
|
||||
CIBW_MANYLINUX_X86_64_IMAGE: manylinux2014
|
||||
CIBW_MANYLINUX_I686_IMAGE: manylinux2014
|
||||
CIBW_SKIP: cp27-manylinux*
|
||||
|
||||
# build using a different image from the docker registry
|
||||
CIBW_MANYLINUX_X86_64_IMAGE: dockcross/manylinux-x64
|
||||
CIBW_MANYLINUX_I686_IMAGE: dockcross/manylinux-x86
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
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
|
||||
actual_wheels = 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 = [w for w in utils.expected_wheels('spam', '0.1.0')
|
||||
if not '-manylinux' in w or '-manylinux2010' in w]
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
@@ -0,0 +1,27 @@
|
||||
import os, pytest
|
||||
import utils
|
||||
|
||||
|
||||
@pytest.mark.parametrize('manylinux_image', ['manylinux1', 'manylinux2010', 'manylinux2014'])
|
||||
def test(manylinux_image):
|
||||
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 variable is necessary to fail on 'malloc_info' (on manylinux1) during compilation/linking,
|
||||
# rather than when dynamically loading the Python
|
||||
add_env = {
|
||||
'CIBW_ENVIRONMENT': 'CFLAGS="$CFLAGS -Werror=implicit-function-declaration"',
|
||||
'CIBW_MANYLINUX_X86_64_IMAGE': manylinux_image,
|
||||
'CIBW_MANYLINUX_I686_IMAGE': manylinux_image,
|
||||
}
|
||||
if manylinux_image == 'manylinux2014':
|
||||
add_env['CIBW_SKIP'] = 'cp27*' # not available on manylinux2014
|
||||
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env)
|
||||
|
||||
expected_wheels = [w for w in utils.expected_wheels('spam', '0.1.0', manylinux_versions=[manylinux_image])]
|
||||
if manylinux_image == 'manylinux2014':
|
||||
expected_wheels = [w for w in expected_wheels if '-cp27' not in w]
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
@@ -1,6 +1,12 @@
|
||||
#include <Python.h>
|
||||
#if defined(__linux__)
|
||||
#include <malloc.h>
|
||||
|
||||
#if !defined(__GLIBC_PREREQ)
|
||||
#error "Must run on a glibc linux environment"
|
||||
#endif
|
||||
|
||||
#if !__GLIBC_PREREQ(2, 5) /* manylinux1 is glibc 2.5 */
|
||||
#error "Must run on a glibc >= 2.5 linux environment"
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
@@ -12,7 +18,12 @@ spam_system(PyObject *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, "s", &command))
|
||||
return NULL;
|
||||
|
||||
#if defined(__linux__)
|
||||
#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 17) /* manylinux2014 is glibc 2.17 */
|
||||
// secure_getenv is only available in manylinux2014, ensuring
|
||||
// that only a manylinux2014 wheel is produced
|
||||
sts = (int)secure_getenv("NON_EXISTING_ENV_VARIABLE");
|
||||
#elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 10) /* manylinux2010 is glibc 2.12 */
|
||||
// malloc_info is only available on manylinux2010+
|
||||
sts = malloc_info(0, stdout);
|
||||
#endif
|
||||
if (sts == 0) {
|
||||
@@ -38,7 +49,7 @@ spam_system(PyObject *self, PyObject *args)
|
||||
#endif
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
{"system", (PyCFunction)spam_system, METH_VARARGS,
|
||||
{"system", (PyCFunction)spam_system, METH_VARARGS,
|
||||
"Execute a shell command."},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
@@ -47,9 +58,9 @@ MOD_INIT(spam)
|
||||
{
|
||||
PyObject* m;
|
||||
|
||||
MOD_DEF(m,
|
||||
"spam",
|
||||
"Example module",
|
||||
MOD_DEF(m,
|
||||
"spam",
|
||||
"Example module",
|
||||
module_methods,
|
||||
-1)
|
||||
|
||||
+32
-48
@@ -66,67 +66,51 @@ def cibuildwheel_run(project_path, env=None, add_env=None, output_dir=None):
|
||||
return wheels
|
||||
|
||||
|
||||
def expected_wheels(package_name, package_version):
|
||||
def expected_wheels(package_name, package_version, manylinux_versions=['manylinux1', 'manylinux2010']):
|
||||
'''
|
||||
Returns a list of expected wheels from a run of cibuildwheel.
|
||||
'''
|
||||
# per PEP 425 (https://www.python.org/dev/peps/pep-0425/), wheel files shall have name of the form
|
||||
# {distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl
|
||||
# {python tag} and {abi tag} are closely related to the python interpreter used to build the wheel
|
||||
# so we'll merge them below as python_abi_tag
|
||||
python_abi_tags = ['cp27-cp27m', 'cp35-cp35m', 'cp36-cp36m', 'cp37-cp37m', 'cp38-cp38']
|
||||
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}-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',
|
||||
]
|
||||
python_abi_tags.append('cp27-cp27mu') # python 2.7 has 2 different ABI on manylinux
|
||||
platform_tags = []
|
||||
for architecture in ['x86_64', 'i686']:
|
||||
for manylinux_version in manylinux_versions:
|
||||
platform_tags.append('{manylinux_version}_{architecture}'.format(
|
||||
manylinux_version=manylinux_version, architecture=architecture
|
||||
))
|
||||
def get_platform_tags(python_abi_tag):
|
||||
return platform_tags
|
||||
elif platform == 'windows':
|
||||
templates = [
|
||||
'{package_name}-{package_version}-cp27-cp27m-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}-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',
|
||||
]
|
||||
def get_platform_tags(python_abi_tag):
|
||||
return ['win32', 'win_amd64']
|
||||
elif platform == 'macos':
|
||||
templates = [
|
||||
'{package_name}-{package_version}-cp27-cp27m-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',
|
||||
'{package_name}-{package_version}-cp38-cp38-macosx_10_9_x86_64.whl',
|
||||
]
|
||||
def get_platform_tags(python_abi_tag):
|
||||
if python_abi_tag == 'cp38-cp38':
|
||||
return ['macosx_10_9_x86_64']
|
||||
else:
|
||||
return ['macosx_10_6_intel']
|
||||
else:
|
||||
raise Exception('unsupported platform')
|
||||
|
||||
templates = []
|
||||
for python_abi_tag in python_abi_tags:
|
||||
for platform_tag in get_platform_tags(python_abi_tag):
|
||||
templates.append('{package_name}-{package_version}-{python_abi_tag}-{platform_tag}.whl'.format(
|
||||
package_name=package_name, package_version=package_version,
|
||||
python_abi_tag=python_abi_tag, platform_tag=platform_tag
|
||||
))
|
||||
|
||||
if IS_WINDOWS_RUNNING_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)
|
||||
for filename in templates]
|
||||
return templates
|
||||
|
||||
|
||||
platform = None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user