# 機能設計書 120-clang-installapi

## 概要

本ドキュメントは、LLVMプロジェクトにおけるmacOS向けInstallAPI生成ツール「clang-installapi」の機能設計を記述する。

### 本機能の処理概要

clang-installapiは、macOS/iOS向けのダイナミックライブラリ（.dylib/.framework）からTextAPI形式のインターフェースファイル（.tbd）を生成するツールである。AppleのInstallAPI機能をClangライブラリとして実装し、ライブラリの公開API情報を抽出・検証・出力する。

**業務上の目的・背景**：macOS/iOSのSDKでは、ダイナミックライブラリの代わりにテキストベースのスタブファイル（.tbd）が含まれる。これにより、SDKサイズを大幅に削減しながら、リンク時に必要なシンボル情報を提供できる。clang-installapiは、ヘッダーファイルを解析してAPI情報を抽出し、オプションで既存のダイナミックライブラリと比較検証することで、正確な.tbdファイルを生成する。

**機能の利用シーン**：
- macOS/iOS向けフレームワークの.tbdファイル生成
- ライブラリAPIの検証（ヘッダーとバイナリの整合性確認）
- SDK向けスタブファイルの作成
- 複数アーキテクチャ対応のユニバーサルスタブ生成

**主要な処理内容**：
1. オプション解析と設定
2. ターゲット（アーキテクチャ/プラットフォーム）ごとの処理
3. ヘッダーファイルの解析（Clangフロントエンド）
4. シンボル収集（Public/Private/Project）
5. オプション：既存バイナリとの検証
6. InterfaceFile生成とTextAPI出力

**関連システム・外部連携**：Clang Frontend、InstallAPIライブラリ、TextAPIライブラリ

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

## 関連画面

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

## 機能種別

API抽出 / スタブ生成 / 検証

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| 入力ディレクトリ | string | Yes | ヘッダーファイルディレクトリ | 存在確認 |
| -o | string | Yes | 出力ファイルパス | パス妥当性確認 |
| -target | string[] | Yes | ターゲットトリプル | 有効なトリプル |
| -verify-against | string | No | 検証対象のdylib | ファイル存在確認 |
| -install_name | string | No | インストール名 | - |
| -current_version | string | No | 現在バージョン | バージョン形式 |
| -compatibility_version | string | No | 互換バージョン | バージョン形式 |
| -allowable_client | string[] | No | 許可クライアント | - |
| -rpath | string[] | No | ランタイムパス | - |

### 入力データソース

- ヘッダーファイルディレクトリ（Public/Private/Project）
- ファイルリスト（JSON形式）
- 検証対象ダイナミックライブラリ（オプション）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| TBDFile | text | TextAPI形式のスタブファイル |

### 出力先

- 指定されたファイル（-oオプション、必須）

## 処理フロー

### 処理シーケンス

