# 機能設計書 41-MonoAOTCompiler

## 概要

本ドキュメントは、.NETランタイムにおけるMonoAOTCompilerビルドタスクの機能設計を記述したものである。MonoAOTCompilerは、Monoランタイム向けにIL（Intermediate Language）コードをネイティブコードに事前コンパイル（AOT: Ahead-of-Time）する機能を提供するMSBuildタスクである。

### 本機能の処理概要

MonoAOTCompilerは、.NETアセンブリをネイティブコードに事前コンパイルすることで、実行時のJITコンパイルを不要にし、起動時間の短縮やメモリ使用量の削減を実現する。

**業務上の目的・背景**：モバイルプラットフォーム（iOS、Android）やWebAssemblyなど、JITコンパイラが利用できない、または性能上の理由からAOTコンパイルが望ましい環境において、.NETアプリケーションを実行可能にする必要がある。AOTコンパイルにより、アプリケーションの起動時間短縮、予測可能な実行性能、メモリフットプリントの削減が実現できる。

**機能の利用シーン**：
- iOS/Android向けモバイルアプリケーションのビルド時
- Blazor WebAssemblyアプリケーションのビルド時
- パフォーマンスクリティカルなサーバーアプリケーションの最適化時
- 組み込みシステム向けアプリケーションのビルド時

**主要な処理内容**：
1. 入力アセンブリの検証と管理対象外アセンブリのフィルタリング
2. AOTコンパイラ（mono-aot-cross）の引数生成と実行
3. LLVMを使用した最適化コンパイルのサポート
4. 並列コンパイルによるビルド時間の短縮
5. AOTモジュールテーブルの生成（静的リンク用）
6. 出力ファイル（オブジェクトファイル、アセンブリファイル、ライブラリ）の管理
7. キャッシュ機能による増分コンパイルのサポート

**関連システム・外部連携**：
- mono-aot-cross（Mono AOTクロスコンパイラ）
- LLVM（最適化バックエンド）
- MSBuildシステム（ビルドタスクとして実行）

**権限による制御**：特になし。ファイルシステムへの読み書き権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | ビルドプロセス（CLI） | 主機能 | dotnet buildコマンドから間接的に呼び出される |

## 機能種別

ビルドタスク / コンパイル処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| CompilerBinaryPath | string | Yes | AOTコンパイラ（mono-aot-cross）のパス | ファイルが存在すること |
| Assemblies | ITaskItem[] | Yes | AOT対象アセンブリのリスト | 少なくとも1つ以上 |
| OutputDir | string | Yes | 出力ディレクトリ | ディレクトリが存在すること |
| IntermediateOutputPath | string | Yes | 中間出力ディレクトリ | - |
| Mode | string | No | AOTモード（Normal, Full, LLVMOnly等） | 有効な列挙値 |
| OutputType | string | No | 出力形式（ObjectFile, AsmOnly, Library） | 有効な列挙値 |
| UseLLVM | bool | No | LLVMを使用するか | LLVMPath設定時はtrue必須 |
| LLVMPath | string | No | LLVMバイナリのパス | UseLLVM時に必須 |
| Triple | string | No | ターゲットトリプル | - |
| UseStaticLinking | bool | No | 静的リンクを使用するか | - |
| DisableParallelAot | bool | No | 並列AOTを無効化するか | - |
| CacheFilePath | string | No | キャッシュファイルのパス | - |

### 入力データソース

- ビルドプロセスから渡されるアセンブリファイル（.dll）
- プロファイルファイル（.mibc, .aotprofile）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CompiledAssemblies | ITaskItem[] | AOTコンパイル済みアセンブリ情報 |
| FileWrites | string[] | 書き込まれたファイルのパス一覧 |

### 出力先

