# バッチ設計書 43-build-rootfs.sh

## 概要

本ドキュメントは、クロスコンパイル用のルートファイルシステム（rootfs/sysroot）を構築するBashスクリプト `eng/common/cross/build-rootfs.sh` の設計を記述します。このスクリプトは、Linux ARM、ARM64、RISC-V等のターゲットプラットフォーム向けビルド環境の構築を自動化します。

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

このバッチでは、指定されたアーキテクチャとLinuxディストリビューション用のルートファイルシステムを構築し、クロスコンパイルに必要なヘッダーファイル、ライブラリ、開発ツールを配置します。

**業務上の目的・背景**：.NET Runtimeは複数のCPUアーキテクチャ（ARM、ARM64、RISC-V64、x64等）とOS（Ubuntu、Alpine、FreeBSD、Haiku等）をサポートしています。ホストマシン（通常x64 Linux）から異なるアーキテクチャ向けにビルドするには、ターゲット環境のシステムライブラリとヘッダーファイルを含むsysrootが必要です。本スクリプトはこのsysrootを自動構築します。

**バッチの実行タイミング**：クロスコンパイルビルドの前に1回実行されます。rootfsは一度構築すれば、同じターゲット向けの複数ビルドで再利用可能です。

**主要な処理内容**：
1. コマンドライン引数の解析（アーキテクチャ、ディストリビューション、LLDBバージョン等）
2. ターゲットに応じたパッケージリストの構築
3. ディストリビューションに応じた構築方法の選択
4. debootstrap（Debian/Ubuntu）、apk（Alpine）、pkg（FreeBSD）等によるrootfs構築
5. シンボリックリンクの修正と後処理

**前後の処理との関連**：このスクリプトで構築されたrootfsは、環境変数`ROOTFS_DIR`を通じてビルドスクリプト（build.sh）に渡され、CMakeのsysroot設定に使用されます。

**影響範囲**：クロスコンパイルビルド全体に影響します。rootfsの構築に失敗すると、対象アーキテクチャ向けのビルドができません。

## バッチ種別

環境構築 / クロスコンパイル準備

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（クロスコンパイル環境構築時） |
| 実行時刻 | N/A |
| 実行曜日 | N/A |
| 実行日 | N/A |
| トリガー | 手動実行またはCI初回セットアップ |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Linux環境 | Linux（Ubuntu推奨）またはmacOS |
| rootアクセス | debootstrap使用時はsudo権限が必要 |
| ネットワーク接続 | パッケージダウンロードにインターネット接続が必要 |
| 必須ツール | wget/curl、debootstrap（Ubuntu/Debian用）、qemu-user-static（エミュレーション用） |

### 実行可否判定

指定されたアーキテクチャとディストリビューションの組み合わせがサポートされていない場合は失敗します。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| BuildArch | string | No | arm | ターゲットアーキテクチャ（arm, arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64, x86） |
| CodeName | string | No | xenial | Linuxディストリビューション（xenial, bionic, focal, jammy, noble, alpine, freebsd13, freebsd14, illumos, haiku） |
| lldbx.y | string | No | lldb3.9 | LLDBバージョン（lldb3.9, lldb4.0, lldb5.0, lldb6.0, no-lldb） |
| llvmx[.y] | string | No | なし | LLVMバージョン |
| --skipunmount | flag | No | false | rootfsディレクトリのアンマウントをスキップ |
| --skipsigcheck | flag | No | false | パッケージ署名チェックをスキップ |
| --skipemulation | flag | No | false | QEMUエミュレーションをスキップ |
| --use-mirror | flag | No | false | ミラーURLを使用 |
| --rootfsdir | string | No | .tools/rootfs/{arch} | rootfs出力ディレクトリ |
| --jobs N | int | No | CPU数 | 並列ジョブ数 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| パッケージリポジトリ | HTTP | Ubuntu/Debian/Alpine/FreeBSD等のパッケージリポジトリ |
| Alpineキーリング | 埋め込み | Alpineパッケージ署名検証用の公開鍵 |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| rootfsディレクトリ | ファイルシステム | 指定された--rootfsdirまたはデフォルトパス |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ディレクトリ名 | .tools/rootfs/{BuildArch} |
| 内容 | /usr/include（ヘッダー）、/usr/lib（ライブラリ）、/lib（共有ライブラリ）等 |
| サイズ | 数百MB〜数GB（ディストリビューションによる） |

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ アーキテクチャ、ディストリビューション、オプションの設定
2. パッケージリストの構築
   └─ ベース開発パッケージ（build-essential等）
   └─ ランタイム依存パッケージ（libicu-dev, libunwind等）
   └─ LLDBパッケージ（指定時）
