❄️

Nixpkgsに存在しないパッケージを使う

に公開2

挨拶

こんにちは、T4D4です。
最近、NixOSを使い始めたのですが、使いたいパッケージがNixpkgsに存在しなかったので、Nixpkgsに存在しないパッケージを使う方法を調べ、実際に試してみました。

GitHub Copilot(GPT-4o)に相談したところ、以下の方法があるようです。

  1. オーバーレイを使う

    • Nixpkgsに新しいパッケージや修正を追加できます。主に既存パッケージの上書き用途が多い印象。
  2. ローカルにパッケージ定義を書く

    • Nixpkgsにないパッケージをローカルで定義し、それを使う方法。
  3. nivを使う

    • nivはNixの依存管理ツール。プロジェクト単位でパッケージを管理するのに便利。
  4. import関数を使う

    • ローカルまたはリモートのNixファイルをインポートして利用する。

上記の中から、今回は 「ローカルにパッケージ定義を書く」 方法を試してみました。
オーバーレイは既存パッケージの上書き向け、nivはプロジェクト単位の管理向け、import関数は外部Nixファイルの利用向けだと考えたため、それらの方法は今回は見送りました。

実際にやってみる。

ローカルにパッケージ定義を書く方法について、公式のドキュメントを見つけたので、そちらを参考に、Internet Computer(IC)の開発に必須のツールであるDFXをパッケージ化してみます。

まず、以下のような基本的なパッケージ定義ファイル(dfx.nix)を作成します:

dfx.nix
{ stdenv, fetchzip }:

let
  version = "0.25.0"; # バージョンを変数として定義
in

stdenv.mkDerivation {
  pname = "dfx";
  inherit version;

  src = fetchzip {
    url = "https://github.com/dfinity/sdk/releases/download/${version}/dfx-${version}-x86_64-linux.tar.gz";
    sha256 = ""; # SHA-256 ハッシュ(後で設定)
  };
}

ハッシュが空白になっています。これは、アーカイブがダウンロードされ、解凍されるまで知ることが出来ません。fetchzipに与えられたハッシュが正しくない場合、Nixはエラーを返します。なので、ハッシュを空にしておき、返ってきたエラーメッセージから正しいハッシュを取得します。
とりあえずnix-buildしてみます。すると、次のようなエラーが出ました。

gitpod /workspace/dotfiles/pkgs (master) $ nix-build dfx.nix 
error: cannot evaluate a function that has an argument without a value ('stdenv')
       Nix attempted to evaluate a function as a top level expression; in
       this case it must have its arguments supplied either by default
       values, or passed explicitly with '--arg' or '--argstr'. See
       https://nixos.org/manual/nix/stable/language/constructs.html#functions.

       at /workspace/dotfiles/pkgs/dfx.nix:1:3:

            1| { stdenv, fetchzip }:
             |   ^
            2|

stdenvはnixplkgsから利用可能で、このderivationに引数として渡すには、別のNix式でインポートする必要があるようです。そこで、dfx.nixと同じディレクトリに以下のようなファイルを作成します。

default.nix
# default.nix
let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
  pkgs = import nixpkgs { config = {}; overlays = []; };
in
{
  dfx = pkgs.callPackage ./dfx.nix { };
}

これによる、nix-build -A dfxを実行すると、先ほどのエラーとは異なる次のような出力を得られます。

gitpod /workspace/dotfiles/pkgs (master) $ nix-build -A dfx
warning: found empty hash, assuming 'sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
these 2 derivations will be built:
  /nix/store/lh2h9h56ah20j977r4d26nqdfj3c29yd-source.drv
  /nix/store/kqir6vgzka3yy2d147mjgbdwrkixb59h-dfx-0.25.0.drv
building '/nix/store/lh2h9h56ah20j977r4d26nqdfj3c29yd-source.drv'...

trying https://github.com/dfinity/sdk/releases/download/0.25.0/dfx-0.25.0-x86_64-linux.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  133M  100  133M    0     0  23.8M      0  0:00:05  0:00:05 --:--:-- 29.9M
unpacking source archive /tmp/nix-build-source.drv-0/dfx-0.25.0-x86_64-linux.tar.gz
error: hash mismatch in fixed-output derivation '/nix/store/lh2h9h56ah20j977r4d26nqdfj3c29yd-source.drv':
         specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
            got:    sha256-OWqmvgMd2dT8rSlrrLtfmNm1/sjYa1h6+AbpX7uWdnk=
