news 2026/9/19 19:03:47

XGBoost Python 包打包详解:构建二进制 Wheel 与源码发行版(sdist)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
XGBoost Python 包打包详解:构建二进制 Wheel 与源码发行版(sdist)

XGBoost Python 包打包详解:构建二进制 Wheel 与源码发行版(sdist)

【免费下载链接】xgboostScalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library, for Python, R, Java, Scala, C and more. Runs on single machine, Hadoop, Spark, Dask, Flink and DataFlow项目地址: https://gitcode.com/gh_mirrors/xg/xgboost

本文基于仓库中的 doc/contrib/python_packaging.rst 展开,系统讲解 XGBoost Python 包两种标准分发形态——源码发行版(sdist)与二进制 wheel——的构建方法、产物差异与底层原理。读完后,你将能够自行构建可分发的 XGBoost 包,并理解其中 CMake 构建后端、共享库打包与运行时库查找机制的完整链路。

两种分发机制:sdist 与 wheel

Wheel 和源码发行版(source distribution,简称 sdist)是打包和分发 Python 包的两种主要机制:

  • 源码发行版(sdist):一个 tarball(.tar.gz扩展名),包含源码。
  • wheel:一个 ZIP 压缩归档(.whl扩展名),代表一个已构建的发行版。与 sdist 不同,wheel 可以包含编译产物。编译产物在分发前已完成编译,对终端用户而言安装 wheel 更方便。包含编译产物的 wheel 称为二进制 wheel(binary wheel)

理解这两种形态的关键差异在于:wheel 是"构建完成"的产物,sdist 是"构建原料"的产物。对 XGBoost 这样的 C++ 核心 + Python 绑定项目,这一差异直接体现在"是否需要在pip install时现场编译"上。

构建源码发行版(sdist)

对 XGBoost 而言,sdist 同时包含 Python 代码和 C++ 代码,因此 XGBoost 的核心部分可以被编译成共享库libxgboost.so(不同操作系统下共享库文件名不同,见结尾脚注)。

你可以用如下命令获得 sdist:

$ python -m build --sdist .

(执行前需要先安装build包:pip install buildconda install python-build。)

用 sdist 执行pip install会启动 CMake 和 C++ 编译器,把捆绑的 C++ 代码编译为libxgboost.so

$ pip install -v xgboost-2.0.0.tar.gz # 加 -v 可查看构建进度

仓库源码视角:sdist 如何做到自包含

上面的python -m build --sdist .在当前仓库结构下应在 python-package/ 目录中执行(该目录下的 pyproject.toml 声明了构建系统)。这里有一个值得注意的工程细节:sdist 需要把仓库根目录的整个 C++ 源码树塞进发行版,但构建后端的打包规则只能看到项目根目录之下的文件。仓库用一个独立脚本来解决这一点,即 ops/script/prepare_sdist.py:

  • 它把srcincludedmlc-corecmakeplugin五个 C++ 子目录,连同根目录的CMakeLists.txtLICENSE,整体拷贝到python-package/cpp_src/暂存目录;
  • 脚本是幂等的:每次运行先清空并重建暂存目录;
  • 它必须在python -m build --sdist之前运行。

pyproject.toml 中的相应配置印证了这一流程:

[tool.scikit-build] # Source distributions ship the C++ tree under cpp_src/, staged by # ops/script/prepare_sdist.py before `python -m build --sdist`. sdist.include = ["cpp_src/**"] sdist.exclude = ["build/", "dist/", "wheelhouse/", "*.pyc", "__pycache__"] sdist.reproducible = true

其中sdist.reproducible = true开启可复现构建(归档内文件时间戳等元数据归一化),保证同一版本多次打出的 sdist 字节一致,便于校验与审计。

CI 中完整的 sdist 验证流程可见 ops/pipeline/test-python-sdist.sh:先运行prepare_sdist.py暂存 C++ 源码树,再进入python-package/执行python -m build --sdist,随后用pip install -v ./dist/xgboost-*.tar.gz从 sdist 现场编译安装,最后以python -c 'import xgboost'确认导入成功。脚本中还演示了通过--config-settings cmake.define.CMAKE_C_COMPILER_LAUNCHER=sccache给 CMake 注入编译缓存加速器的用法。

构建二进制 wheel

你也可以构建 wheel:

