🚀

Zigでライブラリを利用(git submodules)

2024/04/02に公開

Zigにはまだパッケージマネジャーやパッケージレジストリーのようなものは確立されていないため、ネット上で公開されているZigライブラリを利用するには、手動でインストール・指定する必要があります。そのためのやり方をご紹介します。

準備

まず、ナイトリービルド(nightly build、masterブランチの最新ビルドバージョン)を使います。Windows以外のやり方は、ここでは紹介しませんが、masterブランチを使うことをおすすめします。以下の公式記事をご覧ください。
https://ziglang.org/learn/getting-started/#direct-download

WindowsでZigをインストール

# Scoopをインストール
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression

# Zigをインストール
scoop bucket add versions
scoop install versions/zig-dev

開発環境整備

言語サーバーのインストール

ライブラリのインポートの静的分析をサポートさせるには、NightlyビルドのZLS(Zig Language Server)をインストールする必要があります。ここからPrebuiltの最新版をダウンロードして、PATHに入れます。

https://github.com/zigtools/zls/wiki/Installation

エディターの設定

VSCodeやNeoVimなどお好きなエディターに、ZLSやZigを指定します。ここではVSCodeのやり方を紹介します。

  1. VSCodeを入れます。
  2. ziglang.vscode-zigという拡張機能をインストールします(Ctrl+Shift+P、Install Extention)。
    3.出てきた確認窓でPATHにあるものZigやZLSを設定します。(すでにExtensionをインストールしてしまった場合は、zig.pathzig.zls.pathを空に設定したり、指定したりする)。

プロジェクトの用意

以下のコマンドを実行してプロジェクトを設定して、VSCodeで開きます。

mkdir zig-library-example
cd zig-library-example
zig init
code .

すると、自動的にファイルが生成され以下のようなフォルダー構造になります。

.
├── build.zig
├── build.zig.zon
└── src
    ├── main.zig
    └── root.zig

以下のコマンドを実行すると、以下のような表示が出てくるはずです。

zig build run
All your codebase are belong to us.   
Run `zig build test` to run the tests.

ライブラリの利用

今回はアイヌ語キーボード開発に必要なWindowsAPIのラッパーであるzigwin32を利用したいため、gitのサブモジュールでそのライブラリを持ってきます。

Gitリポジトリの初期化

まず、gitリポジトリを初期化する必要があります。

# .gitignoreに`zig-cache/`と`zig-build`を追加して無視させる
echo "zig-cache/`nzig-build/" > .gitignore
git init
git add .
git commit -m "Initial commit"

サブモジュールの追加

それから、submoduleを追加します。ダウンロードは少し時間がかかります。

git submodule add https://github.com/marlersoft/zigwin32.git lib/zigwin32

できたら、以下のようにlibフォルダーの下にzigwin32がクローンされます。

.
├── build.zig
├── build.zig.zon
├── lib
│   └── zigwin32
│       ├── LICENSE
│       ├── README.md
│       ├── build.zig
│       ├── win32
│       └── win32.zig
└── src
    ├── main.zig
    └── root.zig

パッケージのインストール

簡単のため、src/root.zigを消し、build.zigを開き、不要なLIBを生成するため部分やコメント、テストコードなどを消し、モジュールをロードする指定を追加します。変更したものはこうなります。

build.zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    // モジュールを指定
    const win32 = b.addModule("win32", .{ .root_source_file = .{ .path = "lib/zigwin32/win32.zig" } });
    const exe = b.addExecutable(.{
        .name = "zig-library-example",
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,
    });
    // モジュールをインポートできるように
    exe.root_module.addImport("win32", win32);
    b.installArtifact(exe);

    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());
    if (b.args) |args| {
        run_cmd.addArgs(args);
    }
    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}

ライブラリを使う

今回はWindows APIを利用して、メッセージダイアログを出してみます。以上のようにbuild.zigwin32を指定すれば、@import("win32")を使うことで、インストールされたライブラリを利用することができるようになります。

src/main.zig
const std = @import("std");
const unicode = std.unicode;

const win32 = @import("win32");
const MessageBoxW = win32.ui.windows_and_messaging.MessageBoxW;
const MB_OK = win32.ui.windows_and_messaging.MB_OK;

pub fn main() !void {
    const text = unicode.utf8ToUtf16LeStringLiteral("こんにちは、Zenn❣");
    const caption = unicode.utf8ToUtf16LeStringLiteral("Zigアプリ");
    _ = MessageBoxW(null, text, caption, MB_OK);
}

以下のコマンドを実行すると、以下のようにメッセージボックスが正しくできました。コードのハイライトや型ヒントなども正しく表記されていますね🎉!

zig build run

まとめ

いかがだったでしょうか?ライブラリを実際に使ってみました。

Discussion