- オブジェクトファイル（.dll.o）: OutputDir
- アセンブラファイル（.dll.s）: OutputDir
- ライブラリファイル（.dll.so/.dll.dylib/.dll.dll）: OutputDir
- AOTデータファイル（.aotdata）: アセンブリと同じディレクトリ
- LLVMビットコード/オブジェクト（.dll.bc, .dll-llvm.o）: OutputDir
- AOTモジュールテーブル（.c/.m）: AotModulesTablePath

## 処理フロー

### 処理シーケンス

```
1. 引数の検証
   └─ CompilerBinaryPath、Assemblies、OutputDirの存在確認
   └─ AOTモードと出力タイプの解析
   └─ LLVM設定の検証

2. アセンブリのフィルタリング
   └─ 非マネージドアセンブリを除外
   └─ AOT_InternalForceToInterpret属性を持つアセンブリを除外

3. AOTモジュールテーブルの生成（必要な場合）
   └─ 静的リンク用のC/ObjCソースコード生成

4. 並列AOTコンパイル
   └─ 各アセンブリに対してmono-aot-crossを実行
   └─ 環境変数MONO_PATHの設定
   └─ レスポンスファイル経由での引数渡し

5. 出力ファイルの収集
   └─ コンパイル結果のメタデータ設定
   └─ キャッシュファイルの更新
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数検証]
    B --> C{引数有効?}
    C -->|No| Z[エラー終了]
    C -->|Yes| D[アセンブリフィルタリング]
    D --> E{AotModulesTablePath設定?}
    E -->|Yes| F[AOTモジュールテーブル生成]
    E -->|No| G[並列AOTコンパイル]
    F --> G
    G --> H{全て成功?}
    H -->|No| Z
    H -->|Yes| I[出力メタデータ設定]
    I --> J[キャッシュ更新]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-41-01 | LLVMOnlyモード制約 | LLVMOnlyモードではUseLLVM=trueが必須 | Mode=LLVMOnly時 |
| BR-41-02 | 静的リンク制約 | UseDirectIcallsはUseStaticLinking=trueが必要 | UseDirectIcalls=true時 |
| BR-41-03 | ライブラリモード制約 | OutputType=LibraryとUseStaticLinkingは併用不可 | OutputType=Library時 |
| BR-41-04 | P/Invoke制約 | UseDirectPInvokeとDirectPInvokesは併用不可 | UseDirectPInvoke=true時 |

### 計算ロジック

並列度の決定:
```
allowedParallelism = DisableParallelAot ? 1 : Min(Assemblies.Length, Environment.ProcessorCount)
```

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

該当なし（ファイルシステム操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル不在 | CompilerBinaryPathが存在しない | 正しいパスを指定 |
| - | 引数エラー | Assembliesが空 | 少なくとも1つのアセンブリを指定 |
| - | コンパイルエラー | AOTコンパイラが非0で終了 | ログを確認して問題を修正 |
| LogAsErrorException | 設定エラー | 無効なMode/OutputType値 | 有効な値を指定 |

### リトライ仕様

リトライは行わない。失敗したアセンブリがある場合は処理を中断する。

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

該当なし

## パフォーマンス要件

- 並列処理によりCPUコア数に応じたスケーラビリティを確保
- キャッシュ機能により増分コンパイルをサポート
- ワークスティーリングにより負荷分散を最適化

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

- 入力ファイルパスの検証（パストラバーサル対策）
- プロセス実行時の環境変数制御

## 備考

- MonoAOTCompilerは主にモバイル/WebAssemblyワークロードで使用される
- LLVMを使用することでより高度な最適化が可能

---

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

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

### 推奨読解順序

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

まず、AOTコンパイルに関連するデータ型と列挙型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MonoAOTCompiler.cs | `src/tasks/AotCompilerTask/MonoAOTCompiler.cs` | 1340-1369行目のenum定義（MonoAotMode, MonoAotOutputType, MonoAotLibraryFormat, MonoAotModulesTableLanguage） |

**読解のコツ**: 列挙型MonoAotModeの各値（Normal, JustInterp, Full, FullInterp, Hybrid, LLVMOnly, LLVMOnlyInterp）がどのような動作モードを表すかを理解することが重要。

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

MSBuildタスクのエントリーポイントであるExecuteメソッドを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MonoAOTCompiler.cs | `src/tasks/AotCompilerTask/MonoAOTCompiler.cs` | 488-504行目のExecute()メソッド |

**主要処理フロー**:
1. **488-504行目**: Executeメソッドでtry-catch-finallyによるエラーハンドリング
2. **507-609行目**: ExecuteInternal()で実際の処理を実行

#### Step 3: 引数検証処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MonoAOTCompiler.cs | `src/tasks/AotCompilerTask/MonoAOTCompiler.cs` | 329-485行目のProcessAndValidateArguments()メソッド |

**主要処理フロー**:
- **331-335行目**: CompilerBinaryPathの存在確認
- **337-341行目**: Assembliesの空チェック
- **391-407行目**: Mode/OutputTypeの解析
- **420-464行目**: 各種制約条件のチェック

#### Step 4: AOTコンパイル引数生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | MonoAOTCompiler.cs | `src/tasks/AotCompilerTask/MonoAOTCompiler.cs` | 691-1038行目のGetPrecompileArgumentsFor()メソッド |

**主要処理フロー**:
- **716-728行目**: LLVM関連オプションの設定
- **809-908行目**: 出力モードに応じたファイル名とオプション設定
- **1020-1024行目**: 環境変数の設定

#### Step 5: 並列コンパイル実行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | MonoAOTCompiler.cs | `src/tasks/AotCompilerTask/MonoAOTCompiler.cs` | 584-602行目のParallel.ForEachによる並列実行 |
| 5-2 | MonoAOTCompiler.cs | `src/tasks/AotCompilerTask/MonoAOTCompiler.cs` | 1040-1102行目のPrecompileLibrary()メソッド |

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

```
Execute()
    │
    ├─ ExecuteInternal()
    │      │
    │      ├─ ProcessAndValidateArguments()
    │      │
    │      ├─ FilterOutUnmanagedAssemblies()
    │      │
    │      ├─ EnsureAllAssembliesInTheSameDir()
    │      │
    │      ├─ GenerateAotModulesTable() [optional]
    │      │
    │      ├─ GetPrecompileArgumentsFor() [for each assembly]
    │      │
    │      └─ Parallel.ForEach
    │             └─ PrecompileLibraryParallel()
    │                    └─ PrecompileLibrary()
    │                           └─ Utils.TryRunProcess() [mono-aot-cross]
    │
    └─ FileCache.Save()
```

### データフロー図

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

Assemblies(.dll) ───▶ FilterOutUnmanagedAssemblies() ──▶ managedAssemblies
                              │
                              ▼
                    GetPrecompileArgumentsFor()
                              │
                              ▼
                    mono-aot-cross実行
                              │
                              ▼
                    ┌─────────┼─────────┐
                    ▼         ▼         ▼
              .dll.o     .dll.bc    .aotdata
              (Object)   (LLVM BC)  (AOT Data)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MonoAOTCompiler.cs | `src/tasks/AotCompilerTask/MonoAOTCompiler.cs` | ソース | メインのMSBuildタスク実装 |
| MonoAOTCompiler.csproj | `src/tasks/AotCompilerTask/MonoAOTCompiler.csproj` | プロジェクト | ビルド設定 |
| MonoAOTCompiler.props | `src/mono/msbuild/common/MonoAOTCompiler.props` | MSBuild | デフォルトプロパティ定義 |
| Microsoft.NET.Runtime.MonoAOTCompiler.Task.props | `src/mono/nuget/Microsoft.NET.Runtime.MonoAOTCompiler.Task/build/` | MSBuild | NuGetパッケージ用プロパティ |
