Search code examples
pythonpython-wheelpython-manylinux

Manylinux wheel creation causes "cannot repair because of the presence of too-recent versioned symbols"


I'm trying to build a manylinux wheel using the quay.io/pypa/manylinux_2_24_aarch64 docker image.

Running /opt/python/cp37-cp37m/bin/pip3 wheel ./MYPACKAGE/ -w output produces the following wheels in the output directory:

MYPACKAGE-0.0.5-cp37-cp37m-linux_aarch64.whl                             protobuf-3.19.1-cp37-cp37m-manylinux2014_aarch64.whl
defusedxml-0.7.1-py2.py3-none-any.whl                                    pyusb-1.2.1-py3-none-any.whl
networkx-2.6.3-py3-none-any.whl                                          six-1.16.0-py2.py3-none-any.whl
numpy-1.19.5-cp37-cp37m-manylinux2014_aarch64.whl                        typing_extensions-4.0.1-py3-none-any.whl
onnx-1.10.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

If I now run auditwheel repair ./output/MYPACKAGE-0.0.5-cp37-cp37m-linux_aarch64.whl -w ./output I get

auditwheel: error: cannot repair "./output/MYPACKAGE-0.0.5-cp37-cp37m-linux_aarch64.whl" to "manylinux_2_24_aarch64" ABI because of the presence of too-recent versioned symbols. You'll need to compile the wheel on an older toolchain.

The verbose output (too long to fully post here) shows some policy requirements:

DEBUG:auditwheel.wheel_abi:key libc.so.6, value GLIBC_2.27
DEBUG:auditwheel.wheel_abi:key libc.so.6, value GLIBC_2.28
DEBUG:auditwheel.wheel_abi:key libc.so.6, value GLIBC_2.17
[...]
DEBUG:auditwheel.policy.versioned_symbols:Package requires GLIBC_2.27, incompatible with policy manylinux_2_17_aarch64 which requires {'GLIBC_2.17', 'GLIBC_2.0', 'GLIBC_2.18'}
DEBUG:auditwheel.policy.versioned_symbols:Package requires GLIBC_2.28, incompatible with policy manylinux_2_17_aarch64 which requires {'GLIBC_2.17', 'GLIBC_2.0', 'GLIBC_2.18'}

Where is the GLIBC_2.28 requirement coming from? Which package requires it? auditwheel show gives

MYPACKAGE-0.0.5-cp37-cp37m-linux_aarch64.whl is consistent with
the following platform tag: "linux_aarch64".

The wheel references external versioned symbols in these
system-provided shared libraries: libgcc_s.so.1 with versions
{'GCC_3.0', 'GCC_4.2.0'}, libavcodec.so.57 with versions
{'LIBAVCODEC_57'}, libavutil.so.55 with versions {'LIBAVUTIL_55'},
libpthread.so.0 with versions {'GLIBC_2.17'}, libavformat.so.57 with
versions {'LIBAVFORMAT_57'}, libstdc++.so.6 with versions
{'GLIBCXX_3.4', 'GLIBCXX_3.4.15', 'GLIBCXX_3.4.21', 'GLIBCXX_3.4.19',
'CXXABI_1.3.8', 'CXXABI_1.3.2', 'GLIBCXX_3.4.22', 'GLIBCXX_3.4.14',
'CXXABI_1.3.3', 'GLIBCXX_3.4.18', 'CXXABI_1.3.11', 'CXXABI_1.3.7',
'GLIBCXX_3.4.17', 'GLIBCXX_3.4.11', 'CXXABI_1.3.5', 'CXXABI_1.3.9',
'GLIBCXX_3.4.20', 'GLIBCXX_3.4.9', 'GLIBCXX_3.4.26', 'CXXABI_1.3',
'GLIBCXX_3.4.5'}, libc.so.6 with versions {'GLIBC_2.17', 'GLIBC_2.28',
'GLIBC_2.27'}, libasound.so.2 with versions {'ALSA_0.9.0rc4',
'ALSA_0.9'}, libswresample.so.2 with versions {'LIBSWRESAMPLE_2'},
libm.so.6 with versions {'GLIBC_2.17', 'GLIBC_2.27'}, libdl.so.2 with
versions {'GLIBC_2.17'}, libudev.so.1 with versions {'LIBUDEV_183'}

This constrains the platform tag to "linux_aarch64". In order to
achieve a more compatible tag, you would need to recompile a new wheel
from source on a system with earlier versions of these libraries, such
as a recent manylinux image.

I get the same behavior on other docker images (specifically I tried quay.io/pypa/manylinux2014_aarch64)


Solution

  • I solved it. There is a handy tool called auditwheel-symbols which lists incompatible dependencies: pip install auditwheel-symbols

    After that it was easier to see that FFmpeg was the library which was compiled with too recent symbols:

    auditwheel-symbols --manylinux 2_27 ./output/MYPACKAGE-0.0.5-cp37-cp37m-linux_aarch64.whl
    _mypackage.cpython-37m-aarch64-linux-gnu.so is not manylinux_2_27 compliant because it links the following forbidden libraries:
    libavformat.so.57
    libavcodec.so.57
    libavutil.so.55
    libswscale.so.4
    usr/lib/libavcodec.so.57 is not manylinux_2_27 compliant because it links the following forbidden libraries:
    libavutil.so.55
    libswresample.so.2
    usr/lib/libavformat.so.57 is not manylinux_2_27 compliant because it links the following forbidden libraries:
    libavutil.so.55
    libavcodec.so.57
    libc.so.6       offending symbols: fcntl64@GLIBC_2.28
    

    I recompiled FFmpeg directly on the quay.io/pypa/manylinux_2_27_aarch64 docker container and now it worked as expected.