# 通知設計書 6-MissingLibraryError

## 概要

本ドキュメントは、Zigコンパイラにおけるライブラリ不足エラー（MissingLibraryError）通知の設計を記述するものである。

### 本通知の処理概要

本通知は、Zigコンパイラのリンク処理中に必要なライブラリが見つからない場合に発生するエラーを報告する機能である。

**業務上の目的・背景**：リンク処理において必要なシステムライブラリや外部ライブラリが見つからない場合、ユーザーに対してエラーの原因と検索されたパスを明確に伝達するために必要である。ライブラリ不足は一般的なリンクエラーの原因であり、適切なエラーメッセージが問題解決を支援する。

**通知の送信タイミング**：リンク処理中にライブラリ検索が失敗した時点でDiagsシステムにエラーが追加される。

**通知の受信者**：コンパイラを実行しているユーザー。エラーメッセージは最終的に標準エラー出力（stderr）に出力される。

**通知内容の概要**：エラーメッセージ（どのライブラリが見つからなかったか）と、検索されたパスのリスト（ノートとして）が含まれる。

**期待されるアクション**：ユーザーはエラーメッセージと検索パスを確認し、必要なライブラリのインストール、ライブラリパスの設定、またはリンカーオプションの修正を行う。

## 通知種別

診断メッセージ（ErrorBundle経由での出力）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（エラー蓄積後にバッチ出力） |
| 優先度 | 高 |
| リトライ | 無し |

### 送信先決定ロジック

エラーメッセージは`link.Diags`構造体に蓄積され、検索パス情報がノートとして添付される。最終的に`Compilation.getAllErrorsAlloc()`によってErrorBundleに変換されて出力される。

## 通知テンプレート

### エラー出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | stderr（ErrorBundle経由） |
| 形式 | 構造化エラーメッセージ |

### 本文テンプレート

```
error: {エラーメッセージ}
note: tried {検索パス1}
note: tried {検索パス2}
...
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 診断メッセージのため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| msg | エラーメッセージ | format引数で生成 | Yes |
| checked_paths | 検索されたパスのリスト | 呼び出し元から渡される | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| リンク処理 | Diags.addMissingLibraryError呼び出し | ライブラリ未検出時 | システムライブラリ等の検索失敗 |
| MachOリンク | libSystem検索失敗 | macOS/iOS等でlibSystem未検出時 | Darwin系OSでのシステムライブラリ |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| なし | ライブラリ未検出時は常にDiagsに追加される |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ライブラリ検索開始] --> B{ライブラリ発見?}
    B -->|Yes| C[処理継続]
    B -->|No| D[addMissingLibraryError呼び出し]
    D --> E[メッセージフォーマット]
    E --> F[検索パスをノートとして追加]
    F --> G[Diags.msgsに追加]
    G --> H[呼び出し元に戻る]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | 診断メッセージのためDB参照なし |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | 診断メッセージのためDB更新なし |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| OutOfMemory | メッセージ/ノート生成時のメモリ不足 | setAllocFailureLocked()で記録 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（リンク処理中は常時発生可能）

## セキュリティ考慮事項

- エラーメッセージに検索パス（ファイルシステムパス）が含まれるが、これはユーザーの作業環境情報であり、外部送信されない
- エラー出力は標準エラー出力のみで、ネットワーク経由での送信は行われない

## 備考

- 検索パスはノートとして1つずつ出力され、ユーザーがどのパスを確認したか把握できる
- Diagsシステムはスレッドセーフであり、mutexで保護されている

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

Diags.Msg構造体のnotes機能を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | link.zig | `src/link.zig` | 76-80行目: Msg構造体（notes含む） |

**読解のコツ**: Msg構造体は`notes`フィールドを持ち、これは追加情報を格納するためのMsg配列へのスライスである。

#### Step 2: エントリーポイントを理解する

addMissingLibraryError関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | link.zig | `src/link.zig` | 277-292行目: addMissingLibraryError関数 |
| 2-2 | link.zig | `src/link.zig` | 294-312行目: addMissingLibraryErrorLockedFallible関数 |

**主要処理フロー**:
1. **286行目**: `eu_main_msg = std.fmt.allocPrint(gpa, format, args);` - メインメッセージの生成
2. **303行目**: `notes = try gpa.alloc(Msg, checked_paths.len);` - ノート用メモリ確保
3. **305-307行目**: 各検索パスをノートとしてフォーマット
4. **308-311行目**: メッセージとノートをDiagsに追加

#### Step 3: 使用箇所

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | link/MachO.zig | `src/link/MachO.zig` | 857行目: libSystem検索失敗時の呼び出し |

**主要処理フロー**:
- **857行目**: `diags.addMissingLibraryError(checked_paths.items, "unable to find libSystem system library", .{});`

### プログラム呼び出し階層図

```
link.Diags.addMissingLibraryError(checked_paths, format, args)
    │
    ├─ std.fmt.allocPrint(gpa, format, args)
    │      └─ メインエラーメッセージ生成
    │
    ├─ diags.mutex.lockUncancelable(io)
    │      └─ スレッドセーフのためのロック
    │
    └─ addMissingLibraryErrorLockedFallible(diags, checked_paths, eu_main_msg)
           │
           ├─ gpa.alloc(Msg, checked_paths.len)
           │      └─ ノート用メモリ確保
           │
           ├─ for (checked_paths, notes) |path, *note|
           │      └─ "tried {path}" フォーマットでノート生成
           │
           └─ diags.msgs.appendAssumeCapacity(.{.msg, .notes})
                  └─ メッセージとノートをDiagsに追加
```

### データフロー図

```
[入力]               [処理]                    [出力]

ライブラリ名 ───▶ addMissingLibraryError() ───▶ Diags.msgs
検索パス一覧            │
                       ├─ メインメッセージ生成
                       └─ 各パスをノートとして追加

                         │
                         ▼

             Compilation.getAllErrorsAlloc()
                         │
                         ▼

                 ErrorBundle（stderr出力）
                 error: unable to find library XXX
                 note: tried /path/1
                 note: tried /path/2
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| link.zig | `src/link.zig` | ソース | addMissingLibraryError関数の定義 |
| link/MachO.zig | `src/link/MachO.zig` | ソース | Darwin系OSでのlibSystem検索 |
| Compilation.zig | `src/Compilation.zig` | ソース | getAllErrorsAlloc、ErrorBundle生成 |
