尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

niri 发行版打包完全指南:构建选项、桌面会话安装、依赖与测试(Packaging-niri)

niri 发行版打包完全指南:构建选项、桌面会话安装、依赖与测试(Packaging-niri) niri 发行版打包完全指南构建选项、桌面会话安装、依赖与测试Packaging-niri【免费下载链接】niriA scrollable-tiling Wayland compositor.项目地址: https://gitcode.com/GitHub_Trending/ni/niri导读niri 是一个可滚动平铺scrollable-tiling的 Wayland 合成器。本文面向发行版维护者与打包者系统讲解如何将 niri 构建为原生二进制、按标准目录布局安装为独立桌面会话使其出现在 GDM 等登录管理器中、正确声明运行时依赖、处理版本字符串与 panic 回溯以及如何在打包环境中运行测试。读完本文你将能基于当前仓库的源码与resources/下的官方文件产出符合 niri 上游预期的系统级软件包。一、构建选项feature 与默认构建1.1 从Cargo.toml查看构建特性打包 niri 的第一步是查看仓库根目录的 Cargo.toml 中定义的 feature 列表。当前版本的 workspace 成员包括niri-config、niri-ipc与niri-visual-tests主包名为niri。在 Cargo.toml 中定义的 features 如下Feature说明default默认启用包含dbus、systemd、xdp-gnome-screencastdbus启用 D-Bus 支持提供各类 freedesktop 与 GNOME 接口、无障碍树、电源键处理systemd启用 systemd 集成全局环境、应用放入 transient scope隐式依赖dbusxdp-gnome-screencast通过 xdg-desktop-portal-gnome 启用屏幕录制隐式依赖dbus与pipewireprofile-with-tracy启用 Tracy profiler 插桩profile-with-tracy-ondemand按需启用的 Tracy profiler 插桩profile-with-tracy-allocations启用 Tracy 分配分析dinit启用 dinit 集成全局环境1.2 替换集成目标systemd 换 dinit默认 feature 组合dbus,systemd,xdp-gnome-screencast对绝大多数发行版来说足够好用。但如果你的发行版使用 dinit 作为服务管理器可以用下面的命令把 systemd 集成替换为 dinit 集成cargo build --release --no-default-features --features dinit,dbus,xdp-gnome-screencastdinitfeature 在 Cargo.toml 中被定义为空 featuredinit []它不额外引入 Rust 依赖而是配合resources/dinit/下的服务文件使用。1.3 警告不要使用--all-features[!WARNING]切勿以--all-features构建 niri部分 feature 仅为开发用途设计。例如profile-with-tracy*系列会启用把 profiling 数据收集进内存缓冲区的逻辑该缓冲区会无限增长直到内存耗尽。这些开发专用 feature 与niri-visual-tests一样都不应进入发行包。上游在打包脚本 niri.spec.rpkg 中也是只走默认 feature 构建并显式从测试中排除niri-visual-tests。二、安装布局让 niri 成为独立桌面会话上游推荐把 niri 打包为独立桌面会话standalone desktop session。这样安装后 niri 会出现在 GDM 等显示管理器的会话列表中用户可像选择 GNOME、KDE 一样直接登录 niri。2.1 文件安装对照表根据仓库根目录 Cargo.toml 中package.metadata.generate-rpm与package.metadata.deb两段元数据它们与文档给出的安装布局完全一致以及 niri.spec.rpkg 中的%install段标准安装位置如下文件构建产物/仓库资源目标目录target/release/niri/usr/bin/resources/niri-session/usr/bin/resources/niri.desktop/usr/share/wayland-sessions/resources/niri-portals.conf/usr/share/xdg-desktop-portal/resources/niri.servicesystemd/usr/lib/systemd/user/resources/niri-shutdown.targetsystemd/usr/lib/systemd/user/resources/dinit/niridinit/usr/lib/dinit.d/user/resources/dinit/niri.targetdinit/usr/lib/dinit.d/user/按上表安装后/usr/share/wayland-sessions/niri.desktop的存在即会让 GDM 及其他显示管理器识别 niri 会话。2.2 各资源文件的内容与作用niri.desktopresources/niri.desktop是一个标准的 Desktop EntryExecniri-sessionDesktopNamesniri供登录管理器显示会话选项。niri-sessionresources/niri-session是会话启动脚本其逻辑相当完整值得打包者通读一遍若以用户服务方式运行存在MANAGERPID且SYSTEMD_EXEC_PID等于当前 PID且父进程是systemd --user则直接exec niri --session把会话管理交给外部 systemd否则检查$SHELL是否在/etc/shells中以登录 shell 方式重新执行自身优先检测 systemd检查niri.service未在运行、systemctl --user reset-failed清理失败状态、import-environment导入登录管理器环境、dbus-update-activation-environment --all同步 D-Bus 环境然后systemctl --user --wait start niri.service会话结束时启动niri-shutdown.target--job-modereplace-irreversibly最后清理WAYLAND_DISPLAY、DISPLAY、XDG_SESSION_TYPE、XDG_CURRENT_DESKTOP、NIRI_SOCKET等环境变量若无 systemd 则检测 dinit校验 dinit 用户守护进程在运行、未启动过的 niri、把登录环境导入 dinit、创建$HOME/.local/share/niri日志目录、dinitctl --user start niri.target并用dinit-monitor等待其退出两者都没有时提示使用niri --session。niri.serviceresources/niri.service是 systemd 用户单元Typenotifyniri 会通过 sd-notify 上报就绪、ExecStartniri --session并BindsTographical-session.target、Wantsxdg-desktop-autostart.target保证桌面自启动项在 niri 就绪后运行。niri-shutdown.targetresources/niri-shutdown.target用于会话退出时统一停止graphical-session.target及其依赖StopWhenUnneededtrue、Conflictsgraphical-session.target graphical-session-pre.target。dinit 单元resources/dinit/niriresources/dinit/niri是type process的服务command niri --session通过ready-notification pipevar:NOTIFY_FD上报就绪日志写入$HOME/.local/share/niri/niri.logdepends-on: dbusresources/dinit/niri.targetresources/dinit/niri.target是type internal的目标单元除依赖 niri 外还会waits-for.d扫描用户与系统的niri.d/目录以加载用户自定义服务。参考链接关于发行版集成的进一步说明见 Integrating niri 页面。三、推荐依赖保证开箱即用3.1libwayland-server动态加载的核心依赖首先必须确保 niri 依赖libwayland-server。该库目前是**动态加载dlopen**的因此在 niri 构建期不会被 Cargo 自动纳入依赖清单——打包者必须手动为软件包声明这一运行时依赖。这在 Fedora 打包脚本 niri.spec.rpkg 中有明确体现# Loaded through dlopen Requires: libwayland-server3.2 可选但强烈推荐的依赖以下依赖是可选的但上游强烈建议安装并在可能的情况下将其声明为自动安装的可选依赖automatically-installed optional dependenciesxwayland-satellite运行 X11 应用Steam、Discord 等所必需。注意当前仓库采用集成 Xwayland 方案Fedora 打包脚本中声明Requires: xwayland-satellite 0.7见 niri.spec.rpkgxdg-desktop-portal-gnome屏幕录制screencasting所必需xdg-desktop-portal-gtk在niri-portals.conf中被配置为回退 portalfallback属于通常应当安装的标准回退 portalgnome-keyring在niri-portals.conf中被配置为 Secret portal 的提供者发行版的 GPU 驱动包如mesa-dri-drivers与mesa-libEGL。硬件加速正常工作对运行 niri 是必需条件通知守护进程如mako多数应用依赖其正常工作。resources/niri-portals.conf 的实际内容印证了上述配置[preferred] defaultgnome;gtk; org.freedesktop.impl.portal.Accessgtk; org.freedesktop.impl.portal.Notificationgtk; org.freedesktop.impl.portal.Secretgnome-keyring;3.3 默认配置中绑定的应用你可能还希望自动安装 niri 默认配置文件 中通过spawn绑定的应用搜索spawn关键字即可找到例如终端alacritty与启动器fuzzel。Fedora 打包脚本的做法是把它们作为弱依赖声明niri.spec.rpkgRecommends: alacritty Recommends: fuzzel Recommends: swaylock Recommends: waybar Recommends: swaybg Recommends: mako Recommends: swayidle四、在打包环境中运行测试niri 的大部分测试会自行拉起合成器实例并连接测试用 Wayland 客户端因此不需要图形会话即可运行。但测试采用并行执行在高核数机器上可能触及文件描述符上限。如果遇到该问题需要同时限制 Rust 测试框架的线程数以及 Rayon 的线程数——部分 niri 测试内部使用了 Rayon 线程池export RAYON_NUM_THREADS2 # 然后运行 cargo test可以搭配 --test-threads2另外注意务必排除仅用于开发的niri-visual-testscrate。上游打包脚本正是这样做的niri.spec.rpkg%cargo_test -- --workspace --exclude niri-visual-tests部分测试需要测试时可用surfaceless EGL。若无法满足可以跳过它们cargo test -- --skip::egl可以设置环境变量RUN_SLOW_TESTS1来运行较慢的测试。仓库中的测试代码分布可参考 src/layout/tests/、src/tests/ 等目录其中包含大量 insta 快照如 niri__tests__window_opening__check_fullscreen_maximize.snap用于断言窗口布局行为。五、版本字符串提交哈希与完整覆盖5.1 版本字符串的构成niri 的版本字符串包含版本号与提交哈希$ niri --version niri 25.01 (e35c630)在打包系统中构建时通常没有 Git 仓库提交哈希不可用版本会显示为 unknown commit。5.2 手工设置提交哈希这种情况下请手工设置提交哈希export NIRI_BUILD_COMMITe35c630 # 然后构建 niri5.3 完全覆盖版本字符串你也可以整体覆盖版本字符串但请确保其中保留对应的 niri 版本号export NIRI_BUILD_VERSION_STRING25.01-1 (e35c630) # 然后构建 niri5.4 源码级原理从源码看src/utils/mod.rs 中的version()函数依次读取若设置了NIRI_BUILD_VERSION_STRING环境变量直接原样返回否则取CARGO_PKG_VERSION_MAJOR/MINOR/PATCH再取NIRI_BUILD_COMMIT若未设置则回退到git_version!宏失败时显示unknown commit组装为MAJOR.MINOR (commit)或MAJOR.MINOR.PATCH (commit)格式patch 为 0 时省略 patch 段。Fedora 打包脚本正是通过在.cargo/config.toml的[env]段注入NIRI_BUILD_COMMIT来实现该行为的见 niri.spec.rpkg。5.5 对cargo install的提醒请记得对cargo build和cargo install都设置这些变量——cargo install在环境变化时会重新构建 niri若只在构建时设置会导致安装出的二进制版本字符串不对。六、Panic 回溯质量验收的硬指标6.1 为什么需要好的回溯良好的 panic 回溯对诊断 niri 崩溃至关重要。用户在合成器首次崩溃时通常没有安装 debuginfo 包因此上游要求niri 包本身不安装 debuginfo 或其他包就应产生良好的回溯。6.2 用niri panic验证请使用niri panic命令测试你的包能否产生良好的回溯$ niri panic thread main panicked at /builddir/build/BUILD/rust-1.83.0-build/rustc-1.83.0-src/library/core/src/time.rs:1142:31: overflow when subtracting durations stack backtrace: 0: rust_begin_unwind at /builddir/build/BUILD/rust-1.83.0-build/rustc-1.83.0-src/library/std/src/panicking.rs:665:5 1: core::panicking::panic_fmt at /builddir/build/BUILD/rust-1.83.0-build/rustc-1.83.0-src/library/core/src/panicking.rs:74:14 2: core::panicking::panic_display at /builddir/build/BUILD/rust-1.83.0-build/rustc-1.83.0-src/library/core/src/panicking.rs:264:5 3: core::option::expect_failed at /builddir/build/BUILD/rust-1.83.0-build/rustc-1.83.0-src/library/core/src/option.rs:2021:5 4: expectcore::time::Duration at /builddir/build/BUILD/rust-1.83.0-build/rustc-1.83.0-src/library/core/src/option.rs:933:21 5: sub at /builddir/build/BUILD/rust-1.83.0-build/rustc-1.83.0-src/library/core/src/time.rs:1142:31 6: cause_panic at /builddir/build/BUILD/niri-0.0.git.1699.279c8b6a-build/niri/src/utils/mod.rs:382:13 7: main at /builddir/build/BUILD/niri-0.0.git.1699.279c8b6a-build/niri/src/main.rs:107:27 8: call_oncefn() - core::result::Result(), alloc::boxed::Boxdyn core::error::Error, alloc::alloc::Global, () at /builddir/build/BUILD/rust-1.83.0-build/rustc-1.83.0-src/library/core/src/ops/function.rs:250:5 note: Some details are omitted, run with RUST_BACKTRACEfull for a verbose backtrace.6.3 检查要点对照回溯输出需要确认三点panic 消息存在overflow when subtracting durations回溯完整走到main且包含cause_panic帧回溯包含cause_panic的文件与行号at /.../src/utils/mod.rs:382:13。从当前源码看cause_panic实现在 src/utils/mod.rs#[inline(never)] pub fn cause_panic() { let a Duration::from_secs(1); let b Duration::from_secs(2); let _ a - b; }它刻意构造一次 Duration 减法下溢来触发 panic且用#[inline(never)]保证回溯中保留独立帧CLI 侧的命令入口在 src/cli.rs/// Cause a panic to check if the backtraces are good.的Panic变体。6.4 打包实践为了不依赖 debuginfo 包也能得到好的回溯Fedora 打包脚本做了两件事见 niri.spec.rpkg将%global debug_package %{nil}与%global __strip /bin/true不剥离主二进制的调试信息保留 Cargo.toml 中[profile.release]的debug line-tables-only见 Cargo.toml用仅行表的调试信息在体积与可诊断性之间取得平衡。七、Rust 依赖离线构建与锁定版本7.1 使用 vendored 依赖离线构建每个 niri 发布版都会附带一份由cargo vendor生成的依赖归档可用于完全离线构建对应版本。若不想使用 vendored 依赖则应当遵循该发布版附带的 Cargo.lock其中记录了上游测试该发布版时使用的精确依赖版本。7.2 特别留意smithay与smithay-drm-extras如果必须调整某些依赖的版本请额外关注smithay与smithay-drm-extras的 commit hash。这两个 crate 目前没有常规的稳定版本发布niri 使用的是 git 快照——在 Cargo.toml 中可以看到它们都指向 Smithay 仓库的同一个rev 4cf0b62028039661477d482ec4758b687d8f4392。由于上游经常发生破坏性变更API 与行为两方面强烈建议使用 niri 发布版Cargo.lock中的精确 commit hash。7.3 构建期系统依赖打包 niri 还需要一系列构建期系统库。从 niri.spec.rpkg 的BuildRequires可以看到完整清单udev、gbm、xkbcommon、wayland-devel、libinput、dbus-1、systemd、libseat、libdisplay-info、pipewire-devel、pango、cairo-gobject-devel以及 pipewire-rs 编译所需的clang和测试用的mesa-libEGL。八、Shell 补全生成可以用niri completions SHELL为多种 shell 生成补全脚本例如niri completions bash运行niri completions -h可查看完整支持列表。Fedora 打包脚本在构建后生成 bash、fish、zsh 三套补全并分别安装niri.spec.rpkg 与%install段target/rpm/niri completions bash ./niri target/rpm/niri completions fish ./niri.fish target/rpm/niri completions zsh ./_niri九、打包自检清单完成打包后建议逐项核对以默认 features 构建未使用--all-featureslibwayland-server已作为运行时依赖声明可选依赖xwayland-satellite、xdg-desktop-portal-gnome、xdg-desktop-portal-gtk、gnome-keyring、GPU 驱动、通知守护进程已尽可能声明8 个文件按安装对照表放到正确目录GDM 中能出现 niri 会话niri --version输出版本号与提交哈希而非 unknown commit在不安装 debuginfo 的情况下运行niri panic回溯能追溯到cause_panic的文件与行号测试已排除niri-visual-tests必要时设置RAYON_NUM_THREADS、--test-threads、--skip::egl与RUN_SLOW_TESTS1依赖锁定在发布版Cargo.lock尤其是smithay与smithay-drm-extras的 commit已生成并安装 bash/fish/zsh 补全脚本。参考实现Fedora 的完整打包脚本见 niri.spec.rpkg可作为其他发行版打包的直接参照。【免费下载链接】niriA scrollable-tiling Wayland compositor.项目地址: https://gitcode.com/GitHub_Trending/ni/niri创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表