# バッチ設計書 57-init-compiler.sh

## 概要

本ドキュメントは、ネイティブコードビルド用のC/C++コンパイラを検出・初期化するためのシェルスクリプト `eng/common/native/init-compiler.sh` の設計仕様を記載します。

### 本バッチの処理概要

このバッチは、ネイティブコードのビルドに使用するC/C++コンパイラ（Clang/GCC）を検出し、環境変数（CC、CXX、LDFLAGS等）を設定するためのスクリプトです。複数バージョンのコンパイラがインストールされている環境で、適切なバージョンを自動選択する機能を提供します。

**業務上の目的・背景**：.NET Runtimeのネイティブコンポーネント（CoreCLR等）は特定バージョン以上のClangまたはGCCでのみビルド可能です。開発者の環境には複数のコンパイラバージョンがインストールされていることが多く、どのバージョンを使用するかの選択が必要です。このスクリプトにより、利用可能なコンパイラから適切なバージョンを自動検出し、ビルドに必要な環境変数を統一的に設定できます。また、LLDリンカの自動選択によりリンク時間の短縮も実現します。

**バッチの実行タイミング**：他のビルドスクリプトから source コマンドで読み込まれます。build_arch と compiler 変数が事前に設定されている必要があります。

**主要な処理内容**：
1. 必須変数（build_arch、compiler）の確認
2. コンパイラ名とバージョンの解析（clang-13、gcc-11等）
3. 利用可能なコンパイラバージョンの検索
4. CC、CXX環境変数の設定
5. LLDリンカの検出と LDFLAGS の設定（Clangの場合）
6. scan-buildコマンドの検出

**前後の処理との関連**：このスクリプトは build_arch と compiler 変数が設定された状態で source されることを前提としています。設定された CC、CXX、LDFLAGS 変数は、後続のCMakeビルドで使用されます。

**影響範囲**：環境変数 CC、CXX、LDFLAGS、SCAN_BUILD_COMMAND を設定・エクスポートします。ファイルシステムへの変更は行いません。

## バッチ種別

環境検出 / コンパイラ設定 / ビルド前処理

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | ビルド実行時（随時） |
| 実行時刻 | ビルドスクリプト実行時 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 他スクリプトからのsource呼び出し |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Unix系OS | Linux、macOS等（Darwinでは一部動作が異なる） |
| build_arch 変数 | ターゲットアーキテクチャが設定されていること |
| compiler 変数 | 使用するコンパイラ名（clang/gcc）が設定されていること |
| コンパイラ | Clang 8以上またはGCC 8以上がインストールされていること |

### 実行可否判定

build_arch または compiler 変数が未設定の場合、使用方法を表示して exit 1 で終了します。互換性のあるコンパイラが見つからない場合もエラー終了します。

## 入力仕様

### 入力パラメータ

このスクリプトはコマンドライン引数ではなく、環境変数を入力として使用します。

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| build_arch | 環境変数 | Yes | - | ターゲットアーキテクチャ（x64、arm64等） |
| compiler | 環境変数 | Yes | - | コンパイラ指定（clang、gcc、clang-13等） |
| CLR_CC | 環境変数 | No | - | カスタムCコンパイラパス |
| CLR_CXX | 環境変数 | No | - | カスタムC++コンパイラパス |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| command -v | コマンド | コンパイラの存在確認 |
| $compiler -dumpversion | コマンド | コンパイラバージョン取得 |
| uname | コマンド | OS判定（Darwin判定用） |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| CC 環境変数 | パス | Cコンパイラのフルパス |
| CXX 環境変数 | パス | C++コンパイラのフルパス |
| LDFLAGS 環境変数 | フラグ | リンカオプション（-fuse-ld=lld等） |
| SCAN_BUILD_COMMAND 環境変数 | パス | scan-buildのフルパス |
| stderr | テキスト | エラーメッセージ |

### コンパイラバージョン検索範囲

| コンパイラ | 最小バージョン | 最大バージョン計算式 |
|-----------|---------------|---------------------|
| Clang | 8 | 18 + ((現在年-2024)*12 + 現在月-3) / 6 |
| GCC | 8 | 14 + ((現在年-2024)*12 + 現在月-3) / 12 |

## 処理フロー

### 処理シーケンス

