どうも、こたつやきです。
いつものように nixos-rebuild switch --flake .#example-host --ask-sudo-password を実行したら、使ってもいないContourのビルドに失敗して、NixOSの更新が止まってしまった。
error: Cannot build '/nix/store/<hash>-contour-0.6.3.8249.drv'.
Reason: builder failed with exit code 2.
> /build/source/src/vtbackend/Image.cpp:160:29: error: 'rebind_simd_t' in namespace 'simd' does not name a template type
> /build/source/src/vtbackend/Image.cpp:178:51: error: 'static_simd_cast' is not a member of 'simd'
error: Cannot build '/nix/store/<hash>-system-path.drv'.
Reason: 1 dependency failed.
error: Cannot build '/nix/store/<hash>-nixos-system-example-host-26.11.drv'.
Reason: 1 dependency failed.
なぜ system-path にContourが入っているのか、依存関係を追ってみた。
nix build .#nixosConfigurations.example-host.config.system.build.toplevel nixpkgs#contour
でも、nixpkgs#contour はflake registryのnixpkgsを指す。手元のflakeで固定しているnixpkgsとはcommitが違うので、これでは同じContourを調べていることにならない。そこで両方とも同じflakeから参照することにした。
nix why-depends .#nixosConfigurations.example-host.config.system.build.toplevel .#nixosConfigurations.example-host.pkgs.contour
ところが、これだと肝心のシステムをビルドし始めてしまう。今まさにビルドできなくて困っているのに。最後にたどり着いたのが --derivation だった。
$ nix why-depends --derivation .#nixosConfigurations.example-host.config.system.build.toplevel .#nixosConfigurations.example-host.pkgs.contour
/nix/store/<hash>-nixos-system-example-host-26.11.drv
└───/nix/store/<hash>-system-path.drv
└───/nix/store/<hash>-contour-0.6.3.8249.drv
--derivation を付けるとビルド結果ではなくderivation同士の依存を見られる。確かに system-path がContourに直接依存している。なんで?
nixpkgsを探してみると、nixos/modules/config/terminfo.nix に答えがあった。
environment.systemPackages = lib.mkIf config.environment.enableAllTerminfo (
map (x: x.terminfo) (
with pkgs.pkgsBuildBuild;
[
alacritty
contour
foot
ghostty
kitty
mtm
rio
rxvt-unicode-unwrapped
rxvt-unicode-unwrapped-emoji
st
tmux
wezterm
yaft
]
)
);
environment.enableAllTerminfo を有効にすると、いろいろな端末の terminfo が environment.systemPackages に追加される。Contourを端末として使っていなくても、Contourの terminfo を取り出すためにそのパッケージが依存に入るわけだ。
普段はbinary cacheから取れていたので気にしたことがなかったけど、今回はContourのビルドが失敗する問題に当たってしまった。ひとまず environment.enableAllTerminfo を無効にして、必要なものだけ指定した。
environment.enableAllTerminfo = false;
environment.systemPackages = [ pkgs.wezterm.terminfo ];
全部のterminfoが欲しいわけではないので、僕の環境ではこれで十分。使っていないパッケージのビルドが始まったら、まず nix why-depends --derivation で経路を見てみるとよさそうです。