文章简介
约 1546 字大约 5 分钟
LinuxNixFlake
2025-01-29
Linux的发行版浩如烟海,其本质无非是内核搭配一些基础工具,方便用户的使用,随着用户需求的不断复杂化,包管理器功能也逐渐被划归到发行版的功能之中,到最后,内核和基础工具也被划归到包管理器的管理范畴。可以说,包管理器就是发行版的基石,其管理着系统中几乎所有的软件(包括内核甚至是Bootloader),而包管理器的不同也作为划分发行版谱系的重要依据之一。
大部分Linux新人接触到的都是Debian系,它们是基于apt包管理器的发行版,这个家族的成员有Debian、Ubuntu、Deepin等等;比较特殊的还有Arch系,它们是基于pacman包管理器的发行版,典型成员有Archlinux和Manjaro。
而我们要介绍的NixOS是其中的异类,它基于nix包管理器,是一个声明式的包管理器。
必须要澄清的是,叫做
Debain系的原因是这些发行版都衍生自Debain,而基于apt仅仅是其判断依据,Arch系同理。
所以,nix有什么不一样?
在Arch系中,我们使用pacman在终端中安装软件,比如:
pacman -S clang一旦该命令成功,该软件就会永远留存在你的系统中,除非我们手动卸载该包(pacman -Rs),这种方式符合直觉,简单易懂,但存在以下缺点:
- 配置分散: 虽然大部分软件都遵守LFS规范,但它们的配置文件往往处于不同的位置,使用不同的配置语言,这导致了用户很难管理系统配置。
- 依赖管理混乱: 虽然我们能通过命令获取当前系统中所有的软件和版本,但我们往往没有有效的手段确保这种依赖关系是确定的(因为我们使用的软件源几乎不可能一致),这很可能会导致某开发环境在当前系统中可以运行,但到了另一个系统上就失效了。
- 难以管理外部软件: 如果软件源不满足我们的需求,我们很有可能需要寻求手动安装,一般的发行版并没有对这种软件进行约束,在其编译安装过程中,发行版完全不知情,但其安装结果很有可能改变了某些文件布局,导致某些软件无法正常运行,甚至整个系统崩溃。
nix提供了一种全新的方式,它在实际的LFS路径和软件包之间加入了一层中间层(在NixOS中通常位于/nix/store/),安装软件会在该目录中新建一个由哈希和软件包名组成的路径(来唯一表示该软件包),这个路径是只读的,只有nix相关命令可以修改该目录。在系统启动时,nix会将这个目录中安装的所有软件映射到真正的LFS目录中(一般是/run/current-system/)。
为了适配这套软件安装逻辑,nix还需要一套配置来描述整个系统,用来最终导出系统需要的所有软件包和其配置,我们称之为nix配置文件(一般位于/etc/nixos),每次我们需要安装软件或者修改软件时,我们需要将内容添加到配置文件中,然后重新计算整个配置文件,生成新的系统配置(我们称之为generation或者profile)。
举个例子,我们的配置文件中如果有如下内容:
{ pkgs, ... }:{
environment.systemPackages = [ pkgs.clang_19 ];
}在重新生成系统配置之后,我们可以在上述目录中找到:
/nix/store/0jf7aq1bhi5609mylnas50qrsiclbp34-clang-wrapper-19.1.4/这里包含了clang这个软件的构建结果,同时,我们也可以在上述目录中找到:
/run/current-system/sw/usr/bin/clang对于上面的所有内容,用户只允许更改配置文件,而后面生成的路径下面的所有内容都是只读的,这极大限制了用户的操作空间,限制系统中所有的软件都只应通过配置文件注入,当然,nix提供了大量的方式增强配置文件的能力,在一般发行版中能做到的事,在nix中几乎都能做到。
上面提到的哈希是笔者在自己的
/nix/store中找到的,不代表所有的clang_19均为该哈希。
解决软件源的问题
早年的nix并没有解决软件源的问题,直到flake的出现,flake是nix的项目管理器,它通过将软件源参数化来控制软件源一致性。
使用过Cargo等现代项目管理器的读者想必很熟悉.lock文件,它通过哈希控制项目中每个依赖的在不同的环境中的一致性,flake也使用了这种方式,它将系统配置转换为一个flake项目,将软件源作为它的一个依赖传入,通过flake.lock确定该源在所有环境中的一致性。
本教程着重介绍flake特性,不会涉及过多传统nix的操作。
尽管
flake现在仍然是一个实验特性,但鉴于其目前的使用情况,其稳定性已经得到了保证。
迁移到nix的注意事项
迁移到nix是非常困难的,因为其几乎不支持任何其他发行版通用的约定,例如LFS路径等,这会导致:
nix构建的二进制文件和其他发行版不兼容(可以通过patchelf解决该问题)- 外部二进制文件很难在
NixOS中运行(可以通过手动打包或者nix-ld解决) - 开发环境配置逻辑和其他发行版完全不同
本教程的目的
本教材旨在处理上述提到的注意事项,带领读者一步步接受nix哲学,并体会其中的便利性。
更新日志
8aed7-Nix-打包Tauri应用于ccdee-nix教程前言于f8d73-美化博客,新系列锐意进取中于