error: 1 dependencies of derivation '/nix/store/kqir6vgzka3yy2d147mjgbdwrkixb59h-dfx-0.25.0.drv' failed to build

上のログの仲に、

specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
   got:    sha256-OWqmvgMd2dT8rSlrrLtfmNm1/sjYa1h6+AbpX7uWdnk=

という行があります。これは、指定したハッシュ(空白にしておくと勝手に「sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=」と設定される)と実際にダウンロードしたハッシュが異なることを示しています。なので、dfx.nixsha256の部分を正しいハッシュに置き換えて再度nix-build -A dfxを実行します。

gitpod /workspace/dotfiles/pkgs (master) $ nix-build -A dfx
this derivation will be built:
  /nix/store/i65bl3q8lni1cy57n5yyfckwi48ih6a8-dfx-0.25.0.drv
warning: Ignoring setting 'auto-allocate-uids' because experimental feature 'auto-allocate-uids' is not enabled
warning: Ignoring setting 'impure-env' because experimental feature 'configurable-impure-env' is not enabled
building '/nix/store/i65bl3q8lni1cy57n5yyfckwi48ih6a8-dfx-0.25.0.drv'...
Running phase: unpackPhase
unpacking source archive /nix/store/3pxr9ab7c7j4mlh7wardigm9dyjvcy6d-source
source root is source
Running phase: patchPhase
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: configurePhase
no configure script, doing nothing
Running phase: buildPhase
no Makefile or custom buildPhase, doing nothing
Running phase: installPhase
no Makefile or custom installPhase, doing nothing
Running phase: fixupPhase
error: builder for '/nix/store/i65bl3q8lni1cy57n5yyfckwi48ih6a8-dfx-0.25.0.drv' failed to produce output path for output 'out' at '/nix/store/p73psaxj6412bcdmlp22zv3j4hmqh1w1-dfx-0.25.0'

残念ながらまたエラーです。参考元の記事では、サンプルのコマンドが簡単なモノだからかハッシュを正しく設定すれば成功して終了だったのですが、残念ながらDFXでは上手くいかないみたいです... エラーメッセージによると、 installPhaseで何も行われていないため、出力パスが生成されていないようです。installPhaseをカスタマイズして、必要なファイルを適切な場所にインストールする必要があります。(ByGitHubCopilot) なので、公式ドキュメントを参考に以下のようなinstallPhaseの設定を追記します。

dfx.nix
  installPhase = ''
    mkdir -p $out/bin
    cp -r * $out/bin/
  '';

追記後に再度nix-build -A dfxを実行すると、ビルドに成功し、/result/bin/dfxが生成されると思います。あとは、任意の方法で/result/bin/dfxをPATHに追加すれば、dfxを使えるようになります。
残念ながら、非NixOS環境では、/result/bin/dfxを実行できますが、NixOSでは、

Could not start dynamically linked executable: ./result/bin/dfx Nix0S cannot run dynamically linked executables intended for generic linux environments out of the box. For more information, see: https://nix.dev/permalink/stub-ld

というエラーが出てしまい、実行出来ません。
エラーメッセージ内に出て来るURLによると、

NixOSは、一般的なLinux環境向けにダイナミックリンクされた実行ファイルを、そのままでは実行できません。これは、設計上、グローバルなライブラリパスを持たず、ファイルシステム・ヒエラルキー・スタンダード(FHS)に従っていないからです。(DeepLによる翻訳)
とのこです。
なので、NixOSで実行する為にはもう少し手を加える必要があります。
ドキュメントを読んだところ、autoPatchelfHookを使うと、必要な共有ライブラリの依存関係が適切に設定されていることを確認し、実行可能ファイルを修正してくれるようです。なので、以下のようにdfx.nixを修正します。

dfx.nix
{ stdenv, fetchzip, autoPatchelfHook }:

let
  version = "0.25.0"; # バージョンを変数として定義
