KLayout PyPI 发布流程详解:从 wheel 到源码包用 twine 上传 KLayout Python 包

发布时间:2026/10/14 17:44:42
KLayout PyPI 发布流程详解:从 wheel 到源码包用 twine 上传 KLayout Python 包 硬件开发桌面应用图形学【免费下载链接】klayoutKLayout Main Sources项目地址https://gitcode.com/gh_mirrors/kl/klayout点击查看免费下载本文以仓库中的 ci-scripts/twine/README.md 为核心讲清 KLayout 独立 Python 包klayout即src/pymod对应的 pymod 发布体系如何把构建好的 wheel 文件和源码 tarball 上传到 PyPI。读完后你可以完整掌握本地构建产物如何组织、上传命令及其参数演进从travis upload到twine upload、版本号从何而来以及仓库中 Jenkins / Azure Pipelines 两条自动化发布链路是如何把构建—测试—上传串起来的。一、文档核心流程先上传 wheel再上传源码包ci-scripts/twine/README.md 记录的是当时 KLayout 向 PyPI 发布klayout包的完整手工操作分为两个阶段。1. 定位到 wheel 部署目录并上传所有 wheel构建完成后产物会集中部署到一个dist-pymod风格的目录中文档举例为/Users/tlima/Dropbox/Apps/travis-deploy/Builds/klayout/dist-pymod/0.26.0.dev10。进入该目录后执行travis upload *.whl该命令执行时会提示输入与你的 PyPI 账号关联的 username 和 password这是travis-pypi-tool时代的交互方式凭据由工具本地缓存。*.whl通配符会把该目录下所有平台的 wheel如 manylinux、win32 等版本一次性上传。2. 构建源码 tarball 并上传wheel 上传成功后回到 KLayout 的 git 源码目录执行python setup.py sdist在生成的dist/目录中会找到类似klayout-0.26.0.dev10.tar.gz的源码包然后执行travis upload klayout-0.26.0.dev10.tar.gz这样就完成了wheel sdist两类产物的 PyPI 发布。文档中示例版本号0.26.0.dev10是当时开发版的命名当前仓库 version.sh 中的中央版本配置为KLAYOUT_VERSION0.30.12 # The version used for PyPI (dont use variables here!) KLAYOUT_PYPI_VERSION0.30.12setup.py sdist生成的包名版本正是读取KLAYOUT_PYPI_VERSION——setup.py 中Config.version()用正则从version.sh提取该值并作为setup(nameconfig.root, versionconfig.version(), ...)的参数传入。因此手工上传前应先确认version.sh中的KLAYOUT_PYPI_VERSION是目标发布版本否则 tarball 文件名例如klayout-0.30.12.tar.gz会与预期不符。3. 源码包内容如何界定setup.py sdist打进去哪些文件由 MANIFEST.in 决定。当前清单递归收录了各模块的*.cc、*.h、pysetup.toml如src/pymod、src/pya/pya、src/tl/tl等、数据库插件源码src/plugins/*/db_plugin以及version.sh和src/py.typed。这保证了从 PyPI 下载 sdist 的用户能在有编译器环境下重建整个klayoutPython 包。二、产物从哪里来wheelhouse 与 setup.py 构建文档中travis-deploy 目录下的 wheel并非凭空产生。从仓库的构建脚本看产物的标准落地位置是wheelhouse/目录ci-scripts/docker/docker_build.shmanylinux 容器内构建脚本的核心构建与验证步骤# Compile wheel and build source distribution cd /io /opt/python/$PY_VERSION/bin/python setup.py bdist_wheel -d /io/wheelhouse/ || exit 1 /opt/python/$PY_VERSION/bin/python setup.py sdist --formatszip -d /io/wheelhouse || exit 1 # Bundle external shared libraries into the wheels via auditwheel for whl in /io/wheelhouse/*linux_*.whl; do auditwheel repair $whl -w /io/wheelhouse/ || exit 1 done # Install packages and test TEST_HOME/io/testdata /opt/python/$PY_VERSION/bin/pip install klayout --no-index -f /io/wheelhouse || exit 1 /opt/python/$PY_VERSION/bin/python $TEST_HOME/pymod/import_db.py || exit 1 /opt/python/$PY_VERSION/bin/python $TEST_HOME/pymod/import_rdb.py || exit 1 /opt/python/$PY_VERSION/bin/python $TEST_HOME/pymod/import_tl.py || exit 1 /opt/python/$PY_VERSION/bin/python $TEST_HOME/pymod/pya_tests.py || exit 1几点值得注意的实现细节均可在仓库源码中核实构建命令是setup.py bdist_wheel/setup.py sdist。setup.py顶部注释解释了 KLayout 共享对象架构对打包的挑战Python 扩展库下划线前缀如_tl、_gsi依赖一批实现库distutils 只能用extra_objects方式注入依赖Linux 上还要用-Wl,-soname去掉路径、-Wl,-rpath,$ORIGIN保证运行期按相对路径查找。这些链接参数在 setup.py 的Config.link_args()中实现。auditwheel repair 是 manylinux 标签的前提把lib_*libcurl、libexpat、libz、libpng 等打进 wheel使 wheel 获得 manylinux 标签。ci-scripts/docker/README.md 明确说This command will generate a wheel and place it inwheelhouse/klayout-*manylinux1*.whl. This is the wheel that needs to be uploaded to PyPI via twine.——这正是 twine 上传文档的产物来源。上传前自带冒烟测试构建脚本在安装 wheel 后运行testdata/pymod/下的import_db.py、import_rdb.py、import_tl.py和pya_tests.py确保上传到 PyPI 的 wheel 至少能导入核心模块。Jenkins 版本脚本 ci-scripts/docker/docker_build_jenkins.sh 流程相同只是通过环境变量KLAYOUT_SETUP_MULTICORE1限制为单核编译避免压垮 Jenkins 宿主机而setup.py中读取该变量来决定编译线程数默认取multiprocessing.cpu_count()并对CCompiler.compile做了并行编译的 monkey-patch。三、从 travis upload 到 twine文档命令在当前仓库中的演进ci-scripts/twine/README.md 中的travis upload属于 Travis CI 时期的travis-pypi-tool用法。当前仓库的发布链路已改用twine且凭据不再交互式输入而是通过 CI 变量注入。两处可直接核实的实现1. Jenkins 流水线Jenkinsfile-pypiJenkinsfile-pypi 的完整发布逻辑platform pypi_platform() py_version pypi_py_version() currentBuild.description PyPI deployment platform docker_image jenkins-manylinux2014_x86_64-pypi target platform .whl node(linux) { stage(Checkout sources) { checkout scm } stage(Building target ${target}) { sh(rm -rf wheelhouse ; mkdir -p wheelhouse) withDockerContainer(image: docker_image, args: -v pwd() :/io) { sh(PY_VERSION py_version /io/ci-scripts/docker/docker_build_jenkins.sh) } } stage(Publish and test) { // publish for release tags if (BRANCH_NAME.startsWith(pypi_)) { sh(twine upload --skip-existing wheelhouse/klayout-*manylinux2014*.whl wheelhouse/*.zip) } } }对照手工文档可以看到三个关键差异手工流程travis READMEJenkinsfile-pypitwinetravis upload *.whltwine upload --skip-existing wheelhouse/klayout-*manylinux2014*.whl wheelhouse/*.zippython setup.py sdisttar.gz 落dist/sdist --formatszip -d /io/wheelhouse在容器脚本内完成产物为.zip与 wheel 一起上传交互式输入 username/password凭据由 Jenkins 凭据系统管理命令行不再交互任意时机可执行仅当分支名以pypi_开头发布专用分支/标签才上传--skip-existing参数表示遇到 PyPI 上已存在的同一版本文件时跳过而不是报错这使得发布任务可安全重跑PyPI 不允许覆盖已发布版本。2. Azure PipelinesWindows 侧的上传azure-pipelines.yml 末尾的上传阶段与 Jenkins 版本风格一致但使用TWINE_*环境变量显式注入凭据- bash: | pip install -U twine twine upload --skip-existing $BUILD_ARTIFACTSTAGINGDIRECTORY/* env: TWINE_USERNAME: $(TWINE_USERNAME) TWINE_PASSWORD: $(TWINE_PASSWORD) TWINE_REPOSITORY_URL: $(TWINE_REPOSITORY_URL) displayName: Uploading to PyPI condition: startsWith(variables[Build.SourceBranch], refs/tags/)从这段配置可以推断其上传策略多个并行任务产出的各版本 Windows wheelwheel-3.10.x64…wheel-3.14.x86等 artifact先被下载到工作区再用CopyFiles把**/*.whl扁平化到 staging 目录上传条件为startsWith(variables[Build.SourceBranch], refs/tags/)——只有从 git 标签触发的构建才会真正上传到 PyPI与 Jenkinsfile-pypi 的pypi_前缀分支策略属于同一思路把发布与日常构建严格区分开。3. 当前 Linux 轮子构建已迁移到 cibuildwheelpyproject.toml 中配置了[tool.cibuildwheel]说明当前仓库的 wheel 构建主力已从手工 manylinux 容器命令迁移到 cibuildwheel[tool.cibuildwheel] build-verbosity 3 test-command [ python {package}/testdata/pymod/import_db.py, python {package}/testdata/pymod/import_rdb.py, python {package}/testdata/pymod/import_tl.py, python {package}/testdata/pymod/import_lib.py, python {package}/testdata/pymod/import_lay.py, TESTSRC{package} python {package}/testdata/pymod/pya_tests.py ] skip pp* cp36-* cp37-* cp38-* cp39-* [tool.cibuildwheel.linux] before-all source {project}/ci-scripts/docker/docker_prepare.sh archs [auto64] environment { PATH/usr/lib/ccache:/usr/lib64/ccache:/usr/lib/ccache/bin:$PATH } before-build ccache -s environment-pass [HOST_CCACHE_DIR] [tool.cibuildwheel.macos] repair-wheel-command delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v --ignore-missing-dependencies {wheel}可见构建前用 ci-scripts/docker/docker_prepare.sh 准备 manylinux/musllinux 环境安装 zlib、curl、expat、libpng 开发包并配置 ccacheccache上限设为 5G每个 wheel 构建后仍运行testdata/pymod/下的同一组导入测试与pya_tests.py与容器脚本一脉相承macOS 侧用delocate-wheel约束见 cibw_constraints.txt 中delocate0.10.7修复依赖对应 Linux 侧的auditwheel repair职责skip pp* cp36-* cp37-* cp38-* cp39-*表示不构建 PyPy 与 Python 3.6–3.9 的 wheel这是当前发布矩阵的实际兼容边界。四、把完整流程串起来一次 KLayout PyPI 发布结合文档与当前源码一次发布实际经历以下环节以仓库现状为准定版确认 version.sh 中KLAYOUT_PYPI_VERSION为目标版本当前为0.30.12。sdist/wheel 的包名版本都由它决定。构建 wheelLinux 走 cibuildwheelmanylinux 容器 docker_prepare.sh或 Jenkins 的jenkins-manylinux2014_x86_64-pypi镜像 docker_build_jenkins.shWindows 走 Azure Pipelines 各 Python 版本任务macOS 由 cibuildwheel delocate-wheel处理。构建源码包setup.py sdist容器内为--formatszip -d /io/wheelhouse。内容清单由 MANIFEST.in 决定包含全部 C 模块源码与pysetup.toml模块描述文件。构建后自检安装产物并运行testdata/pymod/的import_db.py、import_rdb.py、import_tl.py、import_lib.py、import_lay.py、pya_tests.py。上传twine upload --skip-existing wheelhouse/...whl ...zip凭据来自 CI 变量TWINE_USERNAME/TWINE_PASSWORD/TWINE_REPOSITORY_URL且仅在发布专用分支pypi_*或 git 标签refs/tags/*触发的构建中执行。五、实操要点与注意事项不要重复发布同一版本号PyPI 禁止覆盖已上传文件--skip-existing只是让重跑不报错若修改了构建产物仍需提升KLAYOUT_PYPI_VERSION后重新打 tag/走发布分支。sdist 与 wheel 要成对发布文档的wheel 先行、sdist 随后顺序保证了即使某平台缺 wheelpip 也能回退到 sdist 本地编译前提是有 C 工具链与 curl/expat/png 等构建依赖见 setup.py 头部注释列出的 build requirements。travis upload命令已退役若按旧文档操作请将其理解为twine upload的前身当前仓库所有发布路径均以twine upload --skip-existing为准。凭据管理早期交互式输入 username/password 的方式只适合一次性手工发布自动化场景一律使用TWINE_*环境变量注入且上传动作被分支/标签条件守卫。参考文件清单本文核心文档ci-scripts/twine/README.md版本中央配置version.sh打包脚本setup.py、MANIFEST.in、pyproject.toml、cibw_constraints.txt构建脚本ci-scripts/docker/README.md、ci-scripts/docker/docker_build.sh、ci-scripts/docker/docker_build_jenkins.sh、ci-scripts/docker/docker_prepare.sh发布流水线Jenkinsfile-pypi、azure-pipelines.yml构建后测试脚本testdata/pymod/赞分享硬件开发桌面应用图形学【免费下载链接】klayoutKLayout Main Sources项目地址https://gitcode.com/gh_mirrors/kl/klayout点击查看免费下载相关推荐runanywhere Python 发行包构建与 PyPI 发布全流程从 pybind11 Wheel 到 twine 上传runanywhere Python 发行包构建与 PyPI 发布全流程从 pybind11 Wheel 到 twine 上传 runanywhere 是 RAI模型推理服务推理引擎本地部署多模态终极指南如何用 Twine 快速发布 Python 包到 PyPI终极指南如何用 Twine 快速发布 Python 包到 PyPI Twine 是 Python 包发布的终极利器 这个强大的工具专门用于将 Pytho开发工具OpenUSD 的 PyPI 打包与发布指南从 build_scripts/pypi 到 usd-core Wheel 包OpenUSD 的 PyPI 打包与发布指南从 build_scripts/pypi 到 usd core Wheel 包 本篇技术指南聚焦 OpenUSD图形学3D渲染创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询