# バッチ設計書 6-mrbgems.rake

## 概要

本ドキュメントは、mrbgemsの初期化コード（`gem_init.c`）とLEGALファイルを生成するRakeタスク定義ファイル `tasks/mrbgems.rake` の設計仕様を記述する。

### 本バッチの処理概要

`mrbgems.rake` は、有効な全gemの初期化関数（init/final）を集約した `gem_init.c` を自動生成し、ライセンス情報を集約した `LEGAL` ファイルを生成するタスクを定義する。また、有効なgemsのテキストファイル（`active_gems.txt`）を生成する `:generate_active_gems_txt` タスクも定義する。

**業務上の目的・背景**：mrubyのgem（mrbgems）システムでは、各gemが独自のinit/final関数を持つ。mrubyの起動時にこれらの関数を順番に呼び出す必要があるが、有効なgemの組み合わせはビルド設定により動的に変わる。そのため、ビルド時に有効なgemの一覧から自動的に初期化コードを生成する仕組みが必要である。また、各gemのライセンス情報を集約したLEGALファイルも法的コンプライアンスのために必要である。

**バッチの実行タイミング**：`rake build` の依存関係解決時に、`gem_init.o` のビルド要求を通じて自動実行される。`enable_gems?` が true のターゲットでのみ実行される。

**主要な処理内容**：
1. `gems.setup_build` と `gems.check` でgemの設定と検証を行う
2. `gem_init.c` を自動生成し、全gemのinit/final関数の宣言と呼び出しコードを含める
3. `mrb_init_mrbgems` 関数を生成し、全gemの初期化を順次実行するコードを出力する
4. `mrb_final_mrbgems` 関数を生成し、全gemのファイナライズを逆順で実行するコードを出力する
5. `LEGAL` ファイルを生成し、mrubyのMITライセンスと全gemのライセンス情報を集約する
6. `active_gems.txt` を生成し、有効なgem名の一覧を出力する

**前後の処理との関連**：`:generate_active_gems_txt`（No.7）が `active_gems.txt` の依存タスクとして定義される。生成された `gem_init.o` は libmruby.rake（No.8）で `libmruby.a` に結合される。

**影響範囲**：`build/{target}/mrbgems/` ディレクトリに `gem_init.c`、`active_gems.txt` が生成される。`build/{target}/` に `LEGAL` ファイルが生成される。

## バッチ種別

コード生成処理（gem初期化コード自動生成 + ライセンス集約）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（ビルド時に自動実行） |
| 実行時刻 | 任意 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | Rakeの依存関係解決により自動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| enable_gems? | ターゲットでgemsが有効であること |
| active_gems.txt | `:generate_active_gems_txt` タスクにより生成済みであること |
| MRUBY_CONFIG | ビルド設定ファイルが正常にロードされていること |

### 実行可否判定

`enable_gems?` が true のターゲットでのみ `gem_init.c` と `LEGAL` の生成が実行される。`active_gems.txt` が更新された場合、または `MRUBY_CONFIG` が変更された場合に再生成される。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | ビルド設定のgems構成から自動決定 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| gems（ビルド設定） | Ruby オブジェクト | 有効なgemの一覧とメタデータ |
| active_gems.txt | テキストファイル | 有効なgem名一覧 |
| MRUBY_CONFIG | Ruby スクリプト | ビルド設定ファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| build/{target}/mrbgems/gem_init.c | Cソースファイル | 全gemのinit/final関数を集約した初期化コード |
| build/{target}/mrbgems/gem_init.o | オブジェクトファイル | gem_init.cをコンパイルしたオブジェクト |
| build/{target}/LEGAL | テキストファイル | mrubyと全gemのライセンス情報 |
| build/{target}/mrbgems/active_gems.txt | テキストファイル | 有効なgem名一覧 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | gem_init.c / LEGAL / active_gems.txt |
| 出力先 | `build/{target}/mrbgems/` および `build/{target}/` |
| 文字コード | UTF-8 |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. gemセットアップ
   └─ gems.setup_build, gems.check でgemの検証
2. gem_init.c 生成
   └─ generate_functions が有効な全gemを抽出
   └─ 各gemの GENERATED_TMP_mrb_{funcname}_gem_init/final 関数を宣言
   └─ gem_funcs 配列に init/final 関数ポインタを登録
   └─ mrb_init_mrbgems 関数で全gem init を順次呼び出し
   └─ mrb_final_mrbgems 関数で全gem final を逆順で呼び出し
   └─ mrb_state_atexit に mrb_final_mrbgems を登録
3. gem_init.c コンパイル
   └─ gem_init.c → gem_init.o
4. LEGAL ファイル生成
   └─ MITライセンス本文を出力
   └─ 各gemの名前、著作者、ライセンスを出力
5. libmruby_objs への登録
   └─ self.libmruby_objs << objfile("#{build_dir}/mrbgems/gem_init")
```

### フローチャート

```mermaid
flowchart TD
    A[mrbgems.rake 処理開始] --> B{enable_gems?}
    B -->|いいえ| C[スキップ]
    B -->|はい| D[gems.setup_build / gems.check]
    D --> E[generate_functions が有効なgemを抽出]
    E --> F[gem_init.c 生成]
    F --> G[init/final 関数宣言を出力]
    G --> H[mrb_init_mrbgems 関数を生成]
    H --> I[mrb_final_mrbgems 関数を生成]
    I --> J[gem_init.c をコンパイル]
    J --> K[LEGAL ファイル生成]
    K --> L[libmruby_objs に追加]
    L --> M[mrbgems.rake 処理終了]
    C --> M
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチではデータベース操作は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | gem検証エラー | gems.check でgemの整合性エラーを検出 | ビルド設定のgem指定を確認 |
| - | コンパイルエラー | gem_init.c のコンパイル失敗 | 自動生成コードの内容を確認 |
| - | ファイル書き込みエラー | 出力ディレクトリの権限不足等 | ファイルシステムの権限を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

gem設定のエラーの場合はビルド設定ファイルを修正する。`rake clean` 後に再ビルドする。

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 有効なgemの数に比例 |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 環境依存 |

## 排他制御

同一ビルドターゲットに対する同時実行は想定されていない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | gem_init.c 生成時 | 生成対象のgem一覧 |
| エラーログ | エラー発生時 | gem検証エラーまたはコンパイラエラー |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | CI/CDパイプラインの通知設定に依存 |

## 備考

- `gem_init.c` には自動生成コメントが含まれ、手動変更は失われる旨が記載される。
- `mrb_init_mrbgems` ではGCアリーナの保存/復元が各gem初期化の前後で行われる（`mrb_gc_arena_save`/`mrb_gc_arena_restore`）。
- gem初期化中にエラーが発生した場合は `mrb_exc_raise` で例外が発生する。
- `mrb_final_mrbgems` は `mrb_protect_error` でラップされており、ファイナライズ中のエラーが他のgemのファイナライズを妨げないようになっている。
- `mrb_state_atexit` に `mrb_final_mrbgems` が登録され、mrubyのステート破棄時に自動的に呼び出される。
- LEGALファイルはMITライセンスをベースとし、各gemのライセンス情報が追加される。
