Open4

Zig Tips

ktz_aliasktz_alias

バッファリングしながら標準入力から読み込む

    const stdin = std.io.getStdIn().reader();
    const allocator = std.heap.page_allocator;

    var buffer = std.ArrayList(u8).init(allocator);
    defer buffer.deinit();

    try stdin.streamUntilDelimiter(buffer.writer(), '\n', null);
    const input = try buffer.toOwnedSlice();
    defer allocator.free(input);

    std.debug.print("CMD: {s}, (len: {})\n", .{input, input.len});

説明

Reader型の各種readUntilXXXは最大読み込みサイズを指定する必要がある。
標準入力の読み込みでは指定する値がないため、必然的にstreamUntilDelimiterを使わなければならない。

ktz_aliasktz_alias

名前付きプレースホルダで文字列整形

std.debug.print("{[a]s:_>[width]}", .{.s = "foo", .width = 10});

出力結果:

_______foo

説明

プレースホルダの中の[]は指定した名前のパラメータで置換できる。
上の例では、sの前の[]は最終出力する値、^の後の[]は成形される幅

See also:
https://ziggit.dev/t/dynamic-string-formatting/6614/3

ktz_aliasktz_alias

Zig以外の言語で提供されるライブラリのバインディングを作る

例えば内部コードがC/C++で記述されてており、それがgithubでホスティングされている場合、
submoduleで自身のバインディングのレポジトリに取り込むことが真っ先に思い浮かぶ。

しかし、zigのパッケージ管理はパッケージのサブモジュールまで面倒見ない。
そのためzig fetchで持ってきても、自身でサブモジュールの更新を行う必要がある。

それよりも楽な方法として、内部コードのレポジトリをzigの依存として取り込む方法がある。
内部コードはzigのモジュールではないためモジュールとして構成はできないが、
std.Build.Dependency.pathメソッドで内部コードのパスをstd.Build.LazyPathとして取得できる。
このパスを起点として、addCSourceFilesメソッドで内部コードのソースをバインディングのソースとして構成できる。

具体的には、

  1. コンソールからzig fetch --save=some_repo 'git+https://github.com/some-user/some-repository'を呼べば、
    build.zig.zonに依存として追加してくれる。

  2. build.zigで依存をstd.Build.Dependencyとして展開する。

const dep = b.dependency("some_repo", .{});
  1. ソースを構成する
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

const mod_core = b.addStaticLibrary(.{
    .name = "some_repo",
    .target = target,
    .optimize = optimize,
});

mod_core.addIncludePath(dep.path("include"));

mod_core.addCSourceFiles(.{
    .root = dep.path("src"),
    .files = &.{
        "file1.c",
        "file2.c",
        // ....
    },
});
  1. 自身のバインディングモジュールから参照するため、内部コードのヘッダファイルをコピーする
mod_core.instalHeader(dep.path("include/some/some.h", "some/some.h");
  1. 自身のバインディングモジュールに内部コードのモジュールをリンクする。
const mod = b.addModule("my_mod", .{
    .root_source_file = b.path("src/root.zig"),
    .target = target,
    .optimize = optimize,
});
mod.addIncludePath(b.pathJoin(b.install_path, "some/some.h"));
mod.linkLibrary(mod_core);