Nix에서 하나의 파생이 옆에 있는 다른 파생에 종속되게 만드는 방법은 무엇입니까?

Nix에서 하나의 파생이 옆에 있는 다른 파생에 종속되게 만드는 방법은 무엇입니까?

현재 일부 비공개 소스 소프트웨어를 Nix 포크에 패키징하려고 합니다. 애플리케이션은 .deb파일 묶음으로 배포되며, 대부분은 애플리케이션의 다른 부분에서 사용할 수 있는 라이브러리를 포함합니다.

단순화하기 위해 app.deb실제 애플리케이션이 포함되어 있고 lib.deb애플리케이션에 필요한 라이브러리가 포함되어 있다고 가정합니다.

현재 나는 다음을 가지고 있습니다:

# default.nix
let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-23.11";
  pkgs = import nixpkgs {
    config = { };
    overlays = [ ];
  };
in {
  lib = pkgs.callPackage ./lib.nix { };
  app = pkgs.callPackage ./app.nix { };
}
# lib.nix
{ lib, stdenv, autoPatchelfHook, dpkg, requireFile,
libcxx, libgcc, }:

stdenv.mkDerivation {
  pname = "myapp-lib";
  version = "1.0.0";
  src = requireFile {
    name = "lib.deb";
    sha256 = "313e8686118ccba397de0bdfca101f1053b758227fd9d3510ea78644f2450bfe";
    url = "https://softwarecorp.example/downloads";
  };

  nativeBuildInputs = [
    dpkg
    autoPatchelfHook
  ];

  unpackPhase = "dpkg-deb -x $src .";

  buildInputs = [ libcxx libgcc ];

  installPhase = ''
    cp -r lib $out/
  '';
}
# app.nix
{ lib, stdenv, autoPatchelfHook, dpkg, requireFile,
libcxx, }:

stdenv.mkDerivation {
  pname = "myapp-bin";
  version = "1.0.0";
  src = requireFile {
    name = "app.deb";
    sha256 = "f4abbdb3f83d982569c5cd30ce5ad63ec4e49011d165e17a2c59d9a613f163b9";
    url = "https://softwarecorp.example/downloads";
  };

  nativeBuildInputs = [
    dpkg
    autoPatchelfHook
  ];

  unpackPhase = "dpkg-deb -x $src .";

  buildInputs = [ libcxx ];

  installPhase = ''
    cp -r bin $out/
  '';

  runtimeDependencies = [ myapp-lib ];  # <-- how to do this?
}

파생은 자체적으로 구축되며 이제 파생 lib에 포함된 내용을 추가하고 싶습니다 . app파일 상단에 있는 일반 패키지 종속성 목록에 추가할 수는 없습니다. 또한 이 시점에서 패키지를 nixpkgs에 제출하는 것을 피하고 싶습니다. 왜냐하면 애플리케이션을 완전히 패키지화할 수 있을지 확신할 수 없고 완료될 수 있다는 것을 알기 전까지는 관리자 역할을 하고 싶지 않기 때문입니다.

또는 그러한 폐쇄 소스 소프트웨어를 패키징하여 광범위한 파생이 필요하지 않도록 하는 좋은 패턴이 있습니까? 내가 아는 한, 여기 라이브러리는 모두 동일한 버전을 갖고 있으며 회사 제품의 다른 곳에서는 절대 사용되지 않으므로 여기에 단일 포크를 구축하는 것은 허용됩니다.

답변1

두 번 분기하는 것을 방지하려면 라이브러리를 패키징하지 installPhase않고 postUnpack.

# app.nix
{
  stdenv,
  autoPatchelfHook,
  dpkg,
  requireFile,
  libcxx,
}: let
  myLib = requireFile {
    name = "lib.deb";
    sha256 = "313e8686118ccba397de0bdfca101f1053b758227fd9d3510ea78644f2450bfe";
    url = "https://softwarecorp.example/downloads";
  };
in
  stdenv.mkDerivation {
    pname = "myapp-bin";
    version = "1.0.0";
    src = requireFile {
      name = "app.deb";
      sha256 = "f4abbdb3f83d982569c5cd30ce5ad63ec4e49011d165e17a2c59d9a613f163b9";
      url = "https://softwarecorp.example/downloads";
    };

    nativeBuildInputs = [
      dpkg
      autoPatchelfHook
    ];

    unpackPhase = "dpkg-deb -x $src .";

    postUnpack = ''
      dpkg-deb -x ${myLib} .
      cp -r lib $out/
    '';

    buildInputs = [libcxx];

    installPhase = ''
      cp -r bin $out/
    '';
  }

콤보epson-alc1100이 구현의 예입니다.

답변2

lib먼저 표현식을 작성하는 동안 파생에 액세스 할 수 있어야 합니다 app. 따라서 맨 아래 부분은 요소가 서로를 참조하고 인수로 전달될 default.nix수 있는 "재귀" 세트를 갖도록 변경해야 합니다 .libapp

{
  lib = pkgs.callPackage ./lib.nix { };
  app = pkgs.callPackage ./app.nix { inherit lib; };
}

이제 app.nix이라는 매개변수가 필수인데 lib이미 추가한 것 같습니다. (실제로 실제 코드에서는 매개변수 pkgs.lib를 제공하는 라이브러리이고 nixpkgs이름 충돌 없이 파생에 사용할 수 있기 때문에 매개변수의 이름이 다른 것으로 예상됩니다 .)

이제 전달하려는 컬렉션을 app.nix작성하기만 하면 됩니다 . 이는 와 동일합니다 . 즉, 파생된 출력 경로 와 동일한 이름의 환경 변수를 설정한다는 의미입니다 . (질문에 쓴 내용에도 불구하고 이것이 유효한 주장 이라고 생각하지 않습니다 .)inherit lib;mkDerivationlib = lib;liblibruntimeDependenciesmkDerivation

이제 빌더 스크립트에서 이를 만들기 위해 app필요한 모든 작업을 수행할 수 있습니다 . 예를 들어 심볼릭 링크를 작성할 수 있습니다. 여기에서 수행하려는 작업의 정확한 세부 사항은 응용 프로그램이 해당 라이브러리를 찾는 방법에 대한 세부 사항에 따라 달라지며, 해당 세부 정보가 없으므로 일반적인 용어로만 말씀드릴 수 있습니다.libappln -s $out/lib $lib

현재 디렉토리에서 심볼릭 링크를 실행 nix-build -A app하고 확인 하여 빌드한 내용을 확인하고 예상한 방식으로 참조되는지 확인하세요.resultlib

관련 정보