Zig Tips
思いついたスニペットなどのメモ置き場
バッファリングしながら標準入力から読み込む
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
を使わなければならない。
名前付きプレースホルダで文字列整形
std.debug.print("{[a]s:_>[width]}", .{.s = "foo", .width = 10});
出力結果:
_______foo
説明
プレースホルダの中の[]
は指定した名前のパラメータで置換できる。
上の例では、s
の前の[]
は最終出力する値、^
の後の[]
は成形される幅
See also:
Zig以外の言語で提供されるライブラリのバインディングを作る
例えば内部コードがC/C++
で記述されてており、それがgithub
でホスティングされている場合、
submodule
で自身のバインディングのレポジトリに取り込むことが真っ先に思い浮かぶ。
しかし、zig
のパッケージ管理はパッケージのサブモジュールまで面倒見ない。
そのためzig fetch
で持ってきても、自身でサブモジュールの更新を行う必要がある。
それよりも楽な方法として、内部コードのレポジトリをzig
の依存として取り込む方法がある。
内部コードはzig
のモジュールではないためモジュールとして構成はできないが、
std.Build.Dependency.path
メソッドで内部コードのパスをstd.Build.LazyPath
として取得できる。
このパスを起点として、addCSourceFiles
メソッドで内部コードのソースをバインディングのソースとして構成できる。
具体的には、
-
コンソールから
zig fetch --save=some_repo 'git+https://github.com/some-user/some-repository'
を呼べば、
build.zig.zon
に依存として追加してくれる。 -
build.zig
で依存をstd.Build.Dependency
として展開する。
const dep = b.dependency("some_repo", .{});
- ソースを構成する
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",
// ....
},
});
- 自身のバインディングモジュールから参照するため、内部コードのヘッダファイルをコピーする
mod_core.instalHeader(dep.path("include/some/some.h", "some/some.h");
- 自身のバインディングモジュールに内部コードのモジュールをリンクする。
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);