```
1. 初期化処理
   ├─ Diagnosticsエンジン設定
   └─ FileManager作成
2. オプション解析（Options）
   ├─ ドライバオプション処理
   ├─ ターゲット設定
   └─ リンカオプション処理
3. InstallAPIContext作成
   ├─ BinaryAttrs設定
   └─ Verifier設定（検証モード時）
4. バイナリ属性検証（検証モード時）
   └─ verifyBinaryAttrs呼び出し
5. ターゲットループ
   ├─ スライス作成
   └─ ヘッダータイプループ（Public/Private/Project）
       ├─ Clang引数構築
       ├─ runFrontend呼び出し
       │   ├─ 入力バッファ作成
       │   ├─ Clang cc1実行
       │   └─ InstallAPIAction実行
       └─ FrontendRecordsに追加
6. シンボル検証
   └─ verifyRemainingSymbols
7. 出力ファイル生成
   ├─ InterfaceFile構築
   ├─ 属性設定
   └─ TextAPIWriter::writeToStream
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Diagnosticsエンジン作成]
    B --> C[FileManager作成]
    C --> D[Options解析]
    D --> E{エラー?}
    E -->|Yes| F[EXIT_FAILURE]
    E -->|No| G[InstallAPIContext作成]
    G --> H{検証モード?}
    H -->|Yes| I[verifyBinaryAttrs]
    H -->|No| J[ターゲットループ開始]
    I --> K{検証成功?}
    K -->|No| F
    K -->|Yes| J
    J --> L[スライス作成]
    L --> M[ヘッダータイプループ]
    M --> N[Public]
    N --> O[Clang引数構築]
    O --> P[runFrontend]
    P --> Q{成功?}
    Q -->|No| F
    Q -->|Yes| R[Private]
    R --> S[runFrontend]
    S --> T{成功?}
    T -->|No| F
    T -->|Yes| U[Project]
    U --> V[runFrontend]
    V --> W{成功?}
    W -->|No| F
    W -->|Yes| X[UniqueArgsループ]
    X --> Y[追加runFrontend]
    Y --> Z{次のターゲット?}
    Z -->|Yes| J
    Z -->|No| AA[verifyRemainingSymbols]
    AA --> AB{検証成功?}
    AB -->|No| F
    AB -->|Yes| AC[InterfaceFile構築]
    AC --> AD[属性設定]
    AD --> AE[TextAPIWriter出力]
    AE --> AF{出力成功?}
    AF -->|No| F
    AF -->|Yes| AG[EXIT_SUCCESS]
    F --> AH[終了]
    AG --> AH
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 出力ファイル必須 | -oオプションは必須 | 起動時 |
| BR-002 | ターゲット必須 | -targetオプションでアーキテクチャ/プラットフォーム必須 | 起動時 |
| BR-003 | ヘッダータイプ | Public/Private/Projectの3種類を順次処理 | ターゲット処理時 |
| BR-004 | スライス生成 | 各ターゲットごとにFrontendRecordsSlice生成 | ターゲット処理時 |
| BR-005 | 検証モード | -verify-against指定時はバイナリとの整合性検証 | 検証モード時 |

### 計算ロジック

- シンボル可視性：ヘッダータイプ（Public/Private/Project）に基づく
- アーキテクチャセット：複数ターゲットのマージ

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

該当なし（ファイルベースのツール）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| err_no_output_file | 必須エラー | -oオプション未指定 | エラーメッセージ出力後終了 |
| err_drv_unsupported_opt_for_target | ターゲットエラー | 無効なターゲット指定 | エラーメッセージ出力後終了 |
| err_cannot_open_file | ファイルエラー | 出力ファイルが開けない | エラーメッセージ出力後終了 |
| - | 検証エラー | バイナリとの不整合 | 検証結果出力後終了 |

### リトライ仕様

リトライ処理なし

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

該当なし

## パフォーマンス要件

特に規定なし

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

- 入力ヘッダーファイルの検証
- 出力ファイルパスの妥当性確認

## 備考

- AppleのInstallAPI機能のオープンソース実装
- macOS/iOSプラットフォーム向け
- TextAPI（.tbd）形式で出力

---

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

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

### 推奨読解順序

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

InstallAPIContextとOptionsがツールの主要構成要素。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Options.h | `clang/tools/clang-installapi/Options.h` | Options、DriverOpts、LinkerOptsの構造 |

**読解のコツ**: DriverOptsがターゲット情報、LinkerOptsがリンカ属性、FEOptsがフロントエンド設定を保持。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClangInstallAPI.cpp | `clang/tools/clang-installapi/ClangInstallAPI.cpp` | clang_installapi_main関数（203-216行目）、run関数（71-201行目） |

**主要処理フロー**:
1. **72-82行目**: Diagnosticsエンジン設定
2. **84-94行目**: FileManager作成
3. **97-99行目**: Options解析
4. **101-103行目**: InstallAPIContext作成
5. **105-113行目**: 検証モード時のバイナリ属性検証
6. **124-149行目**: ターゲット/ヘッダータイプループ
7. **151-152行目**: verifyRemainingSymbols
8. **154-163行目**: 出力ファイル作成
9. **166-186行目**: InterfaceFile構築と属性設定
10. **188-200行目**: TextAPI出力

#### Step 3: フロントエンド実行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ClangInstallAPI.cpp | `clang/tools/clang-installapi/ClangInstallAPI.cpp` | runFrontend関数（42-69行目） |

**runFrontend処理フロー**:
- **47-50行目**: 入力バッファ作成（createInputBuffer）
- **56-57行目**: 入力ファイルをInMemoryFileSystemに追加
- **60-63行目**: ターゲットトリプル付きの引数構築
- **66-68行目**: ToolInvocation実行（InstallAPIAction）

#### Step 4: オプション処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Options.cpp | `clang/tools/clang-installapi/Options.cpp` | processDriverOptions関数（108-200行目以降） |

**オプション処理フロー**:
- **110-117行目**: 入力ディレクトリ/ファイルリスト処理
- **119-130行目**: 出力ファイル処理（必須）
- **133-142行目**: -archと-targetの排他チェック
- **152-165行目**: ターゲットトリプル処理

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

```
clang_installapi_main()
    │
    ├─ sys::PrintStackTraceOnErrorSignal
    │
    └─ run()
           │
           ├─ DiagnosticsEngine作成
           │
           ├─ FileManager作成
           │
           ├─ Options()
           │      ├─ processDriverOptions()
           │      ├─ processLinkerOptions()
           │      └─ processFrontendOptions()
           │
           ├─ Opts.createContext()
           │      └─ InstallAPIContext作成
           │
           ├─ 検証モード時
           │      └─ Ctx.Verifier->verifyBinaryAttrs()
           │
           ├─ ターゲットループ
           │      │
           │      └─ ヘッダータイプループ
           │             │
           │             ├─ getClangFrontendArgs()
           │             ├─ addConditionalCC1Args()
           │             └─ runFrontend()
           │                    │
           │                    ├─ createInputBuffer()
           │                    ├─ InMemoryFileSystem追加
           │                    └─ ToolInvocation.run()
           │                           └─ InstallAPIAction
           │
           ├─ Ctx.Verifier->verifyRemainingSymbols()
           │
           ├─ InterfaceFile構築
           │      ├─ addTarget()
           │      ├─ setFromBinaryAttrs()
           │      ├─ addAllowableClient()
           │      ├─ addRPath()
           │      └─ addReexportedLibrary()
           │
           └─ TextAPIWriter::writeToStream()
