# バッチ設計書 3-rake gensym

## 概要

本ドキュメントは、mrubyプロジェクトのプリシンボル（presym）リストとヘッダーファイルを生成する `rake gensym` タスクの設計仕様を記述する。

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

`rake gensym` は、mrubyのビルド前にシンボルテーブルを事前生成するタスクである。mrubyのシンボル管理を効率化するために、コンパイル前にソースコードをスキャンしてプリシンボル（presym）リストを生成し、対応するCヘッダーファイルを出力する。

**業務上の目的・背景**：mrubyはRubyのシンボル（`:foo` 等）を内部で整数IDとして管理している。ビルド時にシンボルIDを事前に確定させることで、ランタイムでのシンボル登録コストを削減し、組み込み環境でのメモリ効率を向上させる。presym機能は特にメモリが制約された環境において重要である。

**バッチの実行タイミング**：`rake all` の先頭で自動的に実行される。`:all` タスクの依存関係として `:gensym` が指定されており、ビルドの最初のステップとして必ず実行される。

**主要な処理内容**：
1. 全ビルドターゲットのproductsから、オブジェクトファイルの前処理済みファイル（presym preprocessed）を収集する
2. 前処理済みファイルからシンボルをスキャンし、プリシンボルリストを生成する
3. 既存のプリシンボルリストと比較し、変更がある場合のみリストファイルを更新する
4. presym IDヘッダーファイルとpresym テーブルヘッダーファイルを生成する
5. オブジェクトファイルがpresymヘッダーに依存するようRakeの依存関係を設定する

**前後の処理との関連**：`:all` タスク（No.1）の前提タスクとして実行される。生成されたヘッダーファイルは core.rake（No.4）、mrblib.rake（No.5）、mrbgems.rake（No.6）等の全コンパイルタスクで参照される。

**影響範囲**：`build/{target}/include/` ディレクトリにpresymヘッダーファイルが生成される。全ターゲットのコンパイラのインクルードパスに `build/{target}/include` が追加される。

## バッチ種別

コード生成処理（ビルド前処理）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（ビルド時に自動実行） |
| 実行時刻 | 任意 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | `rake all` の依存タスクとして自動実行 / 手動（`rake gensym`） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Ruby実行環境 | Ruby がインストールされていること |
| Cプリプロセッサ | presym preprocessed ファイルを生成するためのCプリプロセッサが利用可能であること |
| ビルド設定ファイル | MRuby.targets が構成済みであること |

### 実行可否判定

各ビルドターゲットの products から presym preprocessed ファイルが特定できること。presym preprocessed ファイルに対応するRakeルールが存在すること。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | パラメータなし。ビルド設定から自動的に入力が決定される |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| *.ppp（presym preprocessed）ファイル | プリプロセス済みCソース | オブジェクトファイルの拡張子をpresym_preprocessed拡張子に変更したファイル |
| build.products | ファイルパス配列 | 各ターゲットの成果物リスト（依存関係の再帰探索元） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| presym.list_path | テキストファイル | プリシンボルの一覧リスト |
| presym.id_header_path | Cヘッダーファイル | シンボルIDの定義（`#define MRB_PRESYM_xxx`） |
| presym.table_header_path | Cヘッダーファイル | シンボルテーブルの定義 |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | ターゲット固有のパス（build/{target}/include/ 配下） |
| 出力先 | `build/{target}/include/` |
| 文字コード | ASCII / UTF-8 |
| 区切り文字 | 該当なし（Cヘッダー形式） |

## 処理フロー

### 処理シーケンス

```
1. インクルードパス設定
   └─ build/{target}/include を全コンパイラのインクルードパスに追加
2. presym preprocessed ファイルの収集
   └─ 全productsの依存関係を再帰的に探索し、オブジェクトファイルを特定
   └─ 各オブジェクトファイルの拡張子をpresym_preprocessed拡張子に変換
   └─ Rakeルールが存在するもののみを収集
3. presymリスト生成
   └─ presym.scan(ppps) でシンボルをスキャン
4. 差分チェック
   └─ 既存リストと比較し、変更がある場合のみ更新
5. ヘッダーファイル生成
   └─ IDヘッダーとテーブルヘッダーを生成（変更がある場合、またはファイルが存在しない場合）
6. 依存関係設定
   └─ 各オブジェクトファイルがpresym.list_pathに依存するよう設定
```

### フローチャート

```mermaid
flowchart TD
    A[rake gensym 開始] --> B[インクルードパス設定]
    B --> C[presym preprocessed ファイル収集]
    C --> D[presym.scan でシンボルスキャン]
    D --> E{既存リストと差分あり?}
    E -->|あり| F[presymリストファイル更新]
    F --> G[IDヘッダー生成]
    G --> H[テーブルヘッダー生成]
    E -->|なし| I{ヘッダーファイル存在?}
    I -->|あり| J[スキップ]
    I -->|なし| G
    H --> K[オブジェクトファイルの依存関係設定]
    J --> K
    K --> L[rake gensym 終了]
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | プリプロセスエラー | presym preprocessed ファイルの生成失敗 | Cプリプロセッサの設定を確認 |
| - | ディレクトリ作成エラー | include ディレクトリの作成失敗 | ファイルシステムの権限を確認 |
| - | ファイル書き込みエラー | ヘッダーファイルの書き込み失敗 | ディスク容量と権限を確認 |

### リトライ仕様

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

### 障害時対応

`rake clean` を実行して全ビルド成果物を削除し、再度 `rake all` を実行する。

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

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

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 全ターゲットのオブジェクトファイル数に比例 |
| 目標処理時間 | 数秒以内（差分がない場合はスキップ） |
| メモリ使用量上限 | 環境依存 |

## 排他制御

同一ビルドディレクトリに対する同時実行は想定されていない。presymリストファイルの同時書き込みが発生する可能性がある。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | presym preprocessed 処理時 | 処理対象ファイル |
| エラーログ | エラー発生時 | プリプロセスエラーメッセージ |

## 監視・アラート

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

## 備考

- presymの差分チェックにより、シンボルリストに変更がない場合はヘッダーファイルの再生成がスキップされる。これにより不要な再コンパイルを防止している。
- `mrbc_build` のオブジェクトファイルはpresymの対象から除外される（`mrbc_build_dir` のチェック）。
- `all_prerequisites` ラムダを使用してRakeタスクの全依存関係を再帰的に収集し、対象となるオブジェクトファイルを網羅的に特定している。
