1
0
hugo/content/blog/2022-08-02-zig.md
2024-04-23 22:21:26 +09:00

111 lines
3.4 KiB
Markdown

+++
date = "2022-08-02"
tags = ["zig","cloudflare"]
title = "zigをwasmにしてcloudflareにdeployする"
slug = "zig-wasm-cloudflare"
+++
`zig`はprogramming-langの一つです。rustに似ていますが、c++寄りだと思います。
zigの利点はなんといってもwasmへのbuildの手軽さだと思います。
wasmはwebから実行できるbinaryです。
今後、webなどでもzigが採用されるケースが増えてくるかもしれません。
```sh
$ 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してみます。
```zig:src/main.zig
const std = @import("std");
pub fn main() anyerror!void {
const stdout = std.io.getStdOut().writer();
try stdout.print("hello, world!\n", .{});
}
```
ここまでで[ziglang/zig.vim](https://github.com/ziglang/zig.vim)を入れておいたほうがいいでしょう。zigはコード内にある`\t`の扱いが特殊です。
```vim
Plug 'ziglang/zig.vim'
```
以下はcloudflare [blog](https://blog.cloudflare.com/running-zig-with-wasi-on-cloudflare-workers/)にあるexampleです。
```zig:src/main.zig
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.
```zig:build.zig
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までをやってみます。
```sh
$ 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が実行され、反応を返します。
```sh
$ 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は開発者なら取っておいたほうがよさそうです。