GuixPkgs: every Guix package, as a Nix flake
GuixPkgs: every Guix package, as a Nix flake
I wrote earlier about what I believe to be an absurd idea, The Guix Nix Abomination: a tool, guix-transfer, that takes any Guix derivation and rewrites it into a Nix derivation, and lets nix-daemon build it. With this primitive in hand, I pondered what it would mean to import the entire Guix package set into Nix. That means we could even build a flake that is all of Guix packages available for use. Well…. Hello GuixPkgs. 🤯
我之前写过一个自认为很荒谬的想法,即“Guix Nix 畸形结合体”:一个名为 guix-transfer 的工具,它能获取任何 Guix 推导(derivation)并将其重写为 Nix 推导,从而让 nix-daemon 进行构建。有了这个基础工具,我开始思考将整个 Guix 软件包集导入 Nix 意味着什么。这意味着我们甚至可以构建一个包含所有可用 Guix 软件包的 flake。那么……你好,GuixPkgs。🤯
Nixpkgs is famously the largest package repository in the world. GuixPkgs makes it bigger by including in the entire GNU Guix package set so you can mix and match Guix and Nixpkgs packages in the same flake.
Nixpkgs 以拥有全球最大的软件包仓库而闻名。GuixPkgs 通过引入整个 GNU Guix 软件包集使其变得更加庞大,这样你就可以在同一个 flake 中混合使用 Guix 和 Nixpkgs 的软件包。
{
description = "A project mixing Nix and Guix";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
guixpkgs.url = "github:fzakaria/guixpkgs";
};
outputs = { self, nixpkgs, guixpkgs }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
guixPkgs = guixpkgs.packages.${system};
in {
devShells.${system}.default = pkgs.mkShell {
buildInputs = [
pkgs.git # from Nixpkgs
guixPkgs.hello # from Guix, via GuixPkgs
];
};
};
}
❯ nix build github:fzakaria/guixpkgs#hello
❯ ./result/bin/hello
Hello, world!
☝ Don’t forget, that hello is built from Guix’s source bootstrap, a 357-byte seed all the way up to GCC and glibc but it lands in /nix/store and behaves like any other Nix package. No guix required on the consuming side.
☝ 别忘了,这个 hello 是从 Guix 的源码引导(source bootstrap)构建出来的,从一个 357 字节的种子一直构建到 GCC 和 glibc,但它最终会存放在 /nix/store 中,表现得就像任何其他 Nix 软件包一样。使用端完全不需要安装 Guix。
Is this just a joke or is there anything of value here? Well, some packages only exist in Guix, notable many GNU Guile built software, like guile-png that are now easily available in Nix. 🤷
这只是个玩笑,还是真的有价值?嗯,有些软件包只存在于 Guix 中,特别是许多基于 GNU Guile 构建的软件(如 guile-png),现在可以轻松地在 Nix 中使用了。🤷
How does it work? Pins a Guix commit and uses guix time-machine to get derivations from that exact Guix thus decoupling the result from whatever guix-daemon version happens to be on the host. Dumps every package’s .drv and feeds them to guix-transfer —disable-tests —emit-nix-dir pkgs. Rebuilds the by-name/ index and records the Guix channel + commit + timestamp in guix-metadata.json.
它是如何工作的?它锁定一个 Guix commit,并使用 guix time-machine 从该特定版本的 Guix 获取推导,从而使结果与宿主机上安装的 guix-daemon 版本解耦。它导出每个软件包的 .drv 文件,并将其输入到 guix-transfer --disable-tests --emit-nix-dir pkgs 中。最后,它重建 by-name/ 索引,并将 Guix 频道、commit 和时间戳记录在 guix-metadata.json 中。
Realising a Guix package under Nix recompiles Guix’s entire source bootstrap. That’s hours per closure. To skip it, GuixPkgs ships a Cachix, cachix use guixpkgs, binary cache that is included in the flake. Thank you @domenkozar for sponsoring me with extra storage. 🙏
在 Nix 下实现一个 Guix 软件包会重新编译 Guix 的整个源码引导过程。每个闭包(closure)都需要耗费数小时。为了跳过这一步,GuixPkgs 提供了一个 Cachix 二进制缓存(cachix use guixpkgs),该缓存已包含在 flake 中。感谢 @domenkozar 为我提供额外的存储空间支持。🙏
What’s next? We can now do some truly horrendous evil stuff. What about an overlay that replaces every package from Nixpkgs which one that exists in Guix? 😈 We can then build a NixOS machine where every package is the Guix equivalent 😱. This was a really fun project to pursue during TacoSprint.
接下来做什么?我们现在可以做一些真正“邪恶”的事情了。比如写一个 overlay,将 Nixpkgs 中的每个软件包替换为 Guix 中对应的版本?😈 这样我们就可以构建一台所有软件包都是 Guix 等价物的 NixOS 机器了 😱。这是我在 TacoSprint 期间进行的一个非常有趣的项目。