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')
|
manylinux_i686_image = os.environ.get('CIBW_MANYLINUX_I686_IMAGE', 'manylinux2010')
|
||||||
|
|
||||||
default_manylinux_images_x86_64 = {'manylinux1': 'quay.io/pypa/manylinux1_x86_64',
|
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',
|
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(
|
build_options.update(
|
||||||
manylinux_images={'x86_64': default_manylinux_images_x86_64.get(manylinux_x86_64_image) or manylinux_x86_64_image,
|
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).
|
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 `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
|
#### Examples
|
||||||
|
|
||||||
```yaml
|
```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_X86_64_IMAGE: manylinux1
|
||||||
CIBW_MANYLINUX_I686_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
|
# build using a different image from the docker registry
|
||||||
CIBW_MANYLINUX_X86_64_IMAGE: dockcross/manylinux-x64
|
CIBW_MANYLINUX_X86_64_IMAGE: dockcross/manylinux-x64
|
||||||
CIBW_MANYLINUX_I686_IMAGE: dockcross/manylinux-x86
|
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>
|
#include <Python.h>
|
||||||
#if defined(__linux__)
|
|
||||||
#include <malloc.h>
|
#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
|
#endif
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
@@ -12,7 +18,12 @@ spam_system(PyObject *self, PyObject *args)
|
|||||||
if (!PyArg_ParseTuple(args, "s", &command))
|
if (!PyArg_ParseTuple(args, "s", &command))
|
||||||
return NULL;
|
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);
|
sts = malloc_info(0, stdout);
|
||||||
#endif
|
#endif
|
||||||
if (sts == 0) {
|
if (sts == 0) {
|
||||||
@@ -38,7 +49,7 @@ spam_system(PyObject *self, PyObject *args)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
{"system", (PyCFunction)spam_system, METH_VARARGS,
|
{"system", (PyCFunction)spam_system, METH_VARARGS,
|
||||||
"Execute a shell command."},
|
"Execute a shell command."},
|
||||||
{NULL} /* Sentinel */
|
{NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
@@ -47,9 +58,9 @@ MOD_INIT(spam)
|
|||||||
{
|
{
|
||||||
PyObject* m;
|
PyObject* m;
|
||||||
|
|
||||||
MOD_DEF(m,
|
MOD_DEF(m,
|
||||||
"spam",
|
"spam",
|
||||||
"Example module",
|
"Example module",
|
||||||
module_methods,
|
module_methods,
|
||||||
-1)
|
-1)
|
||||||
|
|
||||||
+32
-48
@@ -66,67 +66,51 @@ def cibuildwheel_run(project_path, env=None, add_env=None, output_dir=None):
|
|||||||
return wheels
|
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.
|
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':
|
if platform == 'linux':
|
||||||
templates = [
|
python_abi_tags.append('cp27-cp27mu') # python 2.7 has 2 different ABI on manylinux
|
||||||
'{package_name}-{package_version}-cp27-cp27m-manylinux1_x86_64.whl',
|
platform_tags = []
|
||||||
'{package_name}-{package_version}-cp27-cp27mu-manylinux1_x86_64.whl',
|
for architecture in ['x86_64', 'i686']:
|
||||||
'{package_name}-{package_version}-cp35-cp35m-manylinux1_x86_64.whl',
|
for manylinux_version in manylinux_versions:
|
||||||
'{package_name}-{package_version}-cp36-cp36m-manylinux1_x86_64.whl',
|
platform_tags.append('{manylinux_version}_{architecture}'.format(
|
||||||
'{package_name}-{package_version}-cp37-cp37m-manylinux1_x86_64.whl',
|
manylinux_version=manylinux_version, architecture=architecture
|
||||||
'{package_name}-{package_version}-cp38-cp38-manylinux1_x86_64.whl',
|
))
|
||||||
'{package_name}-{package_version}-cp27-cp27m-manylinux2010_x86_64.whl',
|
def get_platform_tags(python_abi_tag):
|
||||||
'{package_name}-{package_version}-cp27-cp27mu-manylinux2010_x86_64.whl',
|
return platform_tags
|
||||||
'{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':
|
elif platform == 'windows':
|
||||||
templates = [
|
def get_platform_tags(python_abi_tag):
|
||||||
'{package_name}-{package_version}-cp27-cp27m-win32.whl',
|
return ['win32', 'win_amd64']
|
||||||
'{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':
|
elif platform == 'macos':
|
||||||
templates = [
|
def get_platform_tags(python_abi_tag):
|
||||||
'{package_name}-{package_version}-cp27-cp27m-macosx_10_6_intel.whl',
|
if python_abi_tag == 'cp38-cp38':
|
||||||
'{package_name}-{package_version}-cp35-cp35m-macosx_10_6_intel.whl',
|
return ['macosx_10_9_x86_64']
|
||||||
'{package_name}-{package_version}-cp36-cp36m-macosx_10_6_intel.whl',
|
else:
|
||||||
'{package_name}-{package_version}-cp37-cp37m-macosx_10_6_intel.whl',
|
return ['macosx_10_6_intel']
|
||||||
'{package_name}-{package_version}-cp38-cp38-macosx_10_9_x86_64.whl',
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
raise Exception('unsupported platform')
|
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:
|
if IS_WINDOWS_RUNNING_ON_TRAVIS:
|
||||||
# Python 2.7 isn't supported on Travis.
|
# Python 2.7 isn't supported on Travis.
|
||||||
templates = [t for t in templates if '-cp27-' 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)
|
return templates
|
||||||
for filename in templates]
|
|
||||||
|
|
||||||
platform = None
|
platform = None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user