3. 既存rootfsの削除
   └─ 既存ディレクトリがあればアンマウントして削除
4. rootfsディレクトリの作成
5. ディストリビューション別処理
   └─ Alpine: apk.staticでパッケージインストール
   └─ FreeBSD: base.txz展開とpkgでパッケージインストール
   └─ illumos: sysrootダウンロードとbinutilsのビルド
   └─ Haiku: hpkgパッケージ展開
   └─ Ubuntu/Debian: debootstrapでベースシステム構築、apt-getでパッケージインストール
   └─ Tizen: tizen-build-rootfs.shを呼び出し
6. 後処理
   └─ シンボリックリンクの修正
   └─ 一時ファイルのクリーンアップ
```

### フローチャート

```mermaid
flowchart TD
    A[スクリプト開始] --> B[引数解析]
    B --> C[パッケージリスト構築]
    C --> D{既存rootfs?}
    D -->|Yes| E[アンマウント・削除]
    D -->|No| F[rootfsディレクトリ作成]
    E --> F
    F --> G{ディストリビューション?}
    G -->|Alpine| H[apk.staticでインストール]
    G -->|FreeBSD| I[base.txz展開+pkg]
    G -->|illumos| J[sysroot+gcc/binutilsビルド]
    G -->|Haiku| K[hpkg展開]
    G -->|Ubuntu/Debian| L[debootstrap+apt-get]
    G -->|Tizen| M[tizen-build-rootfs.sh呼び出し]
    H --> N[後処理・クリーンアップ]
    I --> N
    J --> N
    K --> N
    L --> N
    M --> N
    N --> O[正常終了]
```

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

本スクリプトはデータベース操作を行いません。

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

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| exit 1 | 使用方法エラー | 不正な引数指定 | ヘルプを参照して正しい引数を指定 |
| exit 1 | ダウンロードエラー | パッケージリポジトリへの接続失敗 | ネットワーク接続を確認 |
| exit 1 | debootstrap失敗 | ベースシステム構築エラー | debootstrap.logを確認 |
| exit 1 | ツール不足 | wget/curlが見つからない | 必要なツールをインストール |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（個別ダウンロードは内部でリトライあり） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. ネットワーク接続を確認
2. パッケージリポジトリの可用性を確認
3. debootstrap.log（存在する場合）を確認
4. --skipsigcheckオプションで署名チェックをスキップして再試行
5. 手動でrootfsディレクトリを削除してから再実行

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイル操作） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1回のrootfs構築 |
| 目標処理時間 | 5-30分（ネットワーク速度による） |
| メモリ使用量上限 | 2GB以上推奨 |
| ディスク使用量 | 1-5GB（ディストリビューションによる） |

## 排他制御

同一rootfsディレクトリへの同時実行は避けてください。スクリプトは既存ディレクトリを削除してから構築を開始します。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 情報ログ | 各ステップ | パッケージインストール状況 |
| エラーログ | debootstrap失敗時 | debootstrap.logの内容 |
| デバッグログ | --verbose指定時 | 詳細な処理状況 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 処理時間 | 60分超過 | CI通知 |
| ディスク空き容量 | 5GB未満 | CI通知 |

## 備考

- サポートされるアーキテクチャ: arm, arm64, armel, armv6, loongarch64, ppc64le, riscv64, s390x, x64, x86
- サポートされるディストリビューション: Ubuntu (xenial〜noble)、Debian (stretch〜sid)、Alpine (3.13〜edge)、FreeBSD (13, 14)、illumos、Haiku、Tizen
- Alpineパッケージ署名用の公開鍵がスクリプトに埋め込まれています
- FreeBSD構築時はpkgをソースからビルドします
- illumos構築時はbinutilsとgccをソースからビルドするため、時間がかかります
- --skipemulationオプションを使用すると、debootstrapの代わりにPythonスクリプト（install-debs.py）を使用します
