Nix не запускает перестройку coreutils - PullRequest
0 голосов
/ 08 ноября 2019

Я использую Nix поверх системы Devuan GNU / Linux (x86_64) со следующими ~/.nixpkgs/config.nix, как описано в Nix Pills :

{
  packageOverrides = pkgs: {
    coreutils = pkgs.coreutils.override {
      aclSupport = false;
      attrSupport = false;
      selinuxSupport = false;
    };
    coreutils2 = pkgs.coreutils.override {
      aclSupport = false;
      attrSupport = false;
      selinuxSupport = false;
    };
    w3m = pkgs.w3m.override {
      graphicsSupport = false;
      imlib2 = null;
      x11Support = false;
      mouseSupport = true;
    };
  };
}

Но когда я запускаюnix-env -iA nixpkgs.coreutils, Nix устанавливает стандартную версию coreutils с включенными дополнительными функциями:

$ nix-env -iA nixpkgs.coreutils
replacing old 'coreutils-8.31'
installing 'coreutils-8.31'
$ ldd /home/iu/.nix-profile/bin/ls |grep libattr
        libattr.so.1 => /nix/store/5xwmn6ai8c42j84k6gdzja0lnkdi3c60-attr-2.4.48/lib/libattr.so.1
(0x00007f0354e7f000)

Но если я ссылаюсь на тот же вывод (ссылочная прозрачность) через другое имя:

$ nix-env -iA nixpkgs.coreutils2

Nixначинает перестройку из исходного кода, что приводит к созданию двоичных файлов, скомпилированных без дополнительных функций, как и было запрошено. Что еще более загадочно, переопределяющие параметры сборки для w3m работает и do вызывает перестроение.

Кроме того, я заметил такое же странное поведение с gnutar. Это как-то связано с тем, что coreutils и gnutar необходимы для самого Nix? Как я могу сделать coreutils ожидаемым образом?

1 Ответ

1 голос
/ 08 ноября 2019

Это происходит потому, что одно окончательное наложение применяется после ваших наложений. (Вы используете packageOverrides, который по сути становится первым пользовательским оверлеем)

Чтобы процитировать commit :

Оверлей stdenvOverrides используется для доставки пакетоввперед во время начальной загрузки через stdenv.overrides. К этим пакетам уже были применены наложения на предыдущем этапе загрузки. Если stdenvOverrides не последний в стеке наложений, все оставшиеся наложения будут снова применены к этим пакетам.

gnutar также устанавливается этим наложением.

$ nix repl '<nixpkgs>'
nix-repl> lib.attrNames (stdenv.overrides pkgs pkgs)
[ "acl" "attr" "bash" "binutils" "binutils-unwrapped" "bzip2" "coreutils" "diffutils" "findutils" "gawk" "gcc" "glibc" "gnugrep" "gnumake" "gnupatch" "gnused" "gnutar" "gzip" "patchelf" "pcre" "xz" "zlib" ]

«Хорошие» новости - вы можете использовать обычное наложение для настройки последнего наложения. Это запутанно, но работает:

nix-repl> (import <nixpkgs> { overlays = [ (self: super: { stdenv = super.stdenv // { overrides = self2: super2: super.stdenv.overrides self2 super2 // { coreutils = "put your coreutils here"; }; }; }) ]; }).coreutils
"put your coreutils here"

Я рекомендую использовать оверлеи вместо packageOverrides, чтобы убедиться, что это происходит в последнем "пользовательском" оверлее. Таким образом, ваше наложение будет похоже на:

_: super:
let
  coreutils = pkgs.coreutils.override {
    aclSupport = false;
    attrSupport = false;
    selinuxSupport = false;
  };
in
{
  # Overrides for stuff from stdenv go here. They're applied last
  # so we use the same stdenv for builds but a custom coreutils etc for
  # our system. This allows use to still use cache.nixos.org.
  stdenv = super.stdenv // {
    overrides = self2: super2: super.stdenv.overrides self2 super2 // {
      inherit coreutils;
    };
  };

  w3m = ...;
}
...