Фон
Когда я добавил первый Overlay для Nixpkgs, я обнаружил, что куча системных утилит была создана для другой версии:
these derivations will be built:
/nix/store/028dqnwq36xja16gba3gckq5mcprpn06-postfix-main.cf.drv
/nix/store/b2sch2538ny2drdf9zzknf38grn8d8r3-pcre-8.42.drv
/nix/store/i1k9ksk32ca441zap40z3zddy7bhqx3n-zlib-1.2.11.drv
/nix/store/sypawsb3cwqnnhdl1barv2d8nyvbsxyv-coreutils-8.29.drv
/nix/store/xa4vnajxck2zgvjwp7l71lm11hqnz32r-findutils-4.6.0.drv
...
, что занимает много времени и пространства. Я попытался выяснить, что происходит, и закончил с этим вопросом.
Резюме
Идея self
и super
из оверлеев состоит в том, что self
- это накопленный результат после применения всех оверлеев, в то время как super
- результат применения предыдущего оверлея.
Я думал, что атрибут, который не был затронут, будет одинаковым между self
и super
, но некоторые нет.
let
nixpkgs = import <nixpkgs> {
overlays = [
# This overlay obtains self.bash and super.bash, and save them under the
# attrs "bash-from-self" and "bash-from-super" for further examination
(self: super: {
bash-from-self = self.bash;
bash-from-super = super.bash;
})
];
};
# Retrieve bash-from-self (self.bash) and bash-from-super (super.bash)
# from the overlayed nixpkgs
inherit (nixpkgs) bash-from-self bash-from-super;
in {
# Check if bash-from-self (self.bash) and bash-from-super (super.bash)
# are same
isBashSame = (bash-from-self == bash-from-super);
inherit bash-from-self bash-from-super;
}
Вышеуказанное оценивается как:
{ isBashSame = false;
bash-from-self = «derivation /nix/store/zvy7mbpxqlplqpflqn5xk9szx25s4mhg-bash-4.4-p23.drv»;
bash-from-super = «derivation /nix/store/2i91sj16snsphvjrbsa62z8m4zhs261c-bash-4.4-p23.drv»; }
Показывает, что self.bash
и super.bash
- это не одно и то же, даже если атрибут bash
не затрагивается ни при каких наложениях. Почему это происходит, или не хватает каких-то концепций?
Подробнее
Больше разных атрибутов
Помимо bash
, есть еще несколько отличающихся атрибутов:
let
isAttrSame =
attrName:
let
nixpkgs = import <nixpkgs> {
overlays = [
(_self: _super: { inherit _self _super; })
];
};
self = nixpkgs._self."${attrName}";
super = nixpkgs._super."${attrName}";
isSame = self == super;
in
isSame
;
in {
coreutils = isAttrSame "coreutils";
bash = isAttrSame "bash";
zsh = isAttrSame "zsh";
zlib = isAttrSame "zlib";
stdenv = isAttrSame "stdenv";
findutils = isAttrSame "findutils";
gnutar = isAttrSame "gnutar";
gcc = isAttrSame "gcc";
}
{
bash = false;
coreutils = false;
findutils = false;
gcc = true;
gnutar = true;
stdenv = true;
zlib = false;
zsh = true;
}
Строитель self.bash
равен super.bash
?
let
nixpkgs = import <nixpkgs> {
overlays = [
(self: super: {
bash-from-self = self.bash;
bash-from-super = super.bash;
})
];
};
inherit (nixpkgs) bash-from-self bash-from-super;
in {
bash-from-self-builder = bash-from-self.drvAttrs.builder;
bash-from-super-builder = bash-from-super.drvAttrs.builder;
bash-from-self-outPath = bash-from-self.outPath;
bash-from-super-outPath = bash-from-super.outPath;
}
{ bash-from-self-builder = "/nix/store/2ws9cmamvr7xyvdg4d2nnd1bmr1zjrrq-bootstrap-tools/bin/bash";
bash-from-self-outPath = "/nix/store/06z61jbgs0vkw4i9cqqf9yl7zsfkkhw2-bash-4.4-p23";
bash-from-super-builder = "/nix/store/06z61jbgs0vkw4i9cqqf9yl7zsfkkhw2-bash-4.4-p23/bin/bash";
bash-from-super-outPath = "/nix/store/2avim7j13k75k26w18g6br8gai869nm9-bash-4.4-p23"; }
bash-from-self-outPath
- это bash-from-super-builder
(06z61...khw2-bash-4.4-p23
).
Итак, super.bash
использует self.bash
для сборки себя, производя еще один bash (2avim...9nm9-bash-4.4-p23
)?
bootstrap-tools/bash
--builds -> self.bash
--builds -> super.bash
Почему это проблема
Я хочу, чтобы некоторые из моих пакетов, определенных в оверлее, зависели от bash
, coreutils
и прочего. Я хочу использовать их оригинальную версию, предоставленную непосредственно из <nixpkgs>
, а не те, которые могут быть перезаписаны последующими наложениями. Таким образом, в данном случае кажется, что я должен выбрать super.*
вместо self.*
в качестве зависимостей.
Но некоторые super.stuff
не являются оригинальными nixpkgs.stuff
, это приводит к их перестройке, поскольку нет двоичного кеша и является пустой тратой дискового пространства. И self.stuff
может быть перезаписано более поздними наложениями. Что я могу сделать?