使用 NixOS/Nix 的「最佳实践」是什么?

如题。

  1. 对于那些基于 FHS 开发的/发行的软件,有哪些成熟的经验方法将它们移植到 Nix 上?
  2. 为 Nix 打包时有哪些注意事项?

我大概花了2周的时间,想把环境迁移到guix去。但是最后失败了,你说的FHS就是一个很大的原因。

因为GUIX为了保证隔离性和可复现性,所以需要为包做wrap。 比如用脚本wrap 执行文件的环境变量,patch interprete。就比较麻烦,而且有个risk, 如果移植的程序内部有调用一些/usr/bin/ls(硬编码进程序的) 这样的命令的话,就会比较麻烦。这种我暂时没想到解决办法。

另外guix 是不用systemd的,所以如果仍然是硬编码的而且没有源码的话,同样会比较头疼(nix好像是用systemd的?可能没这个问题)。

这些问题可能是可以被解决的,但是我一想到以后我找个软件要是没有guix的支持,我就得自己去做一遍这些patch的话,我就感觉很恐怖所以就放弃了…

你用Nix的话,可以参考一下。另外,guix因为有编译过程,所以安装软件可能没arch和ubuntu这种快, 不知道nix是不是这样的。

nix也有编译过程,大体上guix有的问题,nix也有(nix用systemd)

网络问题,打包问题,文档混乱问题 用起来成本太高了

guix 可以模拟出一个符合 FHS 环境 https://guix.gnu.org/en/blog/2023/the-filesystem-hierarchy-standard-comes-to-guix-containers/

nix 应该类似功能,我不太清楚,因为读 nix 的文档太痛苦了 :stuck_out_tongue:

至于打包其实跟别发型版区别不大,无非是 config, build, install 几个 phrase,往里面填 shell 脚本。对于使用典型的构建系统的软件也是自动处理,比如 autotools,CMake 和各个语言的 de facto 的构建系统。跟在别的发型版上打包没有本质区别,

其实只要是规范的 free and open source,打包没什么困难。至于私有软件就只能自求多福了。

我个人感觉的话,直接用 docker 跑应该是个最佳选择

网上也有人问过类似的问题

我自己尝试过构建一个 shell,参考官方文档最终还是放弃了。。。

https://nixos.org/manual/nixpkgs/stable/#sec-fhs-environments

没用过 Docker,有点疑惑:

  1. Docker 属于虚拟化技术,个人使用会不会性能开销太高了?
  2. 听说 Docker 已经被 GFW 了,甚至连镜像站都给 ban 了。 :fearful:

你都用nix了,还考虑啥GFW啊 少不了从github直接拉文件下来,现编译,还有nixos的缓存机器国内直连也不太好

FHS 的话,nixos 有提供fhs环境,例如vscode 就有fhs包,可以安装任意插件,例如clangd插件,它会下载clangd的二进制包

注意事项,没啥注意事项,能编译过就基本没问题

运行二进制文件: 在一开始如果遇到没有移植的软件,看看有没有像 flatpak,appimage打包的版本。实在不行,用 steam-run 运行下。

日常开发:遇到的问题一般是动态链接库问题,可以用 LD_LIBRARY_PATH 环境变量解决。(一些二进制无法运行也可能是动态链接库问题)。ldd命令非常实用。

遇到问题多上Nix论坛。

  1. 我查了一下资料,Nix 的发明者现在已经被 Nix 社区赶出去了…

https://lwn.net/Articles/971973/

https://save-nix-together.org/

不用担心, 咱不是还有 HW 主导的开放原子开源基金会 搞了个国产绿色版 docker 镜像站吗? :yum:

2 个赞

这个概念在 Nix 里面叫什么名字?

好像叫 steam-run?

这个名字……好像最开始是用来解决 Nix 运行 Steam 的问题的?

哦哦,好像是的,我以前搞的已经忘记了 :joy: 刚刚查了一下,好像更新的做法是用 nix-ld,你可以查一下 NixOS wiki 看看。

  1. 对轻度使用最重要的:Nixpkgs更新极快,而Guix的官方channel简直是滚动更新仓库之耻
  2. Nix下载channels/flake inputs就是直接拉取仓库快照, 而Guix——我不知道它具体是怎么实现的——似乎使用了某种“递归”过程?(注意两者的官方channel都是自包含的)在网络都没问题的情况下前者比后者快得多
  3. Nixpkgs允许非自由固件上架,Guix不允许。不过对于foreign distro来说没什么区别
  4. Nix工具链比Guix更丰富,比如各种xxx2nix;Nix语言作为DSL甚至比Guile受到更多的编辑器支持,就算不支持,直接用vim编辑也比Guile更方便(不过这里是Emacs论坛……所以这个优势应该反过来?)
  5. Flake系统便于去中心化,尽管Nix社区本身相当中心化;双重版本锁定机制也比guix describe更灵活

嗯,你说的前面那些点挺不错,但“Nix社区本身相当中心化”我不认同,而且nixos社区一直宣扬的包多的观点,也就笑笑,它那个分包的粒度,包不多才奇怪呢 nix很多人都是闭门造车,论中心化远不如aur这种,即使同样有nur,也没多少包 很多人自己打包都只在自己的nixos配置中使用,很少有人会单独提取出来作为单独包使用

另外,nixos的社区都已经把nix的作者踢出社区了,没考证过,我记得是在哪个群组有人提了一嘴

我在打包上还是新手,不过根据个人经验来说:

  1. 没有。在Nixpkgs仓库一查你会发现无数种绕过FHS的方法。除了一些特殊情形,这些方法所基于的“原语”无非是find, grep, awk, sed四件套以及编译环境自带的几个bash函数(比如 substituteInPlace)。学习这些东西的最好方法是生成式人工智能。
    • 用flake和nix命令,把channel和nix-命令当作不存在,这样才能获得现代包管理器(conda, cargo, yarn, pkg.jl, etc)的体验。
    • 不要指望文档。 绝大多数包,唯一的文档就是代码注释和PR评论。所以有任何疑问首先看相关包的代码。另外NixOS Wiki上有大量dirty hack(比如直接在/nix/store中搜索、调用甚至改动文件),属于严重的抽象泄漏,与Nix的设计背道而驰。不要信。
    • 虽然说不要指望文档,但Nixpkgs Manual还是必须逐字阅读。有大量稀奇古怪的设计光看别人打的包根本不可能知道(比如nativeBuildInputs并不是单纯的“构建时依赖”,而是包括了Nix-specific的东西,如wrapQtAppsHookhash属性不知道的时候不能随便乱填,而是只能填固定的几个占位符)
    • 如果构建脚本完全自制,那么需要手动创建$out目录,mkDerivation不会帮你创建。
    • mkDerivation的大部分(所有?)属性都会变成环境变量,但是不要太依赖这个功能,因为它无法调用其他环境变量,比如out
2 个赞

有一说一,作为导火索的Anduril事件在我这个中国人看来有些可笑——这伙人都直球向欧盟要饭了,居然对军火商的赞助如此在意。可能是“君子远庖厨”吧。

1 个赞

只用新命令的话,好像是完全没法儿命令式安装包了,只能靠声明式,修改 nixosConfigurations 和 homeConfigurations,感觉和这些现代包管理器没什么关系啊🥲