# 通知設計書 110-hintLinking

## 概要

本ドキュメントは、Nimコンパイラの`hintLinking`ヒント通知に関する設計を定義する。このヒントは、リンカ実行を通知するものである。

### 本通知の処理概要

`hintLinking`ヒントは、Nimコンパイラがリンカを実行してオブジェクトファイルを最終的な実行ファイルやライブラリにリンクする際に出力される通知である。

**業務上の目的・背景**：Nimコンパイラはコンパイルプロセスの最終段階で、Cコンパイラをリンカとして呼び出し、生成されたオブジェクトファイルを結合して実行ファイルを生成する。この通知により、開発者はリンカコマンドを確認でき、リンクエラーの診断やビルドプロセスのデバッグに役立てることができる。

**通知の送信タイミング**：リンカコマンドを実行する直前に送信される。具体的には`execLinkCmd`関数から`execExternalProgram`関数を経由して出力される。

**通知の受信者**：コンパイル実行者（開発者）がコンソール出力（stderr）を通じてこの通知を受信する。

**通知内容の概要**：デフォルトでは空文字列が出力される。`--listCmd`オプションまたは`verbosity > 1`の場合のみ、リンカコマンド全体が表示される。

**期待されるアクション**：開発者はこの通知を確認し、リンカコマンドが期待通りかどうか検証する。リンクエラーが発生した場合、表示されたコマンドを参考に問題を診断できる。

## 通知種別

コンソール出力（コンパイラヒント）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（コンパイルプロセス内で即時出力） |
| 優先度 | 低（ヒント情報） |
| リトライ | 無し |

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

標準エラー出力（stderr）に送信される。`--stdout`オプションが指定されている場合は標準出力（stdout）に送信される。`writelnHook`が設定されている場合は、そのフック関数に委譲される。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| メッセージ種別 | Hint |
| フォーマット | `Hint: [Link]`（デフォルト）または `Hint: {リンカコマンド} [Link]`（verbose時） |
| 色 | 緑色（HintColor = fgGreen） |

### 本文テンプレート

デフォルト（verbosity <= 1かつlistCmdなし）：
```
Hint:  [Link]
```

verbose時（verbosity > 1またはlistCmd）：
```
Hint: gcc -o output main.c.o lib.c.o -lm [Link]
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| $1 | リンカコマンド（またはverbosity条件で空文字列） | execWithEchoの条件分岐 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コンパイル処理 | リンカ実行 | デフォルト | execLinkCmd関数呼び出し時 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| optHints not in conf.options | ヒント出力自体が無効化されている場合 |
| hintLinking not in conf.notes | 個別にヒントが無効 |
| verbosity = 0 | NotesVerbosity[0]から除外 |

### メッセージ内容の条件

| 条件 | 出力内容 |
|-----|------|
| hintLinkingかつlistCmdなしかつverbosity <= 1 | 空文字列 |
| hintLinkingかつ(listCmdありまたはverbosity > 1) | リンカコマンド全体 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[callCCompiler] --> B[execLinkCmd]
    B --> C[execExternalProgram conf, linkCmd, hintLinking]
    C --> D[execWithEcho conf, cmd, hintLinking]
    D --> E{msg == hintLinking?}
    E -->|Yes| F{listCmd or verbosity > 1?}
    F -->|Yes| G[rawMessage hintLinking, cmd]
    F -->|No| H[rawMessage hintLinking, 空文字列]
    E -->|No| I[rawMessage msg, cmd]
    G --> J[liMessage処理]
    H --> J
    J --> K{hintLinking有効?}
    K -->|No| L[出力スキップ]
    K -->|Yes| M[styledMsgWriteln]
    M --> N[execCmd linkCmd]
    L --> N
    N --> O{終了コード確認}
    O -->|成功| P[次の処理へ]
    O -->|失敗| Q[エラー処理: errGenerated]
```

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

該当なし（ファイルシステムやデータベースへのアクセスなし）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 該当なし | このヒントは情報出力のみ | - |
| リンカ失敗 | execCmd != 0 | errGenerated出力 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限なし | リンカ実行ごとに出力（通常1回） |

### 配信時間帯

制限なし（コンパイル実行時に即時出力）

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

- リンカコマンドがログに出力される可能性があるため、パスやライブラリ情報が露出する可能性
- CI/CDログに出力される場合、システム構成情報が漏洩する可能性に注意
- デフォルトでは空文字列が出力されるため、通常は情報漏洩リスクは低い

## 備考

- verbosity 1以上で出力される（NotesVerbosity[0]から除外）
- `--hint:Link:on`オプションで明示的に有効化可能
- デフォルトではリンカコマンド詳細は非表示（空文字列）
- `--listCmd`オプションまたは`verbosity > 1`でコマンド詳細を表示
- hintExecuting（No.109）との違い：hintLinkingはリンカ専用で、デフォルトでコマンド詳細が非表示

---

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

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

### 推奨読解順序

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

通知種別の定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lineinfos.nim | `compiler/lineinfos.nim` | TMsgKind列挙型でhintLinkingの定義を確認（111行目） |
| 1-2 | lineinfos.nim | `compiler/lineinfos.nim` | MsgKindToStr配列でメッセージ文字列を確認（233行目） |
| 1-3 | lineinfos.nim | `compiler/lineinfos.nim` | NotesVerbosity[0]からhintLinkingが除外されていることを確認（271行目） |

**読解のコツ**: hintLinkingは"Link"という短縮名を持ち、出力時には[Link]として表示される。

#### Step 2: リンカ実行処理を理解する

リンカ実行の核心部分を特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | extccomp.nim | `compiler/extccomp.nim` | execWithEcho関数（430-432行目）でhintLinking専用の条件分岐を確認 |
| 2-2 | extccomp.nim | `compiler/extccomp.nim` | execExternalProgram関数（434-437行目）で外部プログラム実行を確認 |
| 2-3 | extccomp.nim | `compiler/extccomp.nim` | execLinkCmd関数（873-875行目）でリンカ実行を確認 |

**主要処理フロー**:
1. **873行目**: `execLinkCmd`関数定義
2. **874行目**: `tryExceptOSErrorMessage`でエラーハンドリング
3. **875行目**: `execExternalProgram(conf, linkCmd, hintLinking)`でリンカ実行
4. **430-432行目**: `execWithEcho`で`msg == hintLinking`の場合の特別処理

**430-432行目の条件分岐詳細**:
```nim
proc execWithEcho(conf: ConfigRef; cmd: string, msg = hintExecuting): int =
  rawMessage(conf, msg, if msg == hintLinking and not(optListCmd in conf.globalOptions or conf.verbosity > 1): "" else: cmd)
  result = execCmd(cmd)
```
- `msg == hintLinking`の場合のみ特別な処理
- `optListCmd in conf.globalOptions`または`conf.verbosity > 1`でない場合は空文字列を出力
- それ以外の場合は実際のコマンドを出力

#### Step 3: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | extccomp.nim | `compiler/extccomp.nim` | callCCompiler関数でexecLinkCmdの呼び出し箇所を確認 |

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

```
callCCompiler (extccomp.nim)
    │
    ├─ execCmdsInParallel (コンパイル処理)
    │      └─ execWithEcho(hintExecuting)
    │
    └─ execLinkCmd (873行目)
           │
           └─ execExternalProgram(conf, linkCmd, hintLinking) (875行目)
                  │
                  └─ execWithEcho(conf, cmd, hintLinking) (430行目)
                         │
                         ├─ msg == hintLinking? → 条件分岐
                         │      │
                         │      ├─ listCmd or verbosity > 1
                         │      │      └─ rawMessage(hintLinking, cmd)
                         │      │
                         │      └─ else
                         │             └─ rawMessage(hintLinking, "")
                         │
                         └─ execCmd(cmd)
```

### データフロー図

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

リンカコマンド   ───▶ execLinkCmd           ───▶ リンカ実行要求
                       │
                       ▼
                  execExternalProgram
                       │
                       ▼
                  execWithEcho(hintLinking)
                       │
                       ├─ listCmd or verbose?
                       │      │
                       │      ├─ Yes ───▶ rawMessage(cmd) ───▶ stderr "Hint: {cmd}"
                       │      │
                       │      └─ No ────▶ rawMessage("")  ───▶ stderr "Hint:  [Link]"
                       │
                       ▼
                  execCmd                  ───▶ リンカ実行
                       │
                       ▼
                  終了コード               ───▶ 成功/失敗判定
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lineinfos.nim | `compiler/lineinfos.nim` | ソース | メッセージ種別定義（TMsgKind列挙型） |
| extccomp.nim | `compiler/extccomp.nim` | ソース | execWithEcho, execExternalProgram, execLinkCmd関数 |
| msgs.nim | `compiler/msgs.nim` | ソース | rawMessage関数、メッセージ出力処理 |
| options.nim | `compiler/options.nim` | ソース | optListCmd, verbosityオプション |
