조금 과장해서 얘기하면, 문서들이 아래와 같이 쓰는 것처럼 보입니다.
"derivation에 있는 derivation이 derivation을 만들어 저장소에 derivation을 남긴다."
이게 무슨 말인가 싶은데, 의미가 조금 더 명확히 보이게 쓰면, 아래와 같습니다.
"derivation 생성식에 있는 derivation 함수가 derivation 객체를 만들어 derivation 파일 .drv에 저장한다."
아래는 처음 derivation을 보는 분들이 아닌, derivation이 저처럼 약간 모호한 분들과 의견을 나누기 위한 글입니다.
닉스의 derivation
"derivation은 패키지 빌드를 위한 모든 정보가 들어 있는 명세서"라는 간단한 설명만으로 넘어 가기엔, 중요한 개념을 담고 있다고 보입니다.
hello/default.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.hello
hello
패키지에 의존하는 somePackage/default.nix
파일에 아래 줄이 있습니다.
hello = import ../hello { inherit pkgs; };
엄밀히 얘기하면 import
하고 있는 hello/default.nix
의 pkgs.hello
는, 평가가 끝나고 나온 결과물 derivation이 아직 아닙니다.
nixpkgs는 derivation
를 생성할 표현식, 즉 derivation이나 .drv가 아니라, derivation 생성식 .nix들의 모음입니다. nixpkgs에 가져온 해당 식을 평가(nix-instantiate
)하면, derivation
이 만들어집니다. .drv 파일은, 이 걸, 나중에 또 계산(평가)하지 않기 위해 /nix/store
에 남기는 derivation 캐싱 파일입니다.
"결과적으로 닉스는 실제 패키지도, derivation도 아닌 필요한 의존성들을 derivation 생성식들의 관계로 표현해 놓고, 최종 겉모양은 하나의 derivation 생성식이 하나의 패키지를 표현하게 된다."
거꾸로 접근해 보면, 보통 그냥 derivation이라 말하는 것은 derivation 객체라고 부를 수 있으며, .drv
파일의 내용을 런타임에 메모리에 올린 derivation 데이터 타입 객체를 의미한다고 볼 수 있습니다.
대부분의 문서들이 derivation 생성식과 derivation을 구별하지 않고 써서, 초반에 derivation 개념 잡는 걸 방해하는 것 아닌가 싶어요. derivation은 derivation 생성식을 평가해서 나온 데이터 구조체일 뿐이니, 이를 구별하지 않고 쓰는 게 이해는 갑니다만,
지금 위와같이 상상하고 파는 이유는, "닉스는 분명 함수형이고, 선언형이라 했으니, 함수로 패키지를 표현하고, 함수들의 합성으로 최종 패키지(만드는 방법)를 표현할 것이다"로 상상하고 접근하니, derivation을 엮어 놓는 것이 아닌 derivation 생성식 - 함수로 엮어 놓는 게 중요한 차이점으로 보입니다.
사실, 그냥 넘어가도 될 것 같은데, 닉스 코드를 언어로 읽어 머릿속 인터프리팅하는데, 저는 은근 위와 같은 명확함이 필요합니다. 아마도 다른 분들도, 위 내용을 먼저 명확히 하고, 진도를 나간다면, 좀 더 자연스럽게 체계가 잡히지 않을까 생각이 듭니다.
잘못된 방향이 보이면 댓글 부탁드립니다.
※ 처음에 hello.drv
파일이 C 프로젝트의 .o
중간 파일처럼, 기계가 보기 위한 바이너리 파일쯤으로 생각했는데, 실제 모양은 아래와 같습니다.
Derive([("out","/nix/store/n131z2zya6ifx050b8q3biymx2jxfdwi-hello","","")],[("/nix/store/029h9shccppyiw1l7qsk6xp0grxgzzbb-stdenv-linux.drv",["out"]),("/nix/store/20vwa6qpx8w3ar66x1fmrjlwy86c7b71-bash-4.4-p23.drv",["out"])],["/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh","/nix/store/m8x2zsc2awjyhwq1fw65czpkikifxq3x-source"],"x86_64-linux","/nix/store/hrpvwkjz04s9i4nmli843hyw9z4pwhww-bash-4.4-p23/bin/bash",["-e","/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],[("buildInputs",""),("buildPhase","gcc -o hello ./hello.c"),("builder","/nix/store/hrpvwkjz04s9i4nmli843hyw9z4pwhww-bash-4.4-p23/bin/bash"),("configureFlags",""),("depsBuildBuild",""),("depsBuildBuildPropagated",""),("depsBuildTarget",""),("depsBuildTargetPropagated",""),("depsHostHost",""),("depsHostHostPropagated",""),("depsTargetTarget",""),("depsTargetTargetPropagated",""),("doCheck",""),("doInstallCheck",""),("installPhase","mkdir -p $out/bin; install -t $out/bin hello"),("name","hello"),("nativeBuildInputs",""),("out","/nix/store/n131z2zya6ifx050b8q3biymx2jxfdwi-hello"),("outputs","out"),("patches",""),("propagatedBuildInputs",""),("propagatedNativeBuildInputs",""),("src","/nix/store/m8x2zsc2awjyhwq1fw65czpkikifxq3x-source"),("stdenv","/nix/store/sm7kk5n84vaisqvhk1yfsjqls50j8s0m-stdenv-linux"),("strictDeps",""),("system","x86_64-linux")])
뉴스 보면서 글 작성하다, 결론이 나고 올립니다.
Read more →