当前位置: 首页 > news >正文

解决pypi上传轮子unsupported platform tag 'linux_x86_64'问题

问题背景

在上传某轮子时出现了这样的一个报错:

$ twine upload --repository-url https://upload.pypi.org/legacy/ dist/*
Uploading distributions to https://upload.pypi.org/legacy/
Enter your username: __token__
Uploading xxx-1.0-cp37-cp37m-linux_x86_64.whl
100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 347.0/347.0 kB • 00:00 • 6.2 MB/s
WARNING  Error during upload. Retry with the --verbose option for more details.   
ERROR    HTTPError: 400 Bad Request from https://upload.pypi.org/legacy/          Binary wheel 'xxx-1.0-cp37-cp37m-linux_x86_64.whl' has an unsupported  platform tag 'linux_x86_64'.

遂发现当前的pypi对于轮子中含有C/C++等代码的库要求不同于纯Python的代码,需要经过many_linux平台的测试验证才能发布。

解决方案

经过一番检索,解决该问题的流程大致为:

  1. 选择一个合适的manylinux docker镜像,例如我这里代码中包含了CUDA,因此选择使用pytorch/manylinux-cuda111这个镜像;
  2. 基于docker镜像构建一个开发环境,然后用其中包含的几个不同版本的Python对代码进行构建,例如/opt/_internal/cpython-3.7.5/bin/python3 setup.py sdist bdist_wheel --universal,这样就会在dist目录下生成一个whl包;
  3. 使用auditwheel对前面生成的whl包进行修复:/opt/_internal/cpython-3.7.5/bin/python3 -m auditwheel repair dist/xxx-*-cp37-cp37m-linux_x86_64.whl --plat manylinux2014_x86_64 -w fix-dist/,以固化动态链接库(如有),最终会在fix-dist/路径下得到一个可以发布的轮子。

setup.py关于data_files的配置

有一些动态构建的动态链接库,直接使用MANIFEST.in或者package_data配置不生效。那么有一种解决的办法是,动态构建完成后,将生成的文件保存到build/路径(Python包构建默认路径)下,然后使用data_files的配置把相关文件包含进来:

data_files=[('xxx', ['build/xxx/libxxx.so','build/xxx/libxxx.1.so'])]

如果不使用data_files进行包装,仅仅设置packagesinclude_package_data,得到的最终轮子内容是这样的:

$ unzip -l dist/xxx-1.7-cp37-cp37m-linux_x86_64.whl 
Archive:  dist/xxx-1.7-cp37-cp37m-linux_x86_64.whlLength      Date    Time    Name
---------  ---------- -----   ----1111024  2024-08-12 09:03   xxx.cpython-37m-x86_64-linux-gnu.so1100448  2024-08-12 09:03   xxx.cpython-37m-x86_64-linux-gnu.so1265  2024-08-12 01:23   xxx/__init__.py3012  2024-08-12 06:05   xxx/__main__.py1176880  2024-08-12 09:03   xxx/xxx.c1181116  2024-08-12 09:03   xxx/xxx.c0  2024-08-12 03:15   xxx/kernels/__init__.py1063  2024-08-12 09:03   xxx-1.7.dist-info/LICENSE2071  2024-08-12 09:03   xxx-1.7.dist-info/METADATA104  2024-08-12 09:03   xxx-1.7.dist-info/WHEEL26  2024-08-12 09:03   xxx-1.7.dist-info/top_level.txt950  2024-08-12 09:04   xxx-1.7.dist-info/RECORD
---------                     -------4577959                     12 files

如果加上这个data_files的配置,whl包中会多出这么两个动态链接库:

844648  2024-08-13 02:06   xxx-1.7.data/data/xxx/xxx.1.so
844648  2024-08-13 02:06   xxx-1.7.data/data/xxx/xxx.so

需要注意的是,使用这个轮子pip安装以后,这两个文件存放的地址跟其他文件不一样(跟Python版本有关,这里我们考虑通用情景)。其他文件是存放在对应的site-packages路径下,如/usr/local/python-3.7.5/lib/python3.7/site-packages/xxx/,而data_files一般是存放在Python路径下,如/usr/local/python-3.7.5/xxx/。知道这个信息之后,我们就可以从对应的路径下去索引动态链接库了。

总结概要

对于一个纯Python的项目,从构建到发布是比较容易的。但是如果构建的轮子中含有C代码或者生成的动态链接库,那么构建发布有另外一套规则。我们需要经过manylinux平台的验证,以及动态链接库的固化等过程,还需要当心动态链接库的存放地址等信息。本文主要是提供了一个流程化的思路,具体操作对于不同的项目和平台来说差异是比较大的。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/pypi-manylinux.html

作者ID:DechinPhy

更多原著文章:https://www.cnblogs.com/dechinphy/

请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Qt 实战(9)窗体 | 9.2、QDialog
  • 【秋招笔试】8.11大疆秋招(第二套)-测开岗
  • 如何使用 Jupyter Notebook
  • 1Panel配置
  • C++(27): 线程池
  • 【自动驾驶】自定义消息格式的话题通信(C++版本)
  • 【CS.DB】数据库-关系型数据库-MySQL-3.4.数据的插入_查询_更新和删除
  • 安防监控/视频汇聚平台EasyCVR如何配置,实现默认获取设备的子码流?
  • 探索NSAppleScript的魔法:Objective-C与AppleScript的无缝对接
  • centos7系统更新阿里镜像源地址
  • Java流程控制01:用户交互Scanner
  • 如何将列数据转换为行数据——SQL和EF Core(C#)两种实现方式
  • 【Linux】
  • Java开发代码规范文档
  • windows 安装TVM
  • 4个实用的微服务测试策略
  • angular2 简述
  • Brief introduction of how to 'Call, Apply and Bind'
  • ESLint简单操作
  • HTTP那些事
  • JavaScript设计模式与开发实践系列之策略模式
  • Laravel 中的一个后期静态绑定
  • LeetCode18.四数之和 JavaScript
  • SAP云平台里Global Account和Sub Account的关系
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • Spring Boot MyBatis配置多种数据库
  • 飞驰在Mesos的涡轮引擎上
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 全栈开发——Linux
  • 小程序开发中的那些坑
  • 一份游戏开发学习路线
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • ‌移动管家手机智能控制汽车系统
  • #define,static,const,三种常量的区别
  • #include到底该写在哪
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (31)对象的克隆
  • (7)svelte 教程: Props(属性)
  • (9)目标检测_SSD的原理
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (一)C语言之入门:使用Visual Studio Community 2022运行hello world
  • (一)utf8mb4_general_ci 和 utf8mb4_unicode_ci 适用排序和比较规则场景
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)详解PHP处理密码的几种方式
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .NET delegate 委托 、 Event 事件
  • .net 中viewstate的原理和使用
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .net6Api后台+uniapp导出Excel
  • .NET技术成长路线架构图
  • ??如何把JavaScript脚本中的参数传到java代码段中