如何在本地机器上为 linux 发布二进制 Python ***
Posted
技术标签:
【中文标题】如何在本地机器上为 linux 发布二进制 Python ***【英文标题】:How to publish binary Python wheels for linux on a local machine 【发布时间】:2018-11-14 09:01:30 【问题描述】:我有一个包含 C 扩展的包,我想上传到 pypi:https://github.com/Erotemic/netharn
我在 Ubuntu 18.04 上使用命令 python setup.py bdist_wheel --py-limited-api=cp36
构建了一个***,但是当我使用 twine upload --skip-existing dist/*
进行上传时,但随后出现错误,它具有不受支持的平台标签:
HTTPError: 400 Client Error: Binary wheel 'netharn-0.0.4-cp36-abi3-linux_x86_64.whl' has an unsupported platform tag 'linux_x86_64'. for url: https://upload.pypi.org/legacy/
经过一番搜索,我发现 PEP 513 需要构建一个***来支持 manylinux(又名 Centos5):https://github.com/pypa/manylinux
他们在这里提供了一个例子:https://github.com/pypa/python-manylinux-demo/blob/master/travis/build-wheels.sh
但是,我能找到的所有示例总是使用某种 CI 服务器构建它们的二进制文件。如果可能的话,我希望能够在本地构建它们。我认为复制 docker 命令并将其构建在我自己机器上的 docker 容器中应该很简单。但是,我遇到了问题。 (我确保删除了 repo 中的任何现有 build 和 dist 目录)
我做的第一件事就是让自己沉浸在一个交互式 docker 会话中,这样我就可以玩一些东西了。我选择了 x8_64 映像并将本地目录安装到我在 docker 机器中 /io
上的代码存储库中。然后我开始了一个交互式 bash 会话。
REPO_DPATH=$HOME/code/netharn
DOCKER_IMAGE=quay.io/pypa/manylinux1_x86_64
PRE_CMD=""
# Interactive test
docker run -it --rm -v $REPO_DPATH:/io $DOCKER_IMAGE $PRE_CMD bash
在 docker 内部,我首先想为 python36 构建一个***(真的,这是我目前唯一有兴趣支持的 Python)。
PYBIN=/opt/python/cp36-cp36m/bin/
简单地安装我的 requirements.txt 似乎没有用,所以我先手动安装了几个包。在这样做之后(imgaug
是罪魁祸首,因为它依赖于特定的主构建),安装 requirements.txt 似乎工作。
cd /io
"$PYBIN/pip" install opencv_python
"$PYBIN/pip" install Cython
"$PYBIN/pip" install pytest
"$PYBIN/pip" install -e git+https://github.com/aleju/imgaug.git@master#egg=imgaug
"$PYBIN/pip" install torch # this is in the requirements.txt, but will cause problems later
"$PYBIN/pip" install -r requirements.txt
然后我运行 wheel 命令并将外部共享库捆绑到 wheel 中
"$PYBIN/pip" wheel /io/ -w wheelhouse/
for whl in wheelhouse/*.whl; do
auditwheel repair "$whl" -w /io/wheelhouse/
done
最后一步是安装包并测试
"$PYBIN/pip" install netharn --no-index -f /io/wheelhouse
(cd "$HOME"; "$PYBIN/python" -m xdoctest netharn all)
但是,当我测试它时,我得到了
ImportError: /opt/python/cp36-cp36m/lib/python3.6/site-packages/torch/_C.cpython-36m-x86_64-linux-gnu.so: ELF file OS ABI invalid
我猜这是因为torch
不支持Centos5。
我不明白torch
如何将cpython-36m-x86_64-linux-gnu.so
共享库上传到pypi,但我遇到了问题?
【问题讨论】:
torch
没有上传cpython-36m-x86_64-linux-gnu.so
,他们uploaded manylinux1_x86_64 二进制***。
为什么我的站点包中有_C.cpython-36m-x86_64-linux-gnu.so
,而当我尝试pip install torch -U
时却显示Requirement already up-to-date: torch in /home/joncrall/venv3.6/lib/python3.6/site-packages (0.4.0)
?我还没有在这台机器上从源代码构建 torch,那么为什么 pip 会给我一个 cpython-36m-x86_64-linux-gnu.so
二进制文件?
因为这个.so在manylinux1_x86_64.whl中。
有点晚了,但是 Torch 有一次(也许仍然)正在上传他们手动标记为 manylinux,尽管不是 manylinux 的***——就是这样 :)跨度>
【参考方案1】:
有以下说明的注意事项的解决方案。
pip install auditwheel twine
apt install patchelf
python setup.py bdist_wheel
auditwheel repair [[lib]]-linux_x86_64.whl -w . --plat manylinux_2_24_x86_64
twine upload [[lib]]-manylinux_2_24_x86_64.whl
上下文
我有一个我不直接拥有的带有 python 包装器的 C 库(使 CI 变得困难),用户群非常小(不需要真正的 manylinux 支持)和一个不包含包装器的官方 conda 二进制文件(不想制作竞争的 conda 频道)。
以上解决了我在 Ubuntu 20.04 上的特定需求,但请在使用前阅读以下内容。
注意事项
如果您可以控制您的存储库,那么您确实应该使用 CI。如果已设置,则无需命令行上传。 这不支持旧的/更广泛的manylinux_1
发行版如Ubuntu 20.04 is too new for it。这应该仍支持大部分 Linux 发行版,但可能无法在较旧的硬件(例如大学 HPC 集群)上运行。
直接从 docker 容器构建可能会更好。构建 + 修复工作流程很丑陋。我猜这只不过是通过一些 .so 清理来重命名文件。
【讨论】:
以上是关于如何在本地机器上为 linux 发布二进制 Python ***的主要内容,如果未能解决你的问题,请参考以下文章
在 ARM 平台上为嵌入式 Linux 交叉编译 Clion
无法使用 VS Code 在 Windows 机器上为 linux 构建 .Net core 3.0 项目