如何在 NixOS 上用 shell.nix 或 flake.nix 配置 Iced 的系统依赖与开发环境
【免费下载链接】icedA cross-platform GUI library for Rust, inspired by Elm项目地址: https://gitcode.com/GitHub_Trending/ic/iced
在 NixOS 上开发 Iced 应用时,除了cargo build,还需要操作系统层面的动态库:Iced 需要一些系统依赖才能工作,而这些依赖不会随 Rust 工具链一起提供,也不是所有系统都默认安装(见 DEPENDENCIES.md)。Iced 官方为 NixOS 提供了两条等价路径:在项目里放一份shell.nix后用nix-shell进入环境,或者放一份flake.nix后用nix develop激活 dev shell。两种方式最终提供的内容相同——cargo/rustc工具链、运行时动态库清单,以及把这些库路径通过RUSTFLAGS传给链接器的设置。
先弄清环境提供了什么
两份 Nix 表达式的结构一致,理解这几个字段后再选择落地方式:
nativeBuildInputs:cargo与rustc,即构建项目所需的 Rust 工具链。dlopenLibraries:程序运行时通过 dlopen 方式加载的库清单,文档按用途分组:libxkbcommon;vulkan-loader:标注为 GPU backend,对应iced_wgpu渲染器使用的 Vulkan 后端;wayland:Wayland 窗口系统;xorg.libX11、xorg.libXcursor、xorg.libXi:X11 窗口系统,示例中默认被注释掉。
env.RUSTFLAGS:形如-C link-arg=-Wl,-rpath,${...},把dlopenLibraries解析出的库路径以 rpath 形式写入可执行文件,使程序运行时能加载到这些库。buildInputs:示例中为空。文档注释说明它用于项目构建时链接的额外库(例如 OpenSSL),只有项目确实链接这类库时才需要填写。
方式一:shell.nix 配合 nix-shell
- 在你的 Iced 项目根目录新建
shell.nix,写入 DEPENDENCIES.md NixOS 小节给出的内容:
{ pkgs ? import <nixpkgs> { } }: let dlopenLibraries = with pkgs; [ libxkbcommon # GPU backend vulkan-loader # libGL # Window system wayland # xorg.libX11 # xorg.libXcursor # xorg.libXi ]; in pkgs.mkShell { nativeBuildInputs = with pkgs; [ cargo rustc ]; # additional libraries that your project # links to at build time, e.g. OpenSSL buildInputs = []; env.RUSTFLAGS = "-C link-arg=-Wl,-rpath,${pkgs.lib.makeLibraryPath dlopenLibraries}"; }这里pkgs参数有默认值import <nixpkgs> { },直接使用本地已安装的 nixpkgs channel,${pkgs.lib.makeLibraryPath dlopenLibraries}是 Nix 表达式插值,运行时会被替换为库的实际路径,无需手工处理。
- 在项目根目录运行:
nix-shell进入 shell 后,工具链和RUSTFLAGS即按上述配置就绪,之后照常用cargo build、cargo run构建和运行项目。
方式二:flake.nix 配合 nix develop
文档给出的替代方案是 flake:在项目根目录新建flake.nix,写入以下内容:
{ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; systems.url = "github:nix-systems/default"; }; outputs = { nixpkgs, systems, ... }: let eachSystem = nixpkgs.lib.genAttrs (import systems); pkgsFor = nixpkgs.legacyPackages; in { devShells = eachSystem (system: let pkgs = pkgsFor.${system}; dlopenLibraries = with pkgs; [ libxkbcommon # GPU backend vulkan-loader # libGL # Window system wayland # xorg.libX11 # xorg.libXcursor # xorg.libXi ]; in { default = pkgs.mkShell { nativeBuildInputs = with pkgs; [ cargo rustc ]; # additional libraries that your project # links to at build time, e.g. OpenSSL buildInputs = []; env.RUSTFLAGS = "-C link-arg=-Wl,-rpath,${nixpkgs.lib.makeLibraryPath dlopenLibraries}"; }; }); }; }然后运行:
nix develop激活的 dev shell 与nix-shell方式提供的字段一一对应。需要注意两处与shell.nix的差异:flake 通过inputs声明了nixpkgs(nixos-unstable分支)与nix-systems/default两个输入,包来源不依赖本地 nixpkgs channel;RUSTFLAGS中用的是${nixpkgs.lib.makeLibraryPath ...}而非${pkgs.lib.makeLibraryPath ...}。
按需启用 X11 库或构建期链接库
示例默认只启用了wayland,X11 相关的三个库被注释。Iced 的默认 features 同时包含x11与wayland两个 Unix 窗口后端(见根 Cargo.toml 的[features]),如果你的程序实际运行在 X11 上,把dlopenLibraries中对应的xorg.libX11、xorg.libXcursor、xorg.libXi取消注释即可,shell.nix与flake.nix两处写法相同。
如果你的项目还在构建期链接额外库(文档举例为 OpenSSL),把它加进buildInputs,而不是dlopenLibraries——后者只负责运行时加载的库。
验证环境配置生效
进入nix-shell或nix develop的 shell 后,按表达式声明的内容逐项核对:
nativeBuildInputs声明的cargo、rustc应可直接调用,例如cargo --version;RUSTFLAGS环境变量应为包含-C link-arg=-Wl,-rpath,...的完整字符串,rpath 部分由makeLibraryPath基于dlopenLibraries生成;- 在环境内构建并运行你的 Iced 应用。Iced 需要这些系统依赖才能工作,程序能正常构建、启动窗口,即说明工具链、动态库与 rpath 三处配置都生效了。
适用边界
- 两份 Nix 表达式均未锁定
rustc版本:shell.nix用本地 nixpkgs channel,flake.nix用nixos-unstable分支,两者解析出的包版本可能不同。仓库 workspace 声明rust-version = "1.92"(见 Cargo.toml),可作为选择工具链来源时的参考。 - 文档为 NixOS 只提供 dev shell 这一层方案,不涉及系统级包配置;DEPENDENCIES.md 末尾也说明,如果你的系统不在其列出的范围内,可以自行补充对应指令。
【免费下载链接】icedA cross-platform GUI library for Rust, inspired by Elm项目地址: https://gitcode.com/GitHub_Trending/ic/iced
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考