Menu

Zero パッケージ|zero.json・src/・ターゲットの仕組み

Zero パッケージのレイアウト解説。zero.json マニフェスト、src/ ディレクトリ、そして同じソースツリーから実行ファイル・ライブラリ・テストを生成するターゲットシステムを紹介します。

なぜパッケージか

言語を学んでいたり、スニペットを試したりしているうちは、ひとつの .0 ファイルで十分です。プロジェクトが 1 ファイルを超えた瞬間に欲しくなるのが パッケージ——マニフェストと、ツールチェーンが理解する既知のレイアウトを持つディレクトリです。

ばらばらのファイルからパッケージへ移ることで得られるものは、

  • プロジェクトの名前、バージョン、メタデータをひとつの正規の場所に置ける。
  • 1 つのツリーに複数のエントリーポイント(実行ファイル、ライブラリ、テスト)を置ける。
  • 予測可能なレイアウト——ツールが設定なしにソースを見つけられる。
  • ファイル単位ではなくツリー全体に対する zero check / zero build

パッケージをスキャフォールドする

最速で始める方法は zero new です。

zero new cli hello

これで hello/ ディレクトリが次のように作られます。

hello/
├── zero.json
└── src/
    └── main.0

cli はテンプレート名で、実行可能なコマンドラインプログラムを生成します。他のテンプレート(ライブラリ、システムプログラム)も同じ形で、デフォルトが異なります。

新しいディレクトリに cd して実行すれば、もう動きます。

cd hello
zero run

パッケージディレクトリ内で、ファイル名を指定せずに zero run を実行すると、zero.json のデフォルトターゲットを拾って実行します。

zero.json マニフェスト

スキャフォールドされた cli パッケージのマニフェストはこんな見た目です。

{
    "package": { "name": "hello", "version": "0.1.0" },
    "targets": { "cli": { "kind": "exe", "main": "src/main.0" } }
}

トップレベルのキーは 2 つ: packagetargets。前者がパッケージを識別し、後者がコンパイラーに何をビルドするかを伝えます。

package

"package": {
    "name": "hello",
    "version": "0.1.0"
}
  • name——パッケージを識別するスラッグ。小文字とハイフンを使います。
  • version——semver 文字列。pre-1.0 パッケージは 0.x.y を使います。

その他のメタデータフィールド(description、author、license、repository)がサポートされる場合があります。マニフェストはまだ進化中なので、権威あるスキーマは現行の Zero ドキュメントに従ってください。

targets

"targets": {
    "cli": { "kind": "exe", "main": "src/main.0" }
}

キー(ここでは cli)は自分で選ぶ ターゲット名 です。値が各ターゲットを記述します。

  • kind——ターゲットの種類。実行ファイルなら exe。他の種類(ライブラリ、テスト)も同じ形に従います。
  • main——パッケージルートからの相対パスのエントリーソースファイル。

1 つのパッケージに複数のターゲットを宣言できます。

{
    "package": { "name": "image-tools", "version": "0.1.0" },
    "targets": {
        "convert": { "kind": "exe", "main": "src/convert.0" },
        "resize":  { "kind": "exe", "main": "src/resize.0" },
        "lib":     { "kind": "lib", "main": "src/lib.0" }
    }
}

CLI からターゲット名を指定して特定のターゲットをビルドできます。

zero build convert
zero run resize

src/ ディレクトリ

すべてのソースファイルは src/ 配下に住みます。コンパイラーがこのディレクトリを自動で走査するので、マニフェストにすべてのファイルをリストする必要はありません。各ターゲットの main フィールドがエントリーファイルを指し、コンパイラーはそこから import を辿って必要なものを見つけます。

ヘルパーモジュールがいくつかあるパッケージは、こんな見た目になるかもしれません。

image-tools/
├── zero.json
└── src/
    ├── convert.0
    ├── resize.0
    ├── lib.0
    └── internal/
        ├── decoder.0
        └── encoder.0

internal/ サブディレクトリは単なる慣習です——マニフェストにそれらのファイル名は出てきません。convert.0 内の import は internal/decoder.0 に直接届きます。

ビルドと実行

パッケージ内に入ったあとのよくあるワークフローです。

