Skip to content

제작물

내장 함수중 가장 중요한 것은 derivation인데 이는 단일 제작물(빌드 행위)를 묘사합니다. 이 함수는 빌드에 필요한 인풋을 명시하는 특성 집합을 인풋으로 전달받습니다.

  • "i686-linux" 혹은 "x86_64-darwin"과 같이 닉스 시스템 종류를 문자열을 통해 명시하는 system이라는 이름의 특성값이 반드시 포함되어야 합니다. (시스템 타입을 알아내기 위해, nix -vv --version을 실행해볼 수 있습니다.) 빌드는 시스템 타입에 부합하는 기기와 운영체제 에서만 수행될 수 있습니다. (닉스는 자동적으로 다른 플랫폼으로 빌드를 넘겨줄 수 있습니다.

  • 문자열로 이루어진 name이라고 이름지어진 특성을 반드시 포함해야 합니다. 이는 nix-env에 쓰일 패키지 이름을 향하는 심볼릭 링크로 사용됩니다. 추가로, 제작물 아웃풋 경로 맨 뒤에도 덧붙여집니다.

  • 빌드를 수행하고자 실행될 프로그램을 가리키는 builder라는 이름의 특성을 반드시 포함하고 있어야 합니다. 빌더는 제작물이거나 소스일 수 있습니다. (로컬 파일 참조일 수도 있음, 예, ./builder.sh)

  • 모든 특성은 빌더에 환경 변수로써 전달됩니다. 특성값들은 다음 과정을 통해 환경 변수로 전환됩니다:

    • 문자열과 숫자는 있는 그대로 전달됩니다.

    • 경로 (예를 들어, ../foo/sources.tar)는 참조되는 파일이 저장소에 복사되게 만듭니다; 저장소 내부에서의 위치값은 환경 변수에 기입됩니다. 착안점은 모든 소스 코드가 닉스 저장소 내부에 있어야 한다는 점이었습니다. 이는 모든 제작물로 향하는 인풋도 닉스 저장소에 있어야 하기 때문입니다.

    • 제작은 해당 제작이 현재 제작보다 앞서 빌드되는 것을 유발합니다; 제작물의 깁곤 아웃풋 경로는 환경 변수에 기입됩니다.

    • 앞선 타입들의 리스트도 역시 허용됩니다. 해당 리스트들은 단순하게 서로 이어 붙여지며, 공백 문자로 구분됩니다.

    • true는 문자열 1로, falsenull은 빈 문자열로 전달됩니다.

  • 선택적 특성인 args는 빌더에 전달되어야할 커맨드라인 인자를 특정합니다. 반드시 리스트여야 합니다.

  • 선택적 특성인 outputs는 제작물의 아웃풋 심볼릭 링크 리스트를 특정합니다. 기본적으로, 제작물은 하나의 아웃풋 경로를 생성하고, 이를 out으로 표기합니다. 그러나, 제작물은 다양한 아웃풋 경로를 생성할 수도 있습니다. 이는 아웃풋이 각각 다운로드되거나 쓰레기 수집이 각각 이루어지는 것을 허용할 수 있게 되므로 유용합니다. 예를 들어, 다이나믹 라이브러리, 헤더 파일과 문서를 제공하는 라이브러리 패키지를 상상해봅시다. 이 라이브러리와 링크되는 프로그램은 실행 시점에는 헤더 파일과 문서가 필요없고, 빌드 시점에는 문서가 필요없습니다. 따라서, 라이브러리 패키지는 다음과 같이 특정될 수 있습니다:

    outputs = [ "lib" "headers" "doc" ];
    

    이로써 닉스는 lib, headers, doc의 원래 저장소 경로를 포함하는 환경 변수들을 빌더에게 제공할 수 있게 만듭니다. 빌더는 통상적으로 아래와 같은 것들을 수행합니다.

    ./configure \
      --libdir=$lib/lib \
      --includedir=$headers/include \
      --docdir=$doc/share/doc
    

    위는 Autoconf 스타일 패키지의 예시입니다. 제작물의 각 아웃풋도 각각을 특성으로 선택함으로써 참조할 수 있습니다. 예를 들어,

    buildInputs = [ pkg.lib pkg.headers ];
    
    outputs의 첫번째 요소는 아웃풋 기본값을 결정합니다. 그러므로, 아래와 같이 작성할 수도 있습니다.

    buildInputs = [ pkg pkg.headers ];
    

    이는 pkgpkg.lib와 같은것이기 때문에 가능합니다.

Nixpkgs 표준 환경에 존재하는 함수 mkDerivationderivation을 둘러싸는 래퍼(wrapper)입니다. derivationsystem을 위한 기본 값을 추가하고 항상 배쉬를 빌더로써 사용하는데 제작 빌더는 커맨드라인 인자로써 제공될 수도 있습니다. 더 자세한 사항은 Nixpkgs 매뉴얼을 참조하시기 바랍니다.

빌더는 다음과 같이 실행됩니다:

  • 빌더가 자리할 곳으로써 TMPDIR (기본값 /tmp)에 의해 특정된 디렉터리 아래에 임시 디렉터리가 생성됩니다. 현재 디렉터리가 해당 디렉터리로 변경됩니다.

  • 환경이 깔끔하게 정리되고 제작물을 위해 위에서 특정된 특성에 맞는 세팅으로 설정됩니다.

  • 추가적으로, 다음 변수들을 설정합니다:

    • NIX_BUILD_TOP는 이 빌드를 위한 임시 디렉터리 경로를 포함합니다.

    • 또한, TMPDIR, TEMPDIR, TMP, TEMP들도 임시 디렉터리를 가리키도록 설정됩니다. 이는 혹시나 빌더가 실수로 임시 파일을 다른 어딘가라도 작성하게 되는 것을 방지하고자 함입니다. 그런 일이 벌어지는 것은 다른 프로세스에 방해를 유발합니다.

    • PATH/path-not-set으로 설정되어 내장 기본값으로 쉘이 시작되는 것을 방지합니다.

    • HOME/homeless-shelter로 설정되어 /etc/passwd나 사용자 홈 디렉터리에서 찾게 될지도 모르는 프로그램을 사용하는 것을 방지합니다. 그런 프로그램이 사용되면 비순수성을 유발합니다. 일반적으로, HOME이 설정된 경우, 해당 변수가 존재하지 않는 경로를 가리키더라도 홈 디렉터리의 위치로써 사용됩니다.

    • NIX_STORE는 닉스 저장소 디렉터리의 최상위 경로로 세팅됩니다. (통상적으로, /nix/store)

    • outputs에 선언된 각각의 아웃풋에 해당하는 환경변수는 해당 아웃풋을 위해 의도된 닉스 저장소 경로를 가리키도록 설정됩니다. 각 아웃풋 경로는 모든 빌드 인풋, name 특성, 아웃풋 이름의 암호화 해쉬로 이어붙여집니다. (아웃풋 이름은 out과 동일하면 생략됨)

  • 아웃풋 경로가 이미 존재하는 경우, 삭제됩니다. 또한, 동시에 여러개의 같은 빌드가 수행되는 것을 방지하고자 잠금(lock)이 활성화됩니다.

  • 일반 출력과 에러가 혼합된 로그는 /nix/var/log/nix에 기록됩니다.

  • 빌더는 args 특성에 특정된 인자들로 실행됩니다. 만약 종료 코드 0과 함께 종료한 경우, 성공한 것으로 간주됩니다.

  • (-K 옵션이 특정되지 않은 이상) 임시 디렉터리는 삭제됩니다.

  • 빌드가 성공적인 경우, 닉스는 인풋의 해쉬값 부분을 활용해 아웃풋 경로에서 인풋 경로로 향하는 참조를 탐색합니다. 이 참조들은 잠재적으로 실행 시점 의존성일 수 있기 때문에 닉스는 그것들을 아웃풋 경로 의존성으로써 등록해둡니다.

  • 빌드 이후, 닉스는 빌드 결과 파일의 모든 마지막 수정 타임스탬프를 1 (00:00:01 1/1/1970 UTC)로 설정합니다. 그룹을 기본 그룹으로 설정합니다. 파일 모드는 0444나 0555로 설정합니다(예, 읽기 전용, 파일이 원래 실행 가능했던 경우에는 실행 허가도 켬) 있을지 모르는 setuidsetgid 비트도 초기화됩니다. setuid와 setgid 프로그램은 현재로써 닉스에서 지원되지 않습니다. 이는 배포에 활용되는 닉스 압축 파일에 소유자 정보 개념이 없고, 있다 하더라도 해당 정보는 빌드를 수행하는 사용자에 의존하는 결과를 낳게 되기 때문입니다.


Last update: November 4, 2021
Back to top