Nix flakesでwasmtimeを使う時にwasmtime/conf.hを追加でインストールする方法
問題
wasmtimeとC FFIで連携するHaskellプログラムが以下のエラーでcabal build
に失敗する。
error: 次のファイルから読み込み: Wasi.hsc:5:
/nix/store/yk4x6g0g36h5bvczrq9jvmbsr5g927di-wasmtime-29.0.1-dev/include/wasi.h:12:10: 致命的エラー: wasmtime/conf.h: No such file or directory
12 | #include <wasmtime/conf.h>
| ^~~~~~~~~~~~~~~~~
コンパイルを停止しました。
Error: [Cabal-7125]
cabalファイルにextra-libraries: wasmtime
と書いてあっても失敗する。
wasmtime自体はNix flakesでインストールしている。
wasmtime
コマンド自体はちゃんと動く。そもそもwasi.h
はwasmtimeパッケージのファイルである。
実際にwasmtime/conf.h
ヘッダーファイルは存在していない。
原因
調べてみたところ、 C APIのヘッダーファイルはcargoでビルドしたあとにcmakeでビルドするシステムになっているらしい。
not all headers are installed for C API · Issue #9382 · bytecodealliance/wasmtime
なんでそんなことになっているのかはよくわからない。 cargoの制限の都合とかですかね…?
それはさておき、追加の手順が必要ならば、追加の手順を追加するだけですね。
解決
Nix flakesにはpostInstallとoverlayの機能があるので、追加のインストール手順を渡してやれば良さそうだ。
元々のpostInstall
をnix replで確認する。
nix-repl> :p pkgs.wasmtime.postInstall
:p pkgs.wasmtime.postInstall
# move libs from out to dev
install -d -m 0755 $dev/lib
install -m 0644 ${!outputLib}/lib/* $dev/lib
rm -r ${!outputLib}/lib
install -d -m0755 $dev/include/wasmtime
install -m0644 $src/crates/c-api/include/*.h $dev/include
install -m0644 $src/crates/c-api/include/wasmtime/*.h $dev/include/wasmtime
これを元にoverlays
にoverlayを追加して、
postInstall
に追加のインストール手順を追加する。
(self: super: {
wasmtime = super.wasmtime.overrideAttrs (oldAttrs: {
postInstall = ''
${oldAttrs.postInstall or ""}
cmake -S crates/c-api -B target/c-api --install-prefix "$(pwd)/artifacts"
cmake --build target/c-api
cmake --install target/c-api
install -m0644 $(pwd)/artifacts/include/wasmtime/conf.h $dev/include/wasmtime
'';
});
})
少し注意するポイントは$src
などにはビルドが終わってからは簡単に書き込めないこと。なのでインストール元のディレクトリは$src
からではなく$(pwd)
から辿る必要がある。
問題解決手順自体は大したものではなかったが、そもそもoverlayを追加する場所を間違えて追加ビルドが走らなかったりして迷ってしまった。まだ私はNixに習熟していないと感じる。
追加形式である必要はないかも
oldAttrs.postInstall
に追加する形式で書いたが、これを除いてもインストールコマンドは走った。追加形式である必要はないのかもしれない。