インストール
Gomamochi は今のところリポジトリの中にあります。
インストールする配布物はなく、手元の go.mod に足すものもありません。
チェックアウトを取ってくれば、あとは ./bin/gomamochi だけで足ります。
必要なもの
- Apple silicon の macOS、または Linux。 エンジンはプラットフォーム自身の GPU の仕組みで描きます。 macOS では Metal、Linux では Vulkan で、ウィンドウは Wayland か X11 に開きます。
- Go 1.25 以降。
コマンド自身を一度ビルドするのに使います。
buildとgateがアプリをコンパイルするのも Go です。 コマンドがビルドできていれば、runに Go のツールチェーンは要りません。 インタプリタはコマンドの中にあります。 - Rust(rustup から)。 コンパイラのバージョンはリポジトリが固定していて、最初のビルドで取ってきます。
- macOS では Xcode の Metal ツールチェーン。 エンジンがビルド時にシェーダをコンパイルするからです。 Linux では C コンパイラと、エンジンがリンクするライブラリの開発パッケージが要ります。 alsa、fontconfig、freetype、xkbcommon(x11 の分も)、xcb、そして Vulkan のローダとドライバです。
インタプリタの yaegi と、cgo なしで Go からエンジンのライブラリを開く purego は、どちらも Go のモジュールです。
コマンドを最初にビルドするときに go が取ってきます。
ほかに要るものはありません。
マシンごとに一度
CARGO_TARGET_DIR は、チェックアウトの中のすべてのクレートが共有します。
二度目以降のビルドが速いのはこれのおかげです。
シェルの設定に書いて、あとは忘れてかまいません。
ほかに黙って取ってくるものはありません。
エンジンは同じチェックアウトの中のクレートで、最初にどれかのコマンドを実行したときに cargo がビルドします。
どのコマンドも先にエンジンをビルドするので、二つの実行のどちらかが古いままになることはありません。
コマンドは Go のプログラムで、bin/gomamochi がそれを ~/.cache/gomamochi/bin/ にビルドして実行します。
コマンド
gomamochi/ から実行します。
$ ./bin/gomamochi run demo/counter.go # ウィンドウが開く。保存で読み直す
$ ./bin/gomamochi check demo/counter.go # 受け取れない書き方
$ ./bin/gomamochi gate demo/counter.go --script "click:+1,dump"
$ ./bin/gomamochi build demo/counter.go --release --app # バイナリと、バンドル
translate はありません。
翻訳するものがないからです。
コンパイルした実行は、書いたファイルをそのまま Go のコンパイラに通したものです。
run はウィンドウを開き、ファイルを見ています。
保存すればその場で効き、アプリの持っていた値も残ります。
check は何もビルドしません。
肝心なのは gate です。
二つの実行を一つのスクリプトで動かし、1 バイトずつ突き合わせます。
build には四つのフラグがあります。
--release は symbol table を落とします。
--app はバイナリとエンジンのライブラリをアプリケーションとして包みます。
macOS では dist/ の下のバンドルになります。
ダブルクリックで開き、アプリの横に <stem>.icns か <stem>.png があれば、それがアイコンになります。
Linux では dist/ の下の AppDir になり、--appimage がそれを一つのファイルに詰めます。
--carry-libs を付けると、エンジンがリンクするデスクトップのライブラリまで Linux のパッケージに入ります。
それらが入っていないかもしれないマシンのためです。
gate には --fresh <path> があり、実行のたびにその場所を消します。
ファイルやデータベースを持つアプリを、二つの実行とも同じ「何もない」状態から始めるためです。
最初のファイル
package main
import (
"fmt"
. "github.com/i2y/yokan/gomamochi"
)
type Counter struct {
count int
}
func (c *Counter) View() Element {
return Column(
Text(fmt.Sprintf("count: %d", c.count)).Size(34),
Button("+1").OnClick(func() { c.count += 1 }),
).Spacing(12).Padding(16)
}
func main() {
Run(&Counter{}, Title("counter"))
}
そのウィンドウを開いたまま編集して保存してみてください。 新しいインタプリタがファイルを読み直し、ウィンドウの持っている構造体は、値をすべて保ったまま新しいコードで動きます。
ビルドすると何ができるか
macOS/arm64 で、エンジンをビルドし終え、キャッシュが温まった状態で測っています。
| もの | 値 |
|---|---|
gate がビルドするバイナリ |
2.9 MB |
配るバイナリ(--release) |
1.9 MB |
| その横に置くエンジンのライブラリ | 20.4 MB |
両方を入れたアプリケーションバンドル(--app) |
22.2 MB |
bin/gomamochi 経由の check |
0.6 秒。検査そのものは 0.1 秒ほどで、残りは、コマンドが最新かどうかを go build が確かめる時間 |
PIXIE_SCRIPT でのウィンドウなしの実行 |
1.0 秒 |
| ゲート 1 回 | 約 2 秒 |
| 全部を 1 回通す(デモ 44 本、断り、二つのツアー、サイト) | 約 3 分 |
バイナリは Go のコンパイラが作ったもので、cgo は使いません。 リンクするのはシステム自身のライブラリだけです。 エンジンは一つの共有ライブラリとして、その横に置かれます。 受け取る人に、Go もツールチェーンも要りません。
全体が動いているかを確かめる
要素の表から生成したコード、Go 自身の vet、断りの文面を置いてあるファイル、すべてのデモの両方の実行、そしてツアーの完全な例を、すべて確かめます。
要素の表、エンジンを開くパッケージ、エンジン自身に手を入れたときに通すものです。
手元の用意が揃っているかを確かめる、いちばん速い方法でもあります。