Closed4

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

funatsufumiyafunatsufumiya

現状zig 0.13.0では、子や孫になっている依存関係と同じモジュールを別のモジュールとしてbuild.zig.zonで利用すると、error: file exists in multiple modules と怒られてしまう。

以下でどのように解決したかを備忘録としてメモ。

https://github.com/Interrupt/delve-framework/issues/77

このケースの場合は、以下のような依存関係ツリーになっていて、delve内で使われているsokolをアプリケーション側でも @import("sokol") できるようにするのが目的だった。(ちなみに別名でimportしても構わない場合は、Issue内の議論の通り、他にも方法はある。)

app
 |--- delve
        |
        |-- sokol
funatsufumiyafunatsufumiya

基本的には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"));

https://github.com/funatsufumiya/delve-framework/blob/1211a792c9795642f564ce6c6b9e1b7c8334acfd/build.zig#L117

(2) こうすることで孫モジュールが子のモジュールとして使えるようになるので、あとはアプリケーション側の build.zigaddImport する。

(例: delveが元々モジュールとして使えていて、(1)でそれと同列にsokolを公開しているので、使い方はそれと同じ。)

exe.root_module.addImport("sokol", delve_dep.module("sokol"));
// just like:
// exe.root_module.addImport("delve", delve_dep.module("delve"));

https://github.com/funatsufumiya/zig-delve-pbr-study/blob/25310f578f7a4d59df9cd21f96212a6ef6f685c7/build.zig#L48

funatsufumiyafunatsufumiya

前述の(1),(2)の手順を踏めば、あとはアプリケーション側でも子が使っていたモジュール(ここでは @import("sokol"))が同じように使えるようになる。

なお、(1)が自分の持っているライブラリではなくてやりづらい場合は、フォークしていじるしかない。フォークしたものは以下のようにコミットIDを指定して依存関係 (build.zig.zon) に含められるので、場合によってはフォークが乱立することになるかもしれないが、一応修正は簡単にできる。

$ zig fetch --save git+https://github.com/funatsufumiya/delve-framework#3e44be1e4efb8d88edbed889a48d1ebca9cbb0f1
funatsufumiyafunatsufumiya

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

このスクラップは2025/01/23にクローズされました