背景是我想安装yazi(https://github.com/sxyazi/yazi),由于主分支和正式版相差过大, 想通过overlay安装。
我按照文档加入了
- yazi.url = “github:sxyazi/yazi”;
- nixpkgs.overlays = [ yazi.overlays.default ];
- cachix :
extra-substituters = [ “https://yazi.cachix.org” ];
extra-trusted-public-keys = [ “yazi.cachix.org-1:Dcdz63NZKfvUCbDGngQDAZq6kOroIrFoyO064uvLh8k=” ];
然后在homemanager里直接填入yazi,但这在我的linux虚拟机上无法命中缓存,每次都要编译,我应该怎么办?
我的commit记录:test · rick-yao/dotfiles@9e9a2b8 · GitHub
因为你的flake里面有一个nixpkgs的checkout,然后你把yazi的包overlay到这个checkout上面,也就意味着依赖都是用的你的nixpkgs里的版本,而不是上游(yazi的flake.nix里的inputs.nixpkgs
)的。这种用法在多数情况下是不能cache hit的。
如果你要用上游的cache,那么就直接写packages = with inputs.yazi.packages; [ yazi ];
,这样得到的就是用yazi的nixpkgs构建出来的,它的derivation就与上游cache过的一致。但是相应的你的系统closure也会增大,因为你用了和目前系统的nixpkgs不同的依赖。
多谢回复,我大概懂你的意思了,另外我还有一个问题,我的overlay不能够覆盖nixpkgs里的yazi么?
说实话它这个写法确实有点迷惑了。看起来确实是应该使用它自己的pkgs的。它的callPackage是这一部分:
(
system:
let
pkgs = import nixpkgs { inherit system overlays; };
# 定义版本,略
yazi-unwrapped = pkgs.callPackage ./nix/yazi-unwrapped.nix { inherit version; };
yazi = pkgs.callPackage ./nix/yazi.nix { inherit yazi-unwrapped; };
in
{
packages = {
inherit yazi-unwrapped yazi;
default = yazi;
};
# 略
}
)
说明在callPackage这个function的时候,输入是yazi的inputs.nixpkgs
,因为callPackage
来自这个nixpkgs。而在后文中定义overlay,这个过程并没有用final或者prev覆盖它(final和prev是应用overlay后和应用overlay前的pkgs,一般来说调包会从prev里面调,避免infinite recursion,但是也有因为别的overlay,或者不用rec从顶层引用overlay里的其他包,而必须从final里调的情况。)
rec {
default = yazi;
yazi = final: prev: {
yazi-unwrapped = self.packages."${final.system}".yazi-unwrapped;
yazi = self.packages."${final.system}".yazi;
};
}
看到yazi的overlay里面其实就直接引用了上文中的yazi,那么确实应该是可以被cache的。
overlay是可以覆盖的。不仅是覆盖最终的top-level package(也就是你在自己的配置中使用的pkgs.foo
),也可以覆盖其他包依赖的那个yazi。它的作用相当于在一开始这个包就作为nixpkgs的一部分存在了。
看你的说法,我写的应该是没有错误的?还是没太明白应该怎么写,按我的理解overlay覆盖之后,homemanager里的yazi就还是写yazi就好了,不需要指明inputs.yazi了
对的,你的写法看起来确实没有错,我也有点不明白,可能比如它其实并没有cache上
cache应该是有的,我在我的ubuntu上照着yazi官网demo试了下,发现我拿一个空的flake,hm就能命中cache,然后再运行我的flake,就不用编译了
发现把substituter注释掉就能触发cache,请问怎么才能让yazi单独走cache呢?
nixConfig = {
42 │ experimental-features = [“nix-command” “flakes”];
43 │
44 │ # substituters = [
45 │ # “https://mirrors.tuna.tsinghua.edu.cn/nix-channels/store”
46 │ # “https://mirrors.ustc.edu.cn/nix-channels/store”
47 │ # “https://cache.nixos.org”
48 │ # ];
49 │ extra-substituters = [ “https://yazi.cachix.org” ];
50 │ extra-trusted-public-keys = [ “yazi.cachix.org-1:Dcdz63NZKfvUCbDGngQDAZq6kOroIrFoyO064uvLh8k=” ];
51 │
52 │ auto-optimise-store = true;
53 │ };
你的这个注释掉也挺奇怪的,man nix.conf
说:
For instance,
substituters = a b
extra-substituters = c d
defines the substituters setting to be a b c d.
所以看起来应该是没什么影响才对…
如果你的意思是“仅对这个derivation的output使用substituter下载”的话,我好像在哪儿提过,但是我们目前暂时还做不到。这就是为小项目添加substituter的一个痛点。
我也查到了,按理来说extra就是在非extra的后面的,我试了下,就算是substituters里面只留下 “https://cache.nixos.org”这一默认项,也不会触发cache,必须把substituters完全注释才行