```
1. 必須変数の確認
   └─ build_arch と compiler が設定されているか確認
2. コンパイラ種別とバージョンの解析
   └─ "clang-13" → compiler=clang, majorVersion=13
3. C++コンパイラ名の決定
   └─ clang → clang++、gcc → g++
4. 環境変数のクリア
   └─ CC、CXX、LDFLAGS を空に設定
5. コンパイラバージョンの検索
   └─ CLR_CC設定時: 指定パスを使用
   └─ バージョン指定時: 指定バージョンを検索
   └─ バージョン未指定時: 最新バージョンを自動検出
6. CC、CXX の設定
   └─ command -v でフルパスを取得
7. バージョン番号の取得
   └─ -dumpversion でメジャーバージョン取得
8. LLDリンカの設定（Clang、Linux、バージョン9以上）
   └─ -fuse-ld=lld が使用可能か確認
9. scan-buildの検出
   └─ scan-build{version} のパスを取得
10. 環境変数のエクスポート
    └─ export CC CXX LDFLAGS SCAN_BUILD_COMMAND
```

### フローチャート

```mermaid
flowchart TD
    A[スクリプト開始] --> B{build_arch設定?}
    B -->|No| C[使用方法表示 exit 1]
    B -->|Yes| D{compiler設定?}
    D -->|No| C
    D -->|Yes| E[コンパイラ種別解析]
    E --> F{CLR_CC設定?}
    F -->|Yes| G[CLR_CC/CLR_CXXを使用]
    F -->|No| H{バージョン指定?}
    H -->|Yes| I[指定バージョン検索]
    H -->|No| J[最新バージョン自動検出]
    I --> K{見つかった?}
    J --> K
    K -->|No| L{コンパイラ存在?}
    L -->|No| M[エラー exit 1]
    L -->|Yes| N[バージョンなしで設定]
    K -->|Yes| O[CC/CXX設定]
    G --> O
    N --> O
    O --> P[バージョン番号取得]
    P --> Q{Darwin?}
    Q -->|Yes| R[LDFLAGS設定スキップ]
    Q -->|No| S{Clang && ver>=9?}
    S -->|No| R
    S -->|Yes| T{s390x && ver<18?}
    T -->|Yes| R
    T -->|No| U{LLD使用可能?}
    U -->|Yes| V[LDFLAGS=-fuse-ld=lld]
    U -->|No| R
    R --> W[scan-build検出]
    V --> W
    W --> X[環境変数エクスポート]
    X --> Y[スクリプト終了]
```

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

### 操作別データベース影響一覧

本バッチはデータベース操作を行いません。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 引数エラー | build_arch または compiler が未設定 | 必要な変数を設定して再実行 |
| 1 | コンパイラ未検出 | 互換性のあるコンパイラが見つからない | 適切なバージョンのClang/GCCをインストール |
| 1 | バージョンエラー | 指定バージョンのコンパイラが見つからない | 正しいバージョンを指定または自動検出を使用 |
| 1 | CLR_CCパスエラー | CLR_CCで指定されたパスが存在しない | 正しいパスを指定 |

### リトライ仕様

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

### 障害時対応

1. エラーメッセージで必要な変数と検出範囲を確認
2. インストール済みのコンパイラバージョンを確認（clang --version、gcc --version）
3. CLR_CC、CLR_CXX 環境変数で明示的にコンパイラを指定
4. 必要に応じて適切なバージョンのコンパイラをインストール

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし |
| コミットタイミング | 該当なし |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回/ビルド |
| 目標処理時間 | 1秒未満 |
| メモリ使用量上限 | 最小限（シェル変数のみ） |

## 排他制御

排他制御は不要です。読み取り専用の環境検出のみを行います。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 使用方法 | 引数エラー時 | "Usage... build_arch=<ARCH> compiler=<NAME>" |
| エラーログ | コンパイラ未検出時 | "Error: No compatible version of $compiler was found" |
| エラーログ | バージョンエラー時 | "Error: Could not find specific version" |
| エラーログ | dumpversionエラー時 | "Error: $CC -dumpversion didn't provide a version" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | 呼び出し元スクリプト |

## 備考

- このスクリプトはArcade SDKの標準コンポーネントであり、.NET系プロジェクト全体で共有されています
- stdoutに何も出力しないことが重要です（他のスクリプトがsourceして使用するため）
- macOS（Darwin）ではLLDリンカの設定はスキップされます（Appleリンカを使用）
- Clangバージョン9以上でLLDが使用可能な場合、自動的に -fuse-ld=lld が設定されます
- s390xアーキテクチャはClang 18以上でのみLLDをサポートします
- コンパイラバージョンの最大値は、リリーススケジュールに基づいて動的に計算されます
- CLR_CC/CLR_CXX 環境変数により、標準的でないパスのコンパイラも使用可能です
