☰
Tsukimi 的 COPR 打包实践:基于 SCM 源类型与 `make srpm` 的 Rust 依赖 Vendor 构建方案
2026/10/3 2:02:30 网站建设 项目流程
  • 桌面应用
  • 音视频

【免费下载链接】tsukimi

A simple third-party Jellyfin client for Linux

项目地址:https://gitcode.com/gh_mirrors/ts/tsukimi
点击查看免费下载

本篇技术指南聚焦 Tsukimi(README.md 中定义的一款基于 GTK4 的 Linux 第三方 Jellyfin 客户端)在 Fedora COPR 仓库中的打包与持续构建方案。Tsukimi 是一个重度依赖 Rust crate 生态的 GNOME 风格应用,Fedora 官方源无法完整覆盖其全部依赖,因此仓库提供了基于 SCM 源类型 +make srpm方法的定制化打包链路,并同时支持稳定版与开发快照两套 RPM 包。读完本文,你将掌握.copr/Makefile的完整打包流程、COPR 项目推荐的配置参数、版本号自动推导规则,以及如何在一个 COPR 项目中同时维护tsukimi与tsukimi-git两个包。

为什么普通的 COPR SCM 构建不适合 Tsukimi

COPR 的经典 SCM 构建方式是:COPR 拉取 Git 仓库后,直接用仓库内指定的.spec文件(例如tsukimi.spec)执行rpmbuild。但这种方式对 Tsukimi 并不适用,原因在 docs/COPR.md 中写得很明确:

Fedora 可能不会提供该应用所需的每一个 Rust crate 依赖。

换句话说,tsukimi.spec的BuildRequires只声明系统级依赖(cargo、meson、pkgconfig(gtk4)等),Rust crate 层面的依赖则需要从 crates.io 拉取。在 Fedora 官方的 Rust 打包体系中,%cargo_build宏会优先使用系统安装的 crate,但 Fedora 仓库未必收录了 Tsukimi 的完整依赖树——例如 crates/tsukimi/Cargo.toml 中依赖的mutsumi、dandanapi-client、moka、glycin等 crate 就不一定都有对应的 Fedora 包。

因此,文档给出的结论是:必须放弃纯 SCM 构建,改用 SCM 源类型配合make srpm方法,在进入rpmbuild之前先把所有 Rust 依赖"vendor"(离线缓存)成源码包。

SCM +make srpm:一条完整的离线依赖打包链路

仓库根目录下的 .copr/Makefile 是这条链路的执行者。当 COPR 以make srpm方法构建时,会执行该 Makefile 的srpm目标(.copr/Makefile),其整体流程分为四个阶段:

  1. 准备构建环境:dnf -y install cargo git-core python3 rpm-build rust zstd,确保系统具备打包所需的工具链。
  2. 生成主源码 tarball:通过git archive --format=tar.gz从当前 checkout(HEAD)导出带name-version/前缀目录的源码归档,即Source0: %{name}-%{version}.tar.gz。
  3. Vendor 全部 Rust 依赖:执行cargo vendor --locked(.copr/Makefile),把所有锁定版本(来自仓库根目录 Cargo.lock)的 crate 下载到本地目录,并生成.cargo/config.toml;随后用sed将配置中的directory路径改写为相对的vendor,保证离线构建时路径可解析。
  4. 生成第二个归档并构建 SRPM:将.cargo与vendor目录打包成%{name}-%{version}-vendor.tar.zst(zstd 压缩),即Source1,再调用rpmbuild -bs产出符合 spec 的 SRPM。

tsukimi.spec中对这两个源归档的引用清晰可见(tsukimi.spec):

Source0: %{name}-%{version}.tar.gz Source1: %{name}-%{version}-vendor.tar.zst

而%prep阶段的%autosetup -a 1(tsukimi.spec)会在解压主源码后,自动解包第二个归档(-a 1即 Source1),把 vendor 依赖与.cargo/config.toml一起放进构建目录,从而让cargo build完全离线进行,不依赖 Fedora 是否收录某个 crate。

推荐 COPR 项目配置

根据 docs/COPR.md,在 COPR 项目设置页面中应按下表配置:

配置项推荐值
Source TypeSCM
SCM Methodmake srpm
Spec Filetsukimi.spec
Clone URL本 Git 仓库地址
ChrootFedora 44+

Chroot 选择 Fedora 44+ 的原因与tsukimi.spec的BuildRequires版本下限直接相关(tsukimi.spec):

  • pkgconfig(gtk4) >= 4.22
  • pkgconfig(libadwaita-1) >= 1.8

这两个版本要求同时也被 meson.build 在 Meson 配置阶段强制校验(gtk4 与 libadwaita 的最低版本甚至由构建脚本从 Cargo.toml 的 feature 中自动提取)。只有 Fedora 44 及以上的 chroot 才能满足,因此文档明确标注了这一前提。

版本号自动推导规则

COPR 的 SCM checkout 可以指向任意 commit,可能是一个精确 tag,也可能是中间提交。.copr/Makefile对此做了两套处理(.copr/Makefile):

  • 精确落在 tag 上:执行git describe --tags --exact-match HEAD,命中后去掉前缀v(如v26.6.1→26.6.1),同时剥离-copr后缀,把该 tag 直接作为 RPMVersion,并通过--define "version_from_tag ..."注入 rpmbuild。
  • 不在任何 tag 上:回退到从crates/tsukimi/Cargo.toml读取package.version(当前为26.9.2,见 crates/tsukimi/Cargo.toml),同样以version_from_tag传入。

tsukimi.spec侧的对应逻辑位于头部(tsukimi.spec):

%global fallback_version 26.9.2 %global pkg_version %{?version_from_tag:%{version_from_tag}}%{!?version_from_tag:%{fallback_version}}

即:优先使用 Makefile 推导并注入的version_from_tag,若缺失(例如本地直接rpmbuild而非经 Makefile),则回退到fallback_version。这与 meson.build 中声明的项目版本26.9.2保持一致,保证构建时三处版本信息不会互相打架。

在同一个 COPR 项目中同时维护稳定版与开发快照

如果想在同一 COPR 项目中额外提供"每日构建"性质的开发快照包,文档给出的方案是在项目中添加第二个 package source,使用tsukimi-git.spec:

  • 稳定包:tsukimi,Spec File: tsukimi.spec
  • HEAD 包:tsukimi-git,Spec File: tsukimi-git.spec

tsukimi-git.spec专为构建当前 HEAD commit 设计,其 SRPM 生成器注入两个关键宏(tsukimi-git.spec):

%global pkg_version %{?version_from_git:%{version_from_git}}%{!?version_from_git:%{fallback_version}} %global snapshot_release %{?git_snapshot:%{git_snapshot}}%{!?git_snapshot:1}
  • Version:取自crates/tsukimi/Cargo.toml,由.copr/Makefile用tomllib读取并注入version_from_git(.copr/Makefile);
  • Release:格式化为0.<YYYYMMDD>git<shortsha>,由git log -1 --date=format:%Y%m%d取提交日期、git rev-parse --short=10 HEAD取 10 位短哈希拼装而成,通过git_snapshot注入(.copr/Makefile)。

在tsukimi-git.spec的Release: 0.%{snapshot_release}%{?dist}中,0.前缀刻意小于稳定包以%autorelease生成的大版本号(tsukimi.spec),从而保证同一个 RPM 版本号下,开发快照永远排在稳定版之后,两个包可以和平共处于同一 COPR 项目中而不会互相覆盖。此外tsukimi-git.spec还声明了Conflicts: tsukimi(tsukimi-git.spec),明确告知 RPM 两个包不可同时安装,避免二进制与资源文件冲突。

这套设计的价值在于:tagged releases 与开发快照在版本空间上天然分离,用户既可以安装稳定的tsukimi,也可以选择跟踪最新的tsukimi-git,而维护者只需在 COPR 界面添加一个 package source 即可。

构建依赖与系统要求一览

无论是tsukimi.spec还是tsukimi-git.spec,BuildRequires完全一致,反映了 Tsukimi 的系统级构建需求(tsukimi.spec):

类别依赖及版本要求
语言工具链cargo、rust >= 1.85、gcc
构建系统meson、ninja-build、pkgconfig、python3
桌面集成desktop-file-utils、gettext
GTK 生态pkgconfig(gtk4) >= 4.22、pkgconfig(libadwaita-1) >= 1.8、pkgconfig(gio-2.0) >= 2.76、pkgconfig(glib-2.0) >= 2.76、pkgconfig(epoxy)
音视频后端pkgconfig(mpv) >= 0.38、pkgconfig(gstreamer-1.0) >= 1.16及 audio/base/play/plugins 系列模块
其他pkgconfig(dbus-1)、pkgconfig(openssl)

构建阶段使用 Meson 并以沙箱化方式关闭系统 Rust 包索引(tsukimi.spec):

%meson \ -Dsandboxed-build=true \ -Drust-target=release %meson_build

-Dsandboxed-build=true正是配合上文 vendor 方案的关键开关,它让 Cargo 完全依赖Source1提供的离线 vendor 目录,而不是尝试访问 crates.io 或系统 crate 索引。

本地验证与手动调试

.copr/Makefile同样可以在本地手工执行,用于调试或复现 COPR 的行为。其srpm目标支持两个隐式变量(.copr/Makefile):

  • spec:指定要构建的 spec 文件(默认tsukimi.spec);
  • outdir:SRPM 与源码归档的输出目录。

典型用法是进入仓库根目录后执行make -f .copr/Makefile srpm spec=tsukimi.spec outdir=/tmp/out,即可在本地生成tsukimi-<version>.tar.gz、tsukimi-<version>-vendor.tar.zst与最终 SRPM,验证版本推导与 vendor 打包逻辑是否符合预期。

构建完成后,普通用户可直接通过 README 中给出的 Fedora 安装方式使用这些产物(README.md):

sudo dnf copr enable walker874/tsukimi sudo dnf install tsukimi

小结

Tsukimi 的 COPR 打包方案围绕一个核心矛盾展开:应用依赖大量 Rust crate,而 Fedora 官方源无法完整覆盖。通过SCM + make srpm组合,.copr/Makefile 把cargo vendor --locked的离线依赖以独立源码归档(Source1)的形式注入 SRPM,使tsukimi.spec可以在任何 chroot 中可复现地构建;同时借助tsukimi-git.spec与version_from_git/git_snapshot宏,实现了稳定版与每日快照在同一 COPR 项目中的共存。对于希望在 COPR 上打包其他重依赖 Rust GUI 应用的维护者,这套"vendor 离线化 + 双 spec 版本隔离"的实践具有很强的直接参考价值。

相关文件:.copr/Makefile · tsukimi.spec · tsukimi-git.spec · crates/tsukimi/Cargo.toml · meson.build · README.md

  • 桌面应用
  • 音视频

【免费下载链接】tsukimi

A simple third-party Jellyfin client for Linux

项目地址:https://gitcode.com/gh_mirrors/ts/tsukimi
点击查看免费下载

相关推荐

上一篇:AGEIPort终极指南:阿里巴巴高性能数据导入导出框架完全解析
下一篇:Skia 2D图形渲染引擎终极指南:从基础架构到高性能应用

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询