in
stdenv.mkDerivation {
  pname = "dfx";
  inherit  version; # バージョンを継承

  src = fetchzip {
    url = "https://github.com/dfinity/sdk/releases/download/${version}/dfx-${version}-x86_64-linux.tar.gz";
    sha256 = "OWqmvgMd2dT8rSlrrLtfmNm1/sjYa1h6+AbpX7uWdnk="; # SHA-256 ハッシュ
  };
  nativeBuildInputs = [ autoPatchelfHook ];

  installPhase = ''
    runHook preInstall
    mkdir -p $out/bin
    cp -r * $out/bin
    runHook postInstall
  '';
}

これで、nix-build -A dfxを実行すると、次のようなエラーが出ます。

長いので折り畳み
this derivation will be built:
  /nix/store/zjghn09xp0sd22rkh1wqsz6ibwawci80-dfx-0.25.0.drv

these 17 paths will be fetched (40.82 MiB download, 133.79 MiB unpacked):
  /nix/store/46zq1hcvd2cnl07rjv0ywcgf59p8w9gm-auto-patchelf-hook
  /nix/store/gq0xyjrkaqvknshf8r6si13ckdv6p7yq-binutils-wrapper-2.41
  /nix/store/sg0xabw675wgc8y1rl6mymmhggqkqmjr-expand-response-params
  /nix/store/nbbg70f6gihj51p65kv19m0fnq8ik5kh-expat-2.6.4
  /nix/store/y8fzwmygqh9rl5rc8rvcydcskgszldpn-gdbm-1.23
  /nix/store/gniy4ab9wcijxjpcciddgpzdwq3v3dnb-libffi-3.4.6
  /nix/store/bb99dclcsv3r0a8q967bnvga02qicxsf-libxcrypt-4.4.36
  /nix/store/v68clh8wa74xxblx0b748vr50gl7xnzc-mailcap-2.1.53
  /nix/store/6x0n8ksnajz1kf7n6q0farmyrc6af4mz-mpdecimal-4.0.0
  /nix/store/zmi2nlx42h1qrs2v7yn142dq4zjq30im-ncurses-6.4
  /nix/store/p8hw2h465g0byxwpamnk6gv6mp5gnqn2-openssl-3.0.14
  /nix/store/s0p1kr5mvs0j42dq5r08kgqbi0k028f2-python3-3.11.10
  /nix/store/v9zjfpkffznvnlaa28mdkc5kr3ka9y6c-python3-3.11.10-env
  /nix/store/6frx0rrqvrjgc5axzih8ybp6x8i3lnfc-python3.11-pyelftools-0.31
  /nix/store/rafcl7sl3f9757z4m5hl7vaklppi8xkr-readline-8.2p10
  /nix/store/0pjc3s5k0zlc56xs2z0cmvq885zkij9h-sqlite-3.45.3
  /nix/store/vil8wqacfkz8qx09aymahxv48d1zq3g2-tzdata-2024b

copying path '/nix/store/sg0xabw675wgc8y1rl6mymmhggqkqmjr-expand-response-params' from 'https://cache.nixos.org'...
copying path '/nix/store/v68clh8wa74xxblx0b748vr50gl7xnzc-mailcap-2.1.53' from 'https://cache.nixos.org'...
copying path '/nix/store/vil8wqacfkz8qx09aymahxv48d1zq3g2-tzdata-2024b' from 'https://cache.nixos.org'...
copying path '/nix/store/nbbg70f6gihj51p65kv19m0fnq8ik5kh-expat-2.6.4' from 'https://cache.nixos.org'...
copying path '/nix/store/y8fzwmygqh9rl5rc8rvcydcskgszldpn-gdbm-1.23' from 'https://cache.nixos.org'...
copying path '/nix/store/gniy4ab9wcijxjpcciddgpzdwq3v3dnb-libffi-3.4.6' from 'https://cache.nixos.org'...
copying path '/nix/store/bb99dclcsv3r0a8q967bnvga02qicxsf-libxcrypt-4.4.36' from 'https://cache.nixos.org'...
copying path '/nix/store/zmi2nlx42h1qrs2v7yn142dq4zjq30im-ncurses-6.4' from 'https://cache.nixos.org'...
copying path '/nix/store/6x0n8ksnajz1kf7n6q0farmyrc6af4mz-mpdecimal-4.0.0' from 'https://cache.nixos.org'...
copying path '/nix/store/p8hw2h465g0byxwpamnk6gv6mp5gnqn2-openssl-3.0.14' from 'https://cache.nixos.org'...
copying path '/nix/store/0pjc3s5k0zlc56xs2z0cmvq885zkij9h-sqlite-3.45.3' from 'https://cache.nixos.org'...
copying path '/nix/store/gq0xyjrkaqvknshf8r6si13ckdv6p7yq-binutils-wrapper-2.41' from 'https://cache.nixos.org'...
copying path '/nix/store/rafcl7sl3f9757z4m5hl7vaklppi8xkr-readline-8.2p10' from 'https://cache.nixos.org'...
copying path '/nix/store/s0p1kr5mvs0j42dq5r08kgqbi0k028f2-python3-3.11.10' from 'https://cache.nixos.org'...
copying path '/nix/store/6frx0rrqvrjgc5axzih8ybp6x8i3lnfc-python3.11-pyelftools-0.31' from 'https://cache.nixos.org'...
copying path '/nix/store/v9zjfpkffznvnlaa28mdkc5kr3ka9y6c-python3-3.11.10-env' from 'https://cache.nixos.org'...
copying path '/nix/store/46zq1hcvd2cnl07rjv0ywcgf59p8w9gm-auto-patchelf-hook' from 'https://cache.nixos.org'...

