2022-08-02 / syui

zig , cloudflare

zigをwasmにしてcloudflareにdeployする

zigはprogramming-langの一つです。rustに似ていますが、c++寄りだと思います。

zigの利点はなんといってもwasmへのbuildの手軽さだと思います。

wasmはwebから実行できるbinaryです。

今後、webなどでもzigが採用されるケースが増えてくるかもしれません。

$ brew install zig
$ mkdir zig-first-project
$ cd zig-first-project
$ zig init-exe
$ cat src/main.zig
$ cat build.zig
$ zig build
$ ./zig-out/bin/zig-first-project

hello-worldしてみます。

const std = @import("std");

pub fn main() anyerror!void {
    const stdout = std.io.getStdOut().writer();
    try stdout.print("hello, world!\n", .{});
}

ここまででziglang/zig.vimを入れておいたほうがいいでしょう。zigはコード内にある\tの扱いが特殊です。

Plug 'ziglang/zig.vim'

以下はcloudflare blogにあるexampleです。

const std = @import("std");

pub fn main() anyerror!void {
    // setup allocator
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer std.debug.assert(!gpa.deinit());
    const allocator = gpa.allocator();

    // setup streams
    const stdout = std.io.getStdOut().writer();
    const in = std.io.getStdIn();
    var reader = std.io.bufferedReader(in.reader()).reader();

    var counter: u32 = 1;

    // read input line by line
    while (try reader.readUntilDelimiterOrEofAlloc(allocator, '\n', std.math.maxInt(usize))) |line| {
        defer allocator.free(line);
        try stdout.print("{d}\t{s}\n", .{counter, line});
        counter = counter + 1;
    }
}

単純に文字を渡すと行番号を追加して返します。

just read some text from stdin and print it to stdout with line numbers, like running cat -n. But it does show just how easy the Workers paradigm is. This Zig program works identically on the command-line on my laptop and as an HTTP API deployed on Cloudflare Workers.

const std = @import("std");

pub fn build(b: *std.build.Builder) void {
    const target = b.standardTargetOptions(.{});
    const mode = b.standardReleaseOptions();
    const exe = b.addExecutable("zig-first-project", "src/main.zig");
    exe.setTarget(target);
    exe.setBuildMode(mode);
    exe.install();
}

cloudflare workersではwasiがsupportされています。wasm-build, workers-deployまでをやってみます。

$ zig build -Dtarget=wasm32-wasi
$ ls zig-out/bin/*.wasm
$ echo "Hello\nWorld" | wasmtime ./zig-out/bin/zig-first-project.wasm
1       Hello
2       World

$ npx wrangler@wasm login
$ npx wrangler@wasm publish --name print-with-line-numbers --compatibility-date=2022-07-07  ./zig-out/bin/zig-first-project.wasm

これでdeployは完了です。取得されたworkersのaddressに文字列をpostしてみましょう。wasm-binaryが実行され、反応を返します。

$ echo "hello\nworld" | curl https://print-with-line-numbers.$USER.workers.dev -X POST --data-binary @-
1       hello
2       world

このようにめちゃくちゃ便利なcloudflare workersですが、cloudflareが提供するworkers.devのidは開発者なら取っておいたほうがよさそうです。