$ pip wheel --no-deps -v .

--no-deps表示不连带构建/下载依赖。)

需要特别指出的是,产物 wheel 中包含一份共享库libxgboost.so的拷贝。由于含有编译二进制,这是一个二进制 wheel

用二进制 wheel 执行pip install时,pip 只把 wheel 内容解压到当前 Python 环境。由于 wheel 内已经带有预构建的libxgboost.so,安装时无需再构建,因此pip install一个二进制 wheel 能很快完成:

$ pip install xgboost-2.0.0-py3-none-linux_x86_64.whl # 快速完成

(文件名中的版本号、Python ABI 标签与平台标签是 wheel 命名规范的一部分:py3-none-linux_x86_64表示纯 Python 3 兼容、无特定 C 扩展 ABI、面向 Linux x86_64。)

仓库源码视角:wheel 中的 libxgboost 从何而来

Python 侧的构建入口是 python-package/CMakeLists.txt,它支持两种构建模式:

  1. 复用预构建库:如果${C++ 源码}/lib/目录下已存在libxgboost.{so,dylib,dll}(通常由 CI 先在仓库根用 CMake 构建好),则直接把该库安装进 wheel 的xgboost/lib/目录。源码中还专门处理了 SOVERSION 符号链接(.so -> .so.3 -> .so.3.3.0)的情况——先file(REAL_PATH ...)解析到底层实体文件再安装,避免 wheel 打包器丢弃悬空软链。
  2. 从源码编译:如果没有预构建库(例如pip install python-package/或从 sdist 安装的场景),该 CMakeLists 通过add_subdirectory()挂载 C++ 源码树现场编译。sdist 安装时 C++ 树位于本文件旁边的cpp_src/(由prepare_sdist.py暂存),仓库内构建时则指向父目录。

两种路径最终都把共享库以无版本号的文件名安装为xgboost/lib/下的libxgboost.so(或对应平台名),这正是 Python 端加载器期望的位置。

pyproject.toml中与 wheel 构建直接相关的配置:

[build-system] requires = ["scikit-build-core>=0.11.0"] build-backend = "scikit_build_core.build" [tool.scikit-build] build-dir = "build/{wheel_tag}" ninja.make-fallback = true wheel.py-api = "py3" wheel.packages = ["xgboost"] # Only install rules tagged with COMPONENT XGBoostPython make it into the # wheel. C++ subprojects (e.g. dmlc-core) register their own install() rules # for headers / static libs / CMake configs that we don't want inside the # Python wheel; this filter quietly skips all of them. install.components = ["XGBoostPython"] [tool.scikit-build.cmake] version = "CMakeLists.txt" build-type = "Release"

几个关键点:

  • 构建后端是scikit-build-core,它驱动 CMake 完成 C++ 编译并组装 wheel;build-type = "Release"指定优化编译;
  • install.components = ["XGBoostPython"]是一个过滤器:只有带该 COMPONENT 标签的安装规则才会进入 wheel,从而把 dmlc-core 等 C++ 子项目面向系统安装的 headers/静态库/CMake 配置规则全部排除在外;
  • ninja.make-fallback = true允许在没有 Ninja 时回退到 Makefile 生成器。

另外,pyproject.toml 文件头注明其由 ops/script/pypi_variants.py 自动生成(当前变体为--use-suffix=na --require-nccl-dep=cu13),用于派生不同发行渠道所需的依赖组合——例如 CUDA 13 变体在 Linux 上额外声明nvidia-nccl-cu13运行时依赖。

CI 中对 wheel 的验证

CI 的 wheel 测试脚本 ops/pipeline/test-python-wheel.sh 演示了官方对 wheel 产物的验收方式:安装./wheelhouse/*.whl后,对于 GPU 变体,会调用from xgboost import build_info读取build_info()["CUDA_VERSION"],断言 wheel 实际是用预期大版本的 CUDA 构建的,再按 CPU/GPU/多 GPU/ARM64 等套件分别运行对应测试集。这为"二进制 wheel 必须与宣传的构建环境一致"提供了可执行的验证手段。

运行时如何找到共享库

为什么 wheel 必须把libxgboost.so打进xgboost/lib/?答案在 python-package/xgboost/libpath.py 的find_lib_path()

  • 首先找包内的xgboost/lib/("normal, after installationlibis copied into Python package tree")——这对应 wheel 安装的场景,库就内置在包目录里;
  • 其次找仓库布局下的../../lib/(editable 安装时不做拷贝);
  • 最后回退到系统前缀sys.base_prefix/lib,并在 Windows 上追加若干 Conda 目录;
  • 找不到时抛出XGBoostLibraryNotFound,错误信息中列出所有候选路径以便排查。

文件名也是按平台硬编码映射的:Linux/FreeBSD/Emscripten 为libxgboost.so,macOS 为libxgboost.dylib,Windows 为xgboost.dll,Cygwin 为cygxgboost.dll。这与 python-package/CMakeLists.txt 中_XGB_LIBNAME的平台分支一一对应。

相关配置速查

主题位置说明
构建后端声明python-package/pyproject.tomlscikit-build-core>=0.11.0sdist.include = ["cpp_src/**"]
C++ 树暂存ops/script/prepare_sdist.py打 sdist 前把src/include/dmlc-core/cmake/plugin拷入python-package/cpp_src/
wheel 打包 CMakepython-package/CMakeLists.txt预构建库复用 / 源码编译两种模式
sdist CI 验证ops/pipeline/test-python-sdist.shsdist 构建 + 现场编译安装 +import xgboost冒烟
wheel CI 验证ops/pipeline/test-python-wheel.sh安装 wheel 并核对build_info()的 CUDA 版本
运行时库查找python-package/xgboost/libpath.py按平台解析共享库名与候选路径
共享库构建文档doc/build.rstCMake 选项(USE_CUDAUSE_NCCL等)与平台库名

共享库文件名的平台差异

脚注(继承原文档):共享库文件名会随操作系统变化——

  • Linux 及其他类 UNIX 系统:libxgboost.so
  • macOS:libxgboost.dylib
  • Windows:xgboost.dll

完整的共享库构建说明参见仓库文档 doc/build.rst 中 "Building the Shared Library" 一节(即原文档脚注引用的build_shared_lib锚点),其中还给出了 GPU(USE_CUDA)、NCCL(USE_NCCLUSE_DLOPEN_NCCL)、HIDE_CXX_SYMBOLS等常用 CMake 选项。

小结

  • sdist 是"源码 + 构建配方",pip install时由 CMake 现场编译libxgboost.so,适合无法提供 wheel 的目标平台,代价是安装慢、要求本机有 C++ 工具链;
  • 二进制 wheel 内置预编译的libxgboost.so(安装到xgboost/lib/),pip install秒级完成,是终端用户的首选;
  • 两条链路的公共基石是 python-package/ 下由 scikit-build-core 驱动的 CMake 构建,配合install.components = ["XGBoostPython"]过滤确保 wheel 内容精确可控;
  • 复现 CI 行为时,参考 ops/pipeline/test-python-sdist.sh 与 ops/pipeline/test-python-wheel.sh 中的命令序列即可。

【免费下载链接】xgboostScalable, Portable and Distributed Gradient Boosting (GBDT, GBRT or GBM) Library, for Python, R, Java, Scala, C and more. Runs on single machine, Hadoop, Spark, Dask, Flink and DataFlow项目地址: https://gitcode.com/gh_mirrors/xg/xgboost

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 19:03:17

340+精选AI提示词模板:论文写作与PDF翻译的完整实操指南

340精选AI提示词模板:论文写作与PDF翻译的完整实操指南 【免费下载链接】awesome-prompts Curated list of chatgpt prompts from the top-rated GPTs in the GPTs Store. Prompt Engineering, prompt attack & prompt protect. Advanced Prompt Engineering pa…

作者头像 李华
网站建设 2026/9/19 19:02:17

方波信号的傅里叶分解与合成:MATLAB实验与吉布斯现象解析

简介:信号与系统课程中关于信号分解与合成实验的完整报告文档,适合电子信息类本科在读学生、备考或开展信号处理实验的初学者使用。内容依托实验五任务,涵盖方波与三角波信号的分解、各次谐波提取与再合成,并给出示波器观测结果、…

作者头像 李华
网站建设 2026/9/19 19:01:50

Nimmake:面向MCU的跨架构固件构建DSL工具

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/19 19:00:49

初中物理电路教学:从串并联定义到实物连接诊断

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华