Zigで子・孫のモジュール(依存関係)を使う方法 (zig 0.13.0)

現状zig 0.13.0では、子や孫になっている依存関係と同じモジュールを別のモジュールとしてbuild.zig.zon
で利用すると、error: file exists in multiple modules
と怒られてしまう。
以下でどのように解決したかを備忘録としてメモ。
このケースの場合は、以下のような依存関係ツリーになっていて、delve内で使われているsokolをアプリケーション側でも @import("sokol")
できるようにするのが目的だった。(ちなみに別名でimportしても構わない場合は、Issue内の議論の通り、他にも方法はある。)
app
|--- delve
|
|-- sokol

基本的にはClose直前のコメントに書いた通りで、
(1) 使いたい(孫)モジュールを持っている(子)依存関係の build.zig
で、dependencyのmoduleをそのまま使って、子のモジュールとして孫のモジュールを公開(露出)する。
(例: ここでは、delveというライブラリで使っているsokolをモジュールとして公開する。)
// Add sokol as module, using dependency module itself
try b.modules.put("sokol", dep_sokol.module("sokol"));
(2) こうすることで孫モジュールが子のモジュールとして使えるようになるので、あとはアプリケーション側の build.zig
で addImport
する。
(例: delve
が元々モジュールとして使えていて、(1)でそれと同列にsokol
を公開しているので、使い方はそれと同じ。)
exe.root_module.addImport("sokol", delve_dep.module("sokol"));
// just like:
// exe.root_module.addImport("delve", delve_dep.module("delve"));

前述の(1),(2)の手順を踏めば、あとはアプリケーション側でも子が使っていたモジュール(ここでは @import("sokol")
)が同じように使えるようになる。
なお、(1)が自分の持っているライブラリではなくてやりづらい場合は、フォークしていじるしかない。フォークしたものは以下のようにコミットIDを指定して依存関係 (build.zig.zon
) に含められるので、場合によってはフォークが乱立することになるかもしれないが、一応修正は簡単にできる。
$ zig fetch --save git+https://github.com/funatsufumiya/delve-framework#3e44be1e4efb8d88edbed889a48d1ebca9cbb0f1

このスクラップにメモしている内容は、おそらくzigの依存関係解決が進化すれば、自然解決していくものと思われるので、現状の暫定策でもありつつ、子のモジュールと全く同じバージョンを同じように使いたい場合には今後も有用と思われる。