```

### データフロー図

```
入力ヘッダー群
    │
    ├─ Public headers ──┐
    ├─ Private headers ─┼──▶ createInputBuffer()
    └─ Project headers ─┘         │
                                   ▼
                          InMemoryFileSystem
                                   │
                                   ▼
                          ToolInvocation
                                   │
                                   ▼
                         InstallAPIAction
                                   │
                                   ▼
                      FrontendRecordsSlice
                                   │
           ┌───────────────────────┼───────────────────────┐
           ▼                       ▼                       ▼
      Target1 Slice           Target2 Slice           TargetN Slice
           │                       │                       │
           └───────────────────────┼───────────────────────┘
                                   │
                                   ▼
                     Ctx.Verifier->takeExports()
                                   │
                                   ▼
                           InterfaceFile
                                   │
                    ┌──────────────┼──────────────┐
                    ▼              ▼              ▼
              addTarget    setFromBinaryAttrs  addRPath等
                    │              │              │
                    └──────────────┼──────────────┘
                                   │
                                   ▼
                    TextAPIWriter::writeToStream()
                                   │
                                   ▼
                            .tbdファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ClangInstallAPI.cpp | `clang/tools/clang-installapi/` | ソース | メイン処理 |
| Options.cpp | `clang/tools/clang-installapi/` | ソース | オプション処理 |
| Options.h | `clang/tools/clang-installapi/` | ヘッダ | オプション定義 |
| InstallAPIOpts.td | `clang/tools/clang-installapi/` | テーブルジェン | オプションテーブル |
| Frontend.h | `clang/include/InstallAPI/` | ヘッダ | フロントエンドインターフェース |
| MachO.h | `clang/include/InstallAPI/` | ヘッダ | MachO関連定義 |
| CMakeLists.txt | `clang/tools/clang-installapi/` | 設定 | ビルド設定 |
