현재 일부 비공개 소스 소프트웨어를 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
수 있는 "재귀" 세트를 갖도록 변경해야 합니다 .lib
app
{
lib = pkgs.callPackage ./lib.nix { };
app = pkgs.callPackage ./app.nix { inherit lib; };
}
이제 app.nix
이라는 매개변수가 필수인데 lib
이미 추가한 것 같습니다. (실제로 실제 코드에서는 매개변수 pkgs.lib
를 제공하는 라이브러리이고 nixpkgs
이름 충돌 없이 파생에 사용할 수 있기 때문에 매개변수의 이름이 다른 것으로 예상됩니다 .)
이제 전달하려는 컬렉션을 app.nix
작성하기만 하면 됩니다 . 이는 와 동일합니다 . 즉, 파생된 출력 경로 와 동일한 이름의 환경 변수를 설정한다는 의미입니다 . (질문에 쓴 내용에도 불구하고 이것이 유효한 주장 이라고 생각하지 않습니다 .)inherit lib;
mkDerivation
lib = lib;
lib
lib
runtimeDependencies
mkDerivation
이제 빌더 스크립트에서 이를 만들기 위해 app
필요한 모든 작업을 수행할 수 있습니다 . 예를 들어 심볼릭 링크를 작성할 수 있습니다. 여기에서 수행하려는 작업의 정확한 세부 사항은 응용 프로그램이 해당 라이브러리를 찾는 방법에 대한 세부 사항에 따라 달라지며, 해당 세부 정보가 없으므로 일반적인 용어로만 말씀드릴 수 있습니다.lib
app
ln -s $out/lib $lib
현재 디렉토리에서 심볼릭 링크를 실행 nix-build -A app
하고 확인 하여 빌드한 내용을 확인하고 예상한 방식으로 참조되는지 확인하세요.result
lib