zero check        # ツリー全体を型検査する
zero run          # デフォルトターゲットをビルドして実行
zero run convert  # 指定したターゲットをビルドして実行
zero build        # デフォルトターゲットをビルド
zero build --all  # すべてのターゲットをビルド(サポートされている場合)
zero test         # すべてのテストターゲットを実行

CLI は zero.json を読み、何をすべきかを把握して進みます。パッケージ内で作業しているなら、パスを綴り出すことはまずありません。

複数のソースファイル: 簡単な例

src/main.0src/math.0 のヘルパーを呼ぶとします。ヘルパーファイル。

pub fun double(value: i32) -> i32 {
    return value * 2
}

エントリーファイル。

pub fun main(world: World) -> Void raises {
    let result = double(21)
    if result == 42 {
        check world.out.write("forty two\n")
    }
}

zero run で実行します。この単純なケースでは、明示的な import 宣言がなくても、コンパイラーがソースツリーの残りに対して double への参照を解決します。パッケージが大きくなると、明示的な import システムがモジュール間の可視性を扱います——import 構文は 1.0 までに動きやすい部分のひとつなので、現行の Zero ドキュメントを参照してください。

git にチェックイン しない もの

Zero パッケージの .gitignore には通常、次が入ります。

# ビルド成果物とキャッシュ
/build/
/target/

# エディタ由来のゴミ
.DS_Store
*.swp

ビルド出力ディレクトリの正確な名前は異なる場合があります——現行のツールチェーンのドキュメントで確認してください——が、ルールは「ソースは入れる、ビルド成果物は入れない」です。

パッケージを共有する

Zero は pre-1.0 で、パッケージレジストリはまだ安定した表面の一部ではありません。今のところ、パッケージを共有する現実的な方法は次の通りです。

  • Git: リポジトリをクローンして zero check を実行する。
  • ベンダリングしたコピー: ソースのコピーを別のプロジェクトに落とす。

レジストリが登場したら、パッケージ参照はおそらく zero.json の dependencies フィールドに移ります。今日のスクリプトに織り込むのではなく、先を見据えた機能として扱ってください。

次回: 言語の基礎

これで実際の Zero プロジェクトを整理するために必要なものはすべて揃いました。続く章では言語そのものにズームインし、let バインディング ——Zero の値に名前を付ける方法——から始めます。

よくある質問

Zero パッケージとは?

Zero パッケージは、zero.json マニフェストと .0 ソースを格納する src/ フォルダーを含むディレクトリです。マニフェストはパッケージの名前、バージョン、そして 1 つ以上の「ターゲット」を宣言します——各ターゲットは、ソースから何(実行ファイル、ライブラリ、テストバイナリ)をどうビルドするかをコンパイラーに伝えます。

新しい Zero パッケージはどう作りますか?

zero new <template> <name> を実行します。例: zero new cli hello。CLI は zero.jsonsrc/main.0、そして選んだテンプレートに必要なファイルを持つディレクトリをスキャフォールドします。そこからパッケージ内で zero checkzero runzero build を実行できます。

zero.json には何を書きますか?

最低限、nameversion を持つ package オブジェクト、そしてパッケージがビルドする各ものを記述する targets オブジェクトです。ターゲットは kind(実行ファイルなら exe など)と、エントリーソースファイルを指す main を持ちます。1 つのマニフェストに複数のターゲットを宣言できます。

1 つの Zero パッケージに複数のターゲットを持てますか?

はい。パッケージは任意の数のターゲットを宣言できます——たとえば CLI 用の exe ターゲット 1 つ、再利用可能なライブラリ用の lib ターゲット 1 つ、1 つ以上のテストターゲット、というように。各ターゲットは src/ 配下に独自のエントリーポイントを持ち、CLI から個別にビルド・実行できます。

コンパイラーはビルド出力をどこに置きますか?

ビルド成果物はパッケージ内のビルドディレクトリに着地します(正確なパスは実装依存で、Zero が pre-1.0 のうちは変更される可能性があります)。src/ 配下のソースツリーは決して変更されません。ビルドディレクトリは使い捨て可能なものとして扱いましょう——git にチェックインするのは悪い考えです。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める