building '/nix/store/zjghn09xp0sd22rkh1wqsz6ibwawci80-dfx-0.25.0.drv'...

Running phase: unpackPhase
  unpacking source archive /nix/store/3pxr9ab7c7j4mlh7wardigm9dyjvcy6d-source
  source root is source

Running phase: patchPhase

Running phase: updateAutotoolsGnuConfigScriptsPhase

Running phase: configurePhase
  no configure script, doing nothing

Running phase: buildPhase
  no Makefile or custom buildPhase, doing nothing

Running phase: installPhase

Running phase: fixupPhase
  shrinking RPATHs of ELF executables and libraries in /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0
  shrinking /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0/bin/dfx
  checking for references to /build/ in /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0...
  patching script interpreter paths in /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0
  stripping (with command strip and flags -S -p) in /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0/bin

automatically fixing dependencies for ELF files
  {'append_rpaths': [], 'extra_args': [], 'ignore_missing': [], 'libs': [PosixPath('/nix/store/46zq1hcvd2cnl07rjv0ywcgf59p8w9gm-auto-patchelf-hook/lib'), PosixPath('/nix/store/gq0xyjrkaqvknshf8r6si13ckdv6p7yq-binutils-wrapper-2.41/lib'), PosixPath('/nix/store/2wp235bg03gykpixd9v2nyxp08w8xq8a-patchelf-0.15.0/lib'), PosixPath('/nix/store/2329271b42wh6b6yhl7jmjyi0cs4428b-update-autotools-gnu-config-scripts-hook/lib'), PosixPath('/nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh/lib'), PosixPath('/nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh/lib'), PosixPath('/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh/lib'), PosixPath('/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh/lib'), PosixPath('/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh/lib'), PosixPath('/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh/lib'), PosixPath('/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh/lib'), PosixPath('/nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh/lib'), PosixPath('/nix/store/ilaf1w22bxi6jsi45alhmvvdgy4ly3zs-patch-shebangs.sh/lib'), PosixPath('/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh/lib'), PosixPath('/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh/lib'), PosixPath('/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh/lib'), PosixPath('/nix/store/gps9qrh99j7g02840wv5x78ykmz30byp-strip.sh/lib'), PosixPath('/nix/store/rdc1jnyw74mwr2gszqc5zwi433zxs089-gcc-wrapper-13.2.0/lib'), PosixPath('/nix/store/rl56awy2w2iwvgdmibv98k0vx7lzyw21-binutils-wrapper-2.41/lib'), PosixPath('/nix/store/46zq1hcvd2cnl07rjv0ywcgf59p8w9gm-auto-patchelf-hook/lib'), PosixPath('/nix/store/gq0xyjrkaqvknshf8r6si13ckdv6p7yq-binutils-wrapper-2.41/lib'), PosixPath('/nix/store/2wp235bg03gykpixd9v2nyxp08w8xq8a-patchelf-0.15.0/lib'), PosixPath('/nix/store/2329271b42wh6b6yhl7jmjyi0cs4428b-update-autotools-gnu-config-scripts-hook/lib'), PosixPath('/nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh/lib'), PosixPath('/nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh/lib'), PosixPath('/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh/lib'), PosixPath('/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh/lib'), PosixPath('/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh/lib'), PosixPath('/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh/lib'), PosixPath('/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh/lib'), PosixPath('/nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh/lib'), PosixPath('/nix/store/ilaf1w22bxi6jsi45alhmvvdgy4ly3zs-patch-shebangs.sh/lib'), PosixPath('/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh/lib'), PosixPath('/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh/lib'), PosixPath('/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh/lib'), PosixPath('/nix/store/gps9qrh99j7g02840wv5x78ykmz30byp-strip.sh/lib'), PosixPath('/nix/store/rdc1jnyw74mwr2gszqc5zwi433zxs089-gcc-wrapper-13.2.0/lib'), PosixPath('/nix/store/rl56awy2w2iwvgdmibv98k0vx7lzyw21-binutils-wrapper-2.41/lib')], 'paths': [PosixPath('/nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0')], 'recursive': True, 'runtime_dependencies': []}
  setting interpreter of /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0/bin/dfx
  searching for dependencies of /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0/bin/dfx
  libstdc++.so.6 -> not found!
  libgcc_s.so.1 -> not found!
  auto-patchelf: 2 dependencies could not be satisfied
  error: auto-patchelf could not satisfy dependency libstdc++.so.6 wanted by /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0/bin/dfx
  error: auto-patchelf could not satisfy dependency libgcc_s.so.1 wanted by /nix/store/zz4s5hvgb9zgkchh5a5q80ysryyg71ng-dfx-0.25.0/bin/dfx
  auto-patchelf failed to find all the required dependencies. Add the missing dependencies to --libs or use `--ignore-missing="foo.so.1 bar.so etc.so"`.

error: builder for '/nix/store/zjghn09xp0sd22rkh1wqsz6ibwawci80-dfx-0.25.0.drv' failed with exit code 1; last 25 log lines:
  > PosixPath('/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh/lib'),
  > PosixPath('/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh/lib'),
  > PosixPath('/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh/lib'),
  > PosixPath('/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh/lib'),
  > PosixPath('/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh/lib'),
  > PosixPath('/nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh/lib'),
  > PosixPath('/nix/store/ilaf1w22bxi6jsi45alhmvvdgy4ly3zs-patch-shebangs.sh/lib'),
  > PosixPath('/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh/lib'),
  > PosixPath('/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh/lib'),
  > PosixPath('/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh/lib'),
  >

なかなか長いですが、大事そうなのは次の2行です

  libstdc++.so.6 -> not found!
  libgcc_s.so.1 -> not found!

libstdc++.so.6とlibgcc_s.so.1が見つからないというエラーです。これらは、GCCのC++標準ライブラリとGCCのランタイムライブラリです。これらの依存関係を解決するために、dfx.nixを次のように更新します。

dfx.nix
{ stdenv, fetchzip, autoPatchelfHook, gcc }:

let
  version = "0.25.0"; # バージョンを変数として定義
in
stdenv.mkDerivation {
  pname = "dfx";
  inherit  version; # バージョンを継承

  src = fetchzip {
    url = "https://github.com/dfinity/sdk/releases/download/${version}/dfx-${version}-x86_64-linux.tar.gz";
    sha256 = "OWqmvgMd2dT8rSlrrLtfmNm1/sjYa1h6+AbpX7uWdnk="; # SHA-256 ハッシュ
  };
  nativeBuildInputs = [ autoPatchelfHook ];

  buildInputs = [ gcc.cc.lib ];

  installPhase = ''
    runHook preInstall
    mkdir -p $out/bin
    cp -r * $out/bin
    runHook postInstall
  '';
}

これで実行すると、ビルドが成功します。

長いので再度折り畳み
❯ nix-build -A dfx
this derivation will be built:
  /nix/store/6x9vb9gdmmz6580kgxw5k4i7540nqkhh-dfx-0.25.0.drv
building '/nix/store/6x9vb9gdmmz6580kgxw5k4i7540nqkhh-dfx-0.25.0.drv'...
Running phase: unpackPhase
unpacking source archive /nix/store/3pxr9ab7c7j4mlh7wardigm9dyjvcy6d-source
source root is source
Running phase: patchPhase
Running phase: updateAutotoolsGnuConfigScriptsPhase
Running phase: configurePhase
no configure script, doing nothing
Running phase: buildPhase
no Makefile or custom buildPhase, doing nothing
Running phase: installPhase
Running phase: fixupPhase
shrinking RPATHs of ELF executables and libraries in /nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0
shrinking /nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0/bin/dfx
checking for references to /build/ in /nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0...
patching script interpreter paths in /nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0
stripping (with command strip and flags -S -p) in  /nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0/bin
automatically fixing dependencies for ELF files
{'append_rpaths': [],
 'extra_args': [],
 'ignore_missing': [],
 'libs': [PosixPath('/nix/store/46zq1hcvd2cnl07rjv0ywcgf59p8w9gm-auto-patchelf-hook/lib'),
          PosixPath('/nix/store/gq0xyjrkaqvknshf8r6si13ckdv6p7yq-binutils-wrapper-2.41/lib'),
          PosixPath('/nix/store/2wp235bg03gykpixd9v2nyxp08w8xq8a-patchelf-0.15.0/lib'),
          PosixPath('/nix/store/2329271b42wh6b6yhl7jmjyi0cs4428b-update-autotools-gnu-config-scripts-hook/lib'),
          PosixPath('/nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh/lib'),
          PosixPath('/nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh/lib'),
          PosixPath('/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh/lib'),
          PosixPath('/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh/lib'),
          PosixPath('/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh/lib'),
          PosixPath('/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh/lib'),
          PosixPath('/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh/lib'),
          PosixPath('/nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh/lib'),
          PosixPath('/nix/store/ilaf1w22bxi6jsi45alhmvvdgy4ly3zs-patch-shebangs.sh/lib'),
          PosixPath('/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh/lib'),
          PosixPath('/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh/lib'),
          PosixPath('/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh/lib'),
          PosixPath('/nix/store/gps9qrh99j7g02840wv5x78ykmz30byp-strip.sh/lib'),
          PosixPath('/nix/store/rdc1jnyw74mwr2gszqc5zwi433zxs089-gcc-wrapper-13.2.0/lib'),
          PosixPath('/nix/store/rl56awy2w2iwvgdmibv98k0vx7lzyw21-binutils-wrapper-2.41/lib'),
          PosixPath('/nix/store/90yn7340r8yab8kxpb0p7y0c9j3snjam-gcc-13.2.0-lib/lib'),
          PosixPath('/nix/store/46zq1hcvd2cnl07rjv0ywcgf59p8w9gm-auto-patchelf-hook/lib'),
          PosixPath('/nix/store/gq0xyjrkaqvknshf8r6si13ckdv6p7yq-binutils-wrapper-2.41/lib'),
          PosixPath('/nix/store/2wp235bg03gykpixd9v2nyxp08w8xq8a-patchelf-0.15.0/lib'),
          PosixPath('/nix/store/2329271b42wh6b6yhl7jmjyi0cs4428b-update-autotools-gnu-config-scripts-hook/lib'),
          PosixPath('/nix/store/h9lc1dpi14z7is86ffhl3ld569138595-audit-tmpdir.sh/lib'),
          PosixPath('/nix/store/m54bmrhj6fqz8nds5zcj97w9s9bckc9v-compress-man-pages.sh/lib'),
          PosixPath('/nix/store/wgrbkkaldkrlrni33ccvm3b6vbxzb656-make-symlinks-relative.sh/lib'),
          PosixPath('/nix/store/5yzw0vhkyszf2d179m0qfkgxmp5wjjx4-move-docs.sh/lib'),
          PosixPath('/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh/lib'),
          PosixPath('/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh/lib'),
          PosixPath('/nix/store/pag6l61paj1dc9sv15l7bm5c17xn5kyk-move-systemd-user-units.sh/lib'),
          PosixPath('/nix/store/jivxp510zxakaaic7qkrb7v1dd2rdbw9-multiple-outputs.sh/lib'),
          PosixPath('/nix/store/ilaf1w22bxi6jsi45alhmvvdgy4ly3zs-patch-shebangs.sh/lib'),
          PosixPath('/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh/lib'),
          PosixPath('/nix/store/xyff06pkhki3qy1ls77w10s0v79c9il0-reproducible-builds.sh/lib'),
          PosixPath('/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh/lib'),
          PosixPath('/nix/store/gps9qrh99j7g02840wv5x78ykmz30byp-strip.sh/lib'),
          PosixPath('/nix/store/rdc1jnyw74mwr2gszqc5zwi433zxs089-gcc-wrapper-13.2.0/lib'),
          PosixPath('/nix/store/rl56awy2w2iwvgdmibv98k0vx7lzyw21-binutils-wrapper-2.41/lib'),
          PosixPath('/nix/store/90yn7340r8yab8kxpb0p7y0c9j3snjam-gcc-13.2.0-lib/lib')],
 'paths': [PosixPath('/nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0')],
 'recursive': True,
 'runtime_dependencies': []}
setting interpreter of /nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0/bin/dfx
searching for dependencies of /nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0/bin/dfx
    libstdc++.so.6 -> found: /nix/store/90yn7340r8yab8kxpb0p7y0c9j3snjam-gcc-13.2.0-lib/lib
    libgcc_s.so.1 -> found: /nix/store/dd13q38yxm9qppjclsvwn10dscsf0l9w-gcc-13.2.0-libgcc/lib
setting RPATH to: /nix/store/90yn7340r8yab8kxpb0p7y0c9j3snjam-gcc-13.2.0-lib/lib:/nix/store/dd13q38yxm9qppjclsvwn10dscsf0l9w-gcc-13.2.0-libgcc/lib
auto-patchelf: 0 dependencies could not be satisfied
/nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0

これでresult/bin/dfxか/nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0のパスを指定してあげるとNixOSでもパス指定で実行できるようになりました。

おまけ

実行する度に都度パスを指定するのは滅茶苦茶ダルいです。なので場所を問わずdfxだけで実行できるようにします。 方法は色々ありますが、僕は変にズボラなのでzshの設定でdfxにエイリアスを設定しました。 最後のビルドが成功した旨のログの一番下の行によると、/nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0に保存されていることがわかります。なので、dfx = "/nix/store/dxv0z93dqw50b6ccw8x98nshf6yp0n8v-dfx-0.25.0";とエイリアスを設定してあげてシェルを再起動するとdfxだけで実行できるようになります。 多分ベターな方法は他にあると思いますが、ここまで来るのに疲れてしまったので最初に思いついた手っ取り早い方法で終わらせました。 この方法には明確なデメリットが一つあって、バージョンアップで更新したらインストール先のパスも当然変わってしまうので都度エイリアスとして設定しているパスを更新する必要があるという点です。でも、以外とそれぐらいしか思いつかないので悪くないかもしれないですね。

終わりに

NixOSでnixpkgsに存在しないパッケージをNixOSで使えるようにする方法を実際に試してみました。 これで、NixOSでもdfxを使えるようになりました。 今回はdfxを例にしたのでfetchzipを使いましたが、fetchFromGitHub等、他の関数もあるので、パッケージに合わせて使い分けてください。とりあえず実際にやってみて、僕がNixOSに詳しくないのもあって、色々とハードでした。他の人が使えるようにとNix式を書いてnixpkgsにパッケージを登録してくれているコントリビューターの方々の貢献度は非常に大きいと思いました。今後も彼らに感謝して、NixOSを使っていこうと思います。

Discussion

turttonturtton

実行する度に都度パスを指定するのは滅茶苦茶ダルいです。なので場所を問わずdfxだけで実行できるようにします。 方法は色々ありますが、僕は変にズボラなのでzshの設定でdfxにエイリアスを設定しました

Github上のdotflesをみかけて、flakeも使われているということでしたので flake.nix nixosConfigurations = {の上あたりに

packages."x86_64-linux" = let
  pkgs = import input.nixpkgs { system = "x86_64-linux"; ]; };
in {
  dfx = pkgs.callPackage ./pkgs/dfx.nix { };
}

みたいな感じの内容を追記すると、flake.nixがあるフォルダ上ではnix run .#dfxで、内容をGitHubにプッシュした後ならnix run github:T4D4-IU/dotfiles#dfxでどこでも実行できるようになってより便利だと思います[1]。是非に

脚注
  1. https://zenn.dev/asa1984/books/nix-introduction/viewer/11-flakes#outputs ↩︎

T4D4T4D4

コメントありがとうございます!コメント貰えたのが初めてで、しかも一番欲しいタイプのコメントを頂けて感動しています。😭😭😭
提案していただいたようにflake.nixを更新したら無事にnix run .#dfxnix run github:T4D4-IU/dotfiles#dfxも動作しました!ありがとうございます!!!