Apache Arrow Linux 软件包构建指南:基于 Rake 与 Docker 一键产出 .deb 与 .rpm
【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow
Apache Arrow 仓库内置了一套完整的 Linux 二进制软件包构建流水线,用于为 Arrow C++ 核心库与 GLib 绑定(c_glib)产出 Debian/Ubuntu 的.deb包和 AlmaLinux/Amazon Linux/CentOS 的.rpm包。本指南以 dev/tasks/linux-packages/README.md 为主体,结合仓库内 Rake 任务、Docker 构建脚本与打包模板,讲解如何构建全部或指定平台的软件包、如何进入容器控制台调试失败的构建,以及整套流水线在源码层面的运行原理。读完本文,你将能够在本地克隆仓库中直接驱动这套官方打包体系,产出可用于自建 APT/YUM 仓库的 Arrow 二进制包。
一、构建环境要求
官方文档列出的前置条件只有三项:
- Ruby:用于运行 Rake 构建任务(仓库中所有打包逻辑都以
Rakefile+ Ruby 类实现); - Docker:实际的编译打包发生在容器内部,宿主机只需编排容器;
- 构建 Apache Arrow C++ 与 GLib 的 tar.gz 源码包的工具:即
git archive等生成上游源码归档的能力。
从源码结构看,dev/tasks/linux-packages/Rakefile 通过require_relative "../../release/binary-task"与require_relative "helper"加载基础能力,并维护了三个待构建的软件包:
packages = [ "apache-arrow", "apache-arrow-apt-source", "apache-arrow-release", ]其中apache-arrow是主体(C++ 与 GLib 运行时/开发包),apache-arrow-apt-source与apache-arrow-release分别是 APT 源包与 YUM 仓库配置包。顶层的apt:build、yum:build、version:update任务会依次进入每个包目录递归执行同名子任务。
二、构建全部平台的 .deb 包
官方给出的全量构建命令如下:
cd dev/tasks/linux-packages/apache-arrow rake version:update rake apt:buildrake version:update会先同步版本信息(详见第五节),rake apt:build则对所有默认启用的平台逐个产出.deb包。从 package-task.rb 中的apt_targets_default可以看出,当前仓库默认启用的 APT 目标为:
debian-trixiedebian-forkyubuntu-jammyubuntu-nobleubuntu-resolute
(对应目录为 dev/tasks/linux-packages/apache-arrow/apt/,另存在debian-trixie-arm64、ubuntu-noble-arm64等 arm64 变体目录,但默认被注释禁用,原因是「arm64 目标需要在宿主机上做额外配置」——若你的宿主是 aarch64,仍可手动指定这些目标。)
注意:顶层的 dev/tasks/linux-packages/Rakefile 也暴露了apt:build,它会顺带构建apache-arrow-apt-source这个 APT 源配置包。若只想构建 Arrow 本体,按官方文档进入apache-arrow子目录执行即可。
三、构建指定平台的 .deb 包
3.1 查看所有受支持的平台
在仓库根目录执行以下命令,即可列出 APT 侧全部受支持的平台目录名:
for x in dev/tasks/linux-packages/apache-arrow/apt/{debian,ubuntu}*; do basename $x; done输出即为各APT_TARGETS可用的取值,例如debian-trixie、ubuntu-noble、ubuntu-resolute等。官方特别强调该命令必须从arrow克隆仓库的根目录执行,因为其中使用了相对路径。
3.2 用 APT_TARGETS 指定目标
通过环境变量APT_TARGETS(逗号分隔)可以只构建关心的平台:
cd dev/tasks/linux-packages/apache-arrow rake version:update rake apt:build APT_TARGETS=debian-bookworm,ubuntu-noble从apt_targets的实现(package-task.rb)可以看到:APT_TARGETS以逗号切分,若未设置则回落到默认目标列表;随后会逐一过滤,只保留在apt/目录下真实存在对应子目录的目标。因此传入不存在的平台名会被静默跳过,而不是报错。
四、构建 .rpm 包
4.1 全部平台构建
cd dev/tasks/linux-packages/apache-arrow rake yum:build对应的默认 YUM 目标(来自yum_targets_default):
almalinux-10almalinux-9almalinux-8amazon-linux-2023centos-9-stream
对应目录位于 dev/tasks/linux-packages/apache-arrow/yum/,同样存在almalinux-9-aarch64等 aarch64 变体目录,默认不启用。
4.2 查看支持平台并指定目标
for x in dev/tasks/linux-packages/apache-arrow/yum/{alma,amazon,centos}*; do basename $x; done指定平台则使用YUM_TARGETS:
cd dev/tasks/linux-packages/apache-arrow rake yum:build YUM_TARGETS=almalinux-9,amazon-linux-2023五、调试构建:进入容器控制台
编译失败时,全自动构建脚本会在出错时立即退出,难以排查。为此打包框架提供了apt:build:console与yum:build:console两个交互式任务:它们会照常准备源码、挂载目录,但不自动执行构建脚本,而是打开一个 Bash 提示符让你手动操作。
5.1 调试 .deb 构建
cd dev/tasks/linux-packages/apache-arrow rake version:update rake apt:build:console APT_TARGETS=debian-bookworm官方示例展示了宿主与容器内的协作方式:
host$ rake apt:build:console APT_TARGETS=debian-bookworm container$ /host/build.sh进入容器后执行/host/build.sh即可启动.deb构建;即使构建失败,Bash 会话也会保留,你可以在现场查看日志、检查/build目录、手动重跑debuild等,完成排查后再退出。
5.2 调试 .rpm 构建
cd dev/tasks/linux-packages/apache-arrow rake yum:build:console YUM_TARGETS=almalinux-9host$ rake yum:build:console YUM_TARGETS=almalinux-9 container$ /host/build.sh同样地,容器内执行/host/build.sh触发rpmbuild,失败后会话保留以供调试。
从实现上看(package-task.rb 的docker_run),console: true时容器运行命令不追加/host/build.sh参数,并以交互终端方式挂载当前目录到容器的/host:rw;由于当前目录(即apache-arrow包目录)被挂载,容器内才能访问/host/build.sh、/host/tmp/、/host/repositories/等路径。宿主机上若设置了BUILD_DIR环境变量,还会额外将该目录挂载到容器的/build:rw,保证构建中间产物落在宿主机上。
六、构建流水线的源码级原理
6.1 版本检测与归档准备
rake version:update与构建任务都会先确定版本号。helper.rb 中的detect_version优先读取环境变量ARROW_VERSION,否则解析 cpp/CMakeLists.txt 中的set(ARROW_VERSION "..."),并把-SNAPSHOT后缀替换为-devYYYYMMDD(日期取自ARROW_RELEASE_TIME环境变量或仓库最近一次 git 提交时间)。
版本号随后被解析为 Debian/RPM 两套语义(package-task.rb):
| 版本形态 | Debian upstream 版本 | RPM 版本 / Release |
|---|---|---|
X.Y.Z(正式版) | X.Y.Z | X.Y.Z/1 |
X.Y.Z-rcN(发布候选,rc_build_type=:release) | X.Y.Z | X.Y.Z/1 |
| 其他 dev/rc 形态 | X.Y.Z~devN或X.Y.Z~rcN | X.Y.Z/0.X |
rake version:update的具体工作(define_version_task→update_debian_changelog/update_spec)包括:为各debian*目录的changelog追加一条New upstream release.条目(署名取DEBFULLNAME/NAME或 git 用户信息),以及向 arrow.spec.in 的%changelog写入新记录并重置Release。
源码归档(tar.gz)的来源有三种(define_archive_task):正式版从 Apache 镜像下载、-rcN版本通过gh release download从 GitHub 拉取、其余形态直接用git archive HEAD从当前克隆生成。
6.2 模板替换:control.in 与 arrow.spec.in
打包模板不是写死的。Debian 侧,debian/control.in 内含@USE_SYSTEM_OPEN_TELEMETRY@、@CUDA_ARCHITECTURE@等占位符;apache-arrow/Rakefile 中的apt_prepare_debian_control会按目标平台替换:
- CUDA 架构:arm64 目标可用
any,否则为i386 amd64; - OpenTelemetry:
ubuntu-jammy/ubuntu-noble强制使用 bundled 版本,其余平台优先使用系统opentelemetry-cpp-dev,其中debian-trixie额外启用SYSTEM_OPEN_TELEMETRY_REQUIRE_GRPC。
RPM 侧,yum_build读取 arrow.spec.in,将@PACKAGE@、@VERSION@、@RELEASE@替换后生成临时 spec 文件;该 spec 内还根据 RHEL/Amazon Linux 版本条件化启用 bundled Abseil、GCS、gRPC、ORC 等功能(例如use_bundled_absl、have_grpc等宏)。
6.3 Docker 容器编排
对每个目标,docker_run(package-task.rb)执行两步:
docker build:以目标目录下的 Dockerfile(或from文件描述的镜像)为基础构建编译环境镜像。以 ubuntu-noble/Dockerfile 为例,镜像内预装build-essential、cmake、meson、ninja-build、ccache、mold、GObject Introspection、valac、各类 Arrow 依赖库(brotli/bz2/lz4/snappy/zstd/thrift/re2 等)以及条件安装的nvidia-cuda-toolkit;arm64 目标若不存在 Dockerfile,则读取 from 指定基础镜像,必要时自动切换到docker buildx build --platform=linux/arm64。docker run:将包目录挂载到/host:rw,将BUILD_DIR(可选)挂载到/build:rw,并把DEBUG、DEB_BUILD_OPTIONS、RPM_BUILD_NCPUS等环境变量传入容器,最终执行/host/build.sh。
YUM 侧的 almalinux-9/Dockerfile 则预装gcc-toolset-12(SCL 工具链)、rpmdevtools、ccache以及boost-devel、thrift-devel、llvm-devel等构建依赖。
6.4 容器内的实际构建脚本
APT(apt/build.sh):容器启动后读取/host/env.sh(由宿主机写入PACKAGE、VERSION),按lsb_release判定发行版(Debian 组件为main,Ubuntu 为universe),将源码包复制为${PACKAGE}_${VERSION}.orig.tar.gz,按目标选择debian.<platform>-<arch>或通用debian目录,然后执行debuild -us -uc。脚本默认启用 ccache(CCACHE_MAXSIZE=3GiB),DEB_BUILD_OPTIONS未设置时默认parallel=$(nproc)并行编译,并临时关闭随机构建目录后缀以保证可复现性。产物最终被收集到宿主机挂载目录下的repositories/<dist>/pool/<codename>/<component>/<initial>/<package>/。
YUM(yum/build.sh):读取/host/env.sh中的SOURCE_ARCHIVE/PACKAGE/VERSION/RELEASE,解析/etc/system-release-cpe判断发行版与版本(含CentOS Stream后缀),通过rpmdev-setuptree(或手动)建立rpmbuild目录树,拷贝 spec 与源码包后执行rpmbuild -ba。若镜像设置了SCL(如gcc-toolset-12),还会通过scl enable切换工具链并对 annobin 插件做兼容处理。RPM 与 SRPM 分别输出到repositories/<dist>/<version>/<arch>/Packages与repositories/<dist>/<version>/Source/Packages。
6.5 Debian 侧编译选项
debian/rules 以dh $@ --with gir驱动,并通过override_dh_auto_configure向 CMake 传入一整套构建选项,例如:
- 功能开关:
ARROW_COMPUTE=ON、ARROW_CSV=ON、ARROW_DATASET=ON、ARROW_FLIGHT=ON、ARROW_FLIGHT_SQL=ON、ARROW_GANDIVA=ON、ARROW_GCS=ON、ARROW_HDFS=ON、ARROW_JSON=ON、ARROW_MIMALLOC=ON、ARROW_ORC=ON、ARROW_PARQUET=ON、ARROW_S3=ON; - 工具链:
ARROW_USE_MOLD=ON(使用 mold 链接器)、ARROW_USE_CCACHE=OFF(由 debuild 层统一管理 ccache); - 压缩/序列化依赖:
ARROW_WITH_BROTLI/BZ2/LZ4/SNAPPY/ZLIB/ZSTD=ON、ARROW_WITH_OPENTELEMETRY=ON; - 构建类型
relwithdebinfo,并针对resolute等新发行版禁用 LTO 规避 GCC 15 崩溃。
七、关键环境变量速查
以下变量在整个打包流程中可直接影响行为(均以宿主机环境传入 Rake/Docker):
| 变量 | 作用 | 默认值 |
|---|---|---|
APT_TARGETS | 逗号分隔的 APT 目标列表 | 全部默认平台 |
YUM_TARGETS | 逗号分隔的 YUM 目标列表 | 全部默认平台 |
ARROW_VERSION | 覆盖自动检测的 Arrow 版本 | 解析自 cpp/CMakeLists.txt |
ARROW_RELEASE_TIME | 覆盖发布/构建时间(用于 changelog 与 dev 版本号) | 最近 git 提交时间 |
DEBUG | 设为no关闭调试输出,否则构建脚本输出详细日志并保留现场 | yes(ENV["DEBUG"] != "no"即视为开启) |
BUILD_DIR | 宿主机构建目录,挂载到容器/build | 不挂载 |
DEB_BUILD_OPTIONS | 透传给 debuild,默认parallel=$(nproc) | 并行编译 |
RPM_BUILD_NCPUS | 透传给 rpmbuild 的并行度 | 由 spec 决定 |
DEB_RELEASE | Debian 包的 Debian revision | 1 |
DEBFULLNAME/DEBEMAIL | changelog 署名 | git 用户信息 |
GITHUB_REPOSITORY | 影响 Docker 镜像名与 rc 归档下载仓库 | apache/arrow |
此外,为了配合reprotest验证可复现构建,APT 容器还会透传CPU_LIST、FAKETIME、HOME、LANG、LANGUAGE、LC_ALL、NO_FAKE_STAT、TZ等环境变量(见 package-task.rb 的pass_through_env_names),其中FAKETIME会通过LD_PRELOAD注入 libfaketime。
八、注意事项与实践建议
- arm64 目标默认关闭:
apt_targets_default与yum_targets_default都把 aarch64 变体注释掉,官方注释说明「需要宿主机额外配置」。在 x86_64 宿主上想构建 arm64 包时,需依赖buildx跨架构模拟,并自行确认基础镜像可用。 - 正式版与 RC 版的归档来源不同:
-rcN版本依赖 GitHub CLI(gh release download),需要先配置gh认证;正式版则从 Apache 镜像下载。 - 先
version:update再构建:官方所有构建示例都先执行rake version:update,因为它负责更新 changelog、spec 等元数据,跳过它可能导致版本信息与归档不一致。 - 产物目录:
.deb/.rpm最终输出在apache-arrow/apt/repositories/与apache-arrow/yum/repositories/下(容器内以宿主机当前用户属主落盘),该目录结构已按 Debian pool 与 YUM 仓库布局组织,可直接配合apache-arrow-apt-source、apache-arrow-release两个辅助包搭建自己的分发源。 - 可复现性:构建脚本刻意固定了构建目录名(避免 meson 生成的 pkgconfig 携带随机绝对路径),配合
FAKETIME/CPU_LIST等 reprotest 注入变量,可用于验证同一版本在不同环境下的构建结果一致性。
【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考