# 機能設計書 61-llvm-mt

## 概要

本ドキュメントは、LLVM llvm-mt ツールの機能設計について記載する。llvm-mtは、Windowsマニフェストファイル(.manifest)のマージを行うクロスプラットフォーム対応ツールである。

### 本機能の処理概要

llvm-mtは、複数のWindowsマニフェストXMLファイルを読み込み、それらを1つのマニフェストファイルにマージして出力するツールである。Microsoft社のmt.exeのプラットフォーム非依存な代替実装として設計されている。

**業務上の目的・背景**：Windowsアプリケーション開発において、マニフェストファイルは実行ファイルのメタデータ（依存関係、権限、バージョン情報など）を記述する重要なXMLファイルである。複数のコンポーネントからマニフェストを統合する必要がある場合、このツールを使用してマージ処理を自動化できる。LLVMツールチェーンの一部として、クロスコンパイル環境でもWindowsアプリケーションのビルドを可能にする。

**機能の利用シーン**：
- Windowsアプリケーションのビルドプロセスにおいて、複数のライブラリやコンポーネントのマニフェストを統合する場合
- クロスプラットフォーム開発環境（Linux/macOS上でのWindows向けビルド）でのマニフェスト処理
- CI/CDパイプラインにおける自動ビルドでのマニフェストマージ処理

**主要な処理内容**：
1. コマンドライン引数の解析（-manifest、-out等のオプション処理）
2. 指定された入力マニフェストファイルの読み込み
3. WindowsManifestMergerを使用したXMLマニフェストのマージ処理
4. マージ結果の出力ファイルへの書き込み
5. -notify_updateオプション時の変更検出と特別な終了コード返却

**関連システム・外部連携**：LLVMビルドシステム、WindowsManifestMergerライブラリ（llvm/WindowsManifest）

**権限による制御**：特になし（ファイルシステムへのアクセス権限のみ必要）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIツール | 主機能 | コマンドラインインターフェースによる操作 |

## 機能種別

ファイル変換処理 / XMLマージ処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -manifest | string | Yes | マージ対象のマニフェストファイルパス（複数指定可能） | ファイルが存在すること |
| -out: | string | No | 出力ファイルパス。省略時は入力ファイルが1つの場合そのファイルに上書き | - |
| -notify_update | flag | No | 出力ファイルに変更があった場合に特別な終了コードを返す | - |
| -nologo | flag | No | 互換性のために存在（効果なし） | - |
| -help / -? / -h | flag | No | ヘルプ表示 | - |

### 入力データソース

- ファイルシステム上のマニフェストXMLファイル（.manifest）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| マージされたマニフェスト | XML | 統合されたWindowsマニフェストXML |
| 終了コード | int | 0: 成功（変更なし）、0xbb(Unix)/0x41020001(Win): 変更あり（-notify_update時） |

### 出力先

- 指定された出力ファイル（-out:オプション）
- 入力ファイルが1つの場合はその場所に上書き

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数解析
   └─ CvtResOptTableを使用してオプションを解析

2. 入力ファイルの検証
   └─ -manifestで指定されたファイルの存在確認

3. 出力先の決定
   └─ -out:指定時はその値を使用、なければ単一入力ファイルパスを使用

4. マニフェストのマージ
   └─ WindowsManifestMergerに各マニフェストを順次merge

5. マージ結果の取得
   └─ getMergedManifest()でMemoryBufferとして取得

6. 変更検出（-notify_update時）
   └─ 既存の出力ファイルと内容比較

7. 出力ファイルへの書き込み
   └─ FileOutputBufferを使用してファイル出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C{ヘルプ要求?}
    C -->|Yes| D[ヘルプ表示]
    D --> E[終了 code=0]
    C -->|No| F{入力ファイル存在?}
    F -->|No| G[エラー終了]
    F -->|Yes| H[WindowsManifestMerger初期化]
    H --> I[各マニフェストをmerge]
    I --> J[getMergedManifest]
    J --> K{結果は空?}
    K -->|Yes| L[エラー: 空マニフェスト]
    K -->|No| M{-notify_update?}
    M -->|Yes| N[既存ファイルと比較]
    N --> O{変更あり?}
    O -->|Yes| P[ExitCode = 0xbb/0x41020001]
    O -->|No| Q[ExitCode = 0]
    M -->|No| Q
    P --> R[ファイル出力]
    Q --> R
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-1 | 単一入力時の出力先 | 入力ファイルが1つで-outが未指定の場合、入力ファイルを上書き | 入力ファイル数=1 かつ -out未指定 |
| BR-61-2 | 複数入力時の出力必須 | 複数の入力ファイルがある場合は-outオプション必須 | 入力ファイル数>1 |
| BR-61-3 | 変更通知終了コード | -notify_update時、変更があればUnixでは0xbb、Windowsでは0x41020001を返す | -notify_update指定時 |

### 計算ロジック

特になし

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

該当なし（データベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 入力ファイルエラー | 入力ファイルが指定されていない | "no input file specified"メッセージを表示し終了 |
| - | 出力ファイルエラー | 複数入力で-outが未指定 | "no output file specified"メッセージを表示し終了 |
| - | 空マニフェストエラー | マージ結果が空 | "empty manifest not written"メッセージを表示し終了 |
| - | ファイル読み込みエラー | マニフェストファイルが読み込めない | ファイル名とエラーメッセージを表示し終了 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

特に定義なし（通常のファイルI/O性能に依存）

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

- 入力ファイルへの読み取りアクセス権限が必要
- 出力ファイルへの書き込みアクセス権限が必要

## 備考

- Microsoft mt.exeとの互換性のため、サポートしていないオプション（-identity:、-rgs:など）は警告を出力して無視する
- XMLパース処理はWindowsManifestMergerライブラリに委譲

---

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

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

### 推奨読解順序

#### Step 1: オプション定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Opts.td | `llvm/tools/llvm-mt/Opts.td` | TableGen形式でのコマンドラインオプション定義 |

**読解のコツ**: Opts.tdはTableGen形式でオプションを定義。`Separate`は引数を取るオプション、`Joined`は`=`で値を繋げるオプション、`Flag`はフラグ型。`Group<unsupported>`はサポート外オプションをグループ化。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-mt.cpp | `llvm/tools/llvm-mt/llvm-mt.cpp` | メイン処理フロー全体 |

**主要処理フロー**:
1. **82-86行目**: llvm_mt_main関数のエントリーポイント、引数解析
2. **108-111行目**: -helpオプション時のヘルプ表示処理
3. **113-126行目**: 入力/出力ファイルの検証と設定
4. **128-136行目**: WindowsManifestMergerを使用したマージ処理ループ
5. **138-140行目**: マージ結果の取得と空チェック
6. **142-162行目**: -notify_updateオプション時の変更検出処理
7. **164-171行目**: FileOutputBufferを使用したファイル出力

#### Step 3: マニフェストマージライブラリを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WindowsManifestMerger.h | `llvm/include/llvm/WindowsManifest/WindowsManifestMerger.h` | マージAPIの定義 |

**主要処理フロー**:
- WindowsManifestMergerクラスのmerge()メソッドでマニフェストを順次追加
- getMergedManifest()でマージ結果をMemoryBufferとして取得

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

```
llvm_mt_main()
    │
    ├─ CvtResOptTable::ParseArgs()
    │      └─ コマンドライン引数解析
    │
    ├─ WindowsManifestMerger::merge()
    │      └─ マニフェストXMLのマージ処理
    │
    ├─ WindowsManifestMerger::getMergedManifest()
    │      └─ マージ結果の取得
    │
    ├─ MemoryBuffer::getFile()
    │      └─ 既存ファイル読み込み（-notify_update時）
    │
    └─ FileOutputBuffer::create() / commit()
           └─ 出力ファイルの書き込み
```

### データフロー図

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

manifest1.xml ───┐
                 ├──▶ WindowsManifestMerger ───▶ merged.manifest
manifest2.xml ───┘          │
                            │
                            ▼
                    getMergedManifest()
                            │
                            ▼
                    FileOutputBuffer
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-mt.cpp | `llvm/tools/llvm-mt/llvm-mt.cpp` | ソース | メインプログラム |
| Opts.td | `llvm/tools/llvm-mt/Opts.td` | 定義 | コマンドラインオプション定義 |
| CMakeLists.txt | `llvm/tools/llvm-mt/CMakeLists.txt` | ビルド | ビルド設定 |
| WindowsManifestMerger.h | `llvm/include/llvm/WindowsManifest/WindowsManifestMerger.h` | ヘッダ | マージライブラリAPI |
