Manylinux wheel 创建原因 "cannot repair because of the presence of too-recent versioned symbols"

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

我正在尝试使用 quay.io/pypa/manylinux_2_24_aarch64 docker 映像构建一个 manylinux wheel。

运行 /opt/python/cp37-cp37m/bin/pip3 wheel ./MYPACKAGE/ -w output 在输出目录中生成以下轮子:

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

如果我现在运行auditwheel repair ./output/MYPACKAGE-0.0.5-cp37-cp37m-linux_aarch64.whl -w ./output我得到

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.

详细的输出(此处太长 post)显示了一些政策要求:

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'}

GLIBC_2.28 要求来自哪里?哪个包需要它? auditwheel show 给出

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.

我在其他 docker 图像上也有同样的行为(特别是我试过 quay.io/pypa/manylinux2014_aarch64

我解决了。有一个名为 auditwheel-symbols 的方便工具,它列出了不兼容的依赖项:pip install auditwheel-symbols

之后更容易看出 FFmpeg 是用太新的符号编译的库:

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

我直接在 quay.io/pypa/manylinux_2_27_aarch64 docker 容器上重新编译了 FFmpeg,现在它按预期工作了。