WezTerm 发行版维护者打包指南:版本号机制、二进制拆分与 Cargo Feature 定制
【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm
WezTerm(仓库根目录)是一个用 Rust 编写的 GPU 加速跨平台终端模拟器与多路复用器。官方在 README-DISTRO-MAINTAINER.md 中为各 Linux 发行版、BSD 及包管理系统的维护者提供了完整的打包指引。本文以该文档为骨架,结合仓库内 CI 打包脚本与源码实现,系统梳理从版本号生成、发布资源选择、二进制拆分、辅助资源部署到 Cargo feature 定制的全链路实践,帮助你在自己的发行版仓库中产出规范、可维护的 WezTerm 软件包。
打包思路:以ci/deploy.sh为参考蓝图
官方维护者在文档开篇就明确:仓库中的 ci/deploy.sh 是 WezTerm 官方 CI 用来构建各平台软件包的脚本。它"可能比大多数发行版官方包更粗糙一些"(It is likely a bit more coarse than most distros would want in their official packages),但它的价值在于完整展示了一台发行版机器上各组件"应该被安装到哪里"。因此:
- 如果你的发行版有自己的打包规范(例如使用独立 spec、control、APKBUILD 而非官方脚本),不必照搬该脚本;
- 但脚本中关于二进制文件拆分、安装路径、字体处理、更新检查开关的决策,是官方认可的"标准答案",值得逐行对照参考。
从脚本结构看(ci/deploy.sh),其核心是:先由TAG_NAME决定版本串,再按$OSTYPE分支处理 macOS(darwin*)、Windows(msys|cygwin)、Linux(linux-gnu|linux)与 musl 环境(linux-musl,对应 Alpine),并为 Fedora/CentOS/SUSE 生成 RPM spec、为 Ubuntu/Debian 生成 deb 包、为 Alpine 生成 APKBUILD。
版本号机制:从 git 提交日期派生,或读取.tag文件
WezTerm 的版本号不是自增的数字版本,而是由发布所用提交的日期与短哈希共同派生,格式为YYYYMMDD-HHMMSS-HASH。官方给出的派生命令为:
git -c "core.abbrev=8" show -s "--format=%cd-%h" "--date=format:%Y%m%d-%H%M%S"这条命令的语义是:用--date=format:...将提交时间格式化为YYYYMMDD-HHMMSS,用%h取短哈希(-c core.abbrev=8指定缩写长度为 8 位),最终拼出如20260301-120000-abcdef12的版本串。仓库中这一逻辑有多处落地:
- 在 ci/deploy.sh 与 ci/source-archive.sh 中,
TAG_NAME均通过该 git 命令计算; - 在 wezterm-version/build.rs 中,
wezterm-versioncrate 的构建脚本会在无法读到.tag文件时回退到同一条 git 命令来填充WEZTERM_CI_TAG环境变量,该变量最终通过 wezterm-version/src/lib.rs 的wezterm_version()暴露给wezterm -h与TERM_PROGRAM_VERSION等场合。
非 git 仓库构建:使用.tag文件
如果你不是从 git 仓库构建(例如从官方发布的源码 tarball 构建),WezTerm 会读取源码树根目录下名为.tag的文件来确定版本。其读取逻辑位于 wezterm-version/build.rs:优先读取../.tag(相对wezterm-versioncrate 而言,即仓库根目录下的.tag),成功则直接使用其内容(去除首尾空白)作为版本串,且构建脚本会监听该文件变化(cargo:rerun-if-changed=../.tag)以触发重建。
务必使用官方*-src.tar.gz发布资源而非 GitHub 自动源码包
文档特别强调:请使用 Release 页面中的wezterm-YYYYMMDD-HHMMSS-HASH-src.tar.gz源码包进行打包,而不是 GitHub 自动生成的源码 tarball。理由有两点:
- 官方源码包体积更小——ci/source-archive.sh 会剔除
deps/harfbuzz/harfbuzz/test、deps/freetype/libpng/contrib、docs/screenshots等不需要用于构建的庞大目录,再经 gzip 压缩; - 官方源码包已经内含写好的
.tag文件——该脚本在归档前会执行echo $TAG_NAME > .tag(ci/source-archive.sh),把正确的发布版本号固化进源码树,保证任何方式构建都能得到一致的版本报告。
版本号装饰规则
如果发行版必须对版本做额外标记(例如-1.fc40这类 release 后缀),文档给出的规范是:把补充信息追加到 WezTerm 版本串末尾,形如:
YYYYMMDD-HHMMSS-HASH-EXTRA若你的包管理系统中-字符不合法,建议用.或_替换各段之间的分隔符。仓库中确有先例:RPM 分支将TAG_NAME中的-替换为_(echo ${TAG_NAME#nightly-} | tr - _,见 ci/deploy.sh),并额外追加1.${distroid}${distver}作为 Release 字段(ci/deploy.sh);Alpine 的 APKBUILD 则将pkgver中的-替换为.(ci/deploy.sh)。
二进制文件:四个组件与官方拆分建议
WezTerm 构建产物包含四个可执行文件,官方文档逐一说明了职责与打包归属:
| 二进制 | 职责 | 打包建议 |
|---|---|---|
wezterm-mux-server | 多路复用服务器,无需 GUI(headless) | 建议单独成包,便于部署到无显示服务器的系统 |
wezterm-gui | 终端的 GUI 部分 | 随 GUI 相关资源一起打包 |
wezterm | CLI 与负责启动 GUI 的前端 | 期望 mux-server 与 gui 两侧都能调用它,属于公共组件 |
strip-ansi-escapes | 从 stdin 中过滤转义序列的实用工具 | 用于"去毒"文本,例如拼接 OSC 0/1 标题文本时 |
从 ci/deploy.sh 可见,官方打包时正是将这 4 个二进制同时装配进 macOS App 包、Windows zip 与各 Linux 包中的;其 RPM 分支更是把包拆成了wezterm(元包)、wezterm-common(含wezterm、strip-ansi-escapes及 shell 补全/集成)、wezterm-gui(含 GUI 二进制与桌面集成资源)、wezterm-mux-server(仅含 headless 服务器)四个子包(ci/deploy.sh),可作为发行版拆分方案的直接参考。
附加资源:按归属分发的辅助文件
文档将辅助资源分为两组,分别跟随不同的主二进制部署:
跟随wezterm可执行文件部署:
- assets/shell-integration(
wezterm.sh等 shell 集成脚本) - assets/shell-completion(bash、fish、zsh 补全)
跟随wezterm-gui部署:
- assets/wezterm.desktop(桌面菜单项)
- assets/wezterm.appdata.xml(AppStream 元数据)
- assets/wezterm-nautilus.py(GNOME Files/Nautilus 的"在此打开"扩展)
CI 脚本中的落地路径可以作为安装参考(见 ci/deploy.sh):图标安装到/usr/share/icons/hicolor/128x128/apps/,desktop 文件到/usr/share/applications/,appdata 到/usr/share/metainfo/,Nautilus 扩展到/usr/share/nautilus-python/extensions/;Debian 分支还将 shell 补全分别安装到 bash-completion 与 zsh 的标准目录(ci/deploy.sh)。
构建定制:distro-defaultsfeature 与更新检查开关
文档强烈建议发行版构建时启用distro-defaultsRust feature:
cargo build --release -p wezterm-gui --features distro-defaults该 feature 的当前唯一效果是:check_for_updates的默认值变为false。官方发行的二进制默认会检查更新(默认值true),但发行版包通常应把升级交给包管理器管理,因此关闭自更新更合适。
其实现可以从源码得到印证:
- feature 在 wezterm-gui/Cargo.toml 中被声明为
distro-defaults = ["config/distro-defaults"],透传到 config/Cargo.toml 的同名 feature; - 真正的默认值计算在 config/src/config.rs:
fn default_check_for_updates() -> bool { cfg!(not(feature = "distro-defaults")) }即:编译时若启用了distro-defaults,check_for_updates默认为false,否则默认为true。这是一个纯粹的编译期(cfg!)分支,不依赖运行时配置。
另外值得一提的是TERM_PROGRAM_VERSION的运行时填充也依赖版本号构建逻辑(见 config/src/config.rs),这再次说明正确设置.tag/版本号会影响终端自身对外报告的身份信息。
字体捆绑与解绑:vendored-fonts及四个子 feature
为了让所有平台开箱即用且安装零负担,WezTerm 默认会把若干字体编译进二进制。如果发行版能以系统包形式提供这些字体,官方建议通过禁用对应 feature 来跳过内嵌:
| Feature | 内嵌字体 | 说明 |
|---|---|---|
vendor-nerd-font-symbols-font | Symbols Nerd Font Mono | 覆盖 Nerd Font 符号字形 |
vendor-jetbrains-font | JetBrains Mono | 默认等宽字体 |
vendor-roboto-font | Roboto | 用于 Tab 栏等 UI 文本 |
vendor-noto-emoji-font | Noto Color Emoji | 彩色 emoji |
vendored-fonts | 以上全部 | 一次性启用上述四个子 feature 的聚合开关 |
feature 的声明与聚合关系可见 wezterm-gui/Cargo.toml,它通过wezterm-fontcrate 的同名 feature(wezterm-font/Cargo.toml)控制字体源码的编译期嵌入;嵌入点在 wezterm-font/src/parser.rs,例如#[cfg(any(test, feature = "vendor-jetbrains"))]将 assets/fonts/JetBrainsMono-*.ttf 下的 16 个字形文件经include_bytes!式宏编译进二进制,vendor-noto-emoji-font对应 assets/fonts/NotoColorEmoji.ttf,vendor-nerd-font-symbols-font对应 assets/fonts/SymbolsNerdFontMono-Regular.ttf。
必须注意的最低字体要求:即便做了解绑,WezTerm 在默认配置下要正常启动,系统里至少需要提供以下两种字体(内嵌或系统安装均可):
JetBrains MonoRoboto
换言之,若你的发行版选择--no-default-features之类的构建且不内嵌字体,就必须保证这两个字体以系统包形式可用,否则终端可能无法按默认配置启动。
无 Wayland 支持环境的构建
wezterm-gui的默认 feature 为["vendored-fonts", "wayland"](见 wezterm-gui/Cargo.toml),其中wayland透传到 window crate(wayland = ["window/wayland"])。如果你的发行版不支持 Wayland,文档给出如下构建命令:
cargo build --release -p wezterm-gui --no-default-features --features distro-defaults,vendored-fonts这条命令同时做了三件事:关闭默认的 Wayland 支持、保留distro-defaults(关闭自动更新检查)、保留vendored-fonts(继续内嵌全部字体)。需要说明的是,此命令来自官方文档原样,适用于"无 Wayland 且需要内嵌字体"的场景;若发行版同时提供字体包,可将vendored-fonts替换为你需要的子 feature 组合(如vendor-jetbrains-font,vendor-roboto-font),甚至完全省略字体 feature,但务必满足上文的最低字体要求。
给维护者的延伸建议
文档在结尾处明确邀请发行版维护者:如果希望改变默认行为而现有机制无法满足,请为 WezTerm 提交 issue,以便官方针对发行版维护需求持续改进打包便利性。结合仓库现状,以下几点值得维护者留意:
- 官方 CI 生成 RPM spec 时会根据发行版自动填充
BuildRequires(如fontconfig-devel、libxkbcommon-devel、wayland-devel、mesa-libEGL-devel等,见 ci/deploy.sh),可作依赖清单参考; - Debian 分支通过
dpkg-shlibdeps自动计算运行时依赖(ci/deploy.sh),并用update-alternatives注册x-terminal-emulator(ci/deploy.sh),发行版打包时可借鉴这一"终端模拟器替代机制"的处理; - 源码包内含 termwiz/data/wezterm.terminfo,Alpine 分支用
tic将其编译进/usr/share/terminfo/w/wezterm(ci/deploy.sh),确保终端功能声明与 terminfo 数据库一致。
综上,遵循"官方源码包 + 正确版本号 + 四个二进制合理拆分 +distro-defaults定制 + 字体策略决策"这套流程,即可在发行版体系中构建出与官方行为一致、又符合本地包管理规范的 WezTerm 软件包。
【免费下载链接】weztermA GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust项目地址: https://gitcode.com/GitHub_Trending/we/wezterm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考