# 画面設計書 35-niminst csource

## 概要

本ドキュメントは、Nimコンパイラプロジェクトのインストーラ・パッケージ生成ツール「niminst」における「csource」サブコマンドの画面設計書である。niminst csourceはブートストラップ用のCソースコードを生成する機能を提供する。

### 本画面の処理概要

niminst csourceコマンドは、NimコンパイラのソースコードからCソースコードを生成し、ブートストラップ（Cコンパイラのみでビルド可能な状態）を実現するための機能を提供する。

**業務上の目的・背景**：Nimコンパイラ自体はNim言語で書かれているため、新規環境でビルドするには既存のNimコンパイラが必要となる「鶏と卵」の問題がある。csourceコマンドはこの問題を解決するため、各プラットフォーム（OS・CPU）向けのCソースコードを生成し、Cコンパイラのみでビルドできるようにする。これにより、Nimが利用できない環境でも標準的なCコンパイラ（GCC, Clang等）でNimコンパイラをビルドできる。

**画面へのアクセス方法**：コマンドラインから`niminst csource <ini-file> [options]`の形式で実行する。通常は`koch csource`コマンド経由で呼び出されることが多い。

**主要な操作・処理内容**：
1. INIファイルから対象OS・CPU一覧を取得
2. 各OS・CPUの組み合わせに対してNimコンパイラを呼び出し
3. --compileonly --gen_mappingオプションでCソースのみ生成
4. mapping.txtからCファイルリストを取得
5. c_code/{os}_{cpu}/ディレクトリにCソースをコピー
6. 重複ファイルの排除（SHA1ハッシュで同一性確認）
7. build.sh, build.bat, makefileなどのビルドスクリプトを生成
8. install.sh, deinstall.shを生成（設定による）

**画面遷移**：
- 遷移元：niminstメイン画面またはkochビルドツール
- 遷移先：なし（Cソース生成完了後に終了）

**権限による表示制御**：特になし。CLIツールとして実行権限があれば使用可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 30 | Niminst | 主機能 | ブートストラップ用Cソース生成処理 |
| 1 | Nimコンパイラ本体 | 遷移先機能 | Cソース生成のためのコンパイラ呼び出し |
| 5 | Cコード生成 | 補助機能 | NimコードからCソースを生成 |

## 画面種別

CLIコマンド実行画面（Cソース生成）

## URL/ルーティング

```
niminst csource <ini-file> [compile_options]
```

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 | 例 |
|--------|-----|------|------|-----|
| ini-file | path | Yes | 設定ファイルパス | nim.ini |
| -o, --output | path | No | 出力ディレクトリ | build |
| -m, --main | path | No | メインNimファイル | compiler/nim.nim |
| compile_options | string | No | Nimコンパイラに渡すオプション | -d:danger |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| c_code/{os}_{cpu}/*.c | files | 各プラットフォーム向けCソース |
| c_code/*.h | files | ヘッダファイル（共通） |
| build.sh | file | Unix向けビルドスクリプト |
| build.bat | file | Windows向けビルドスクリプト |
| build32.bat | file | Windows 32bit向けビルドスクリプト |
| build64.bat | file | Windows 64bit向けビルドスクリプト |
| makefile | file | Make用ビルドファイル |
| install.sh | file | インストールスクリプト |
| deinstall.sh | file | アンインストールスクリプト |

## 表示項目

### コマンド実行時の表示

| 項目 | 表示形式 | 説明 |
|------|----------|------|
| コンパイルコマンド | コマンドライン | nimコンパイラ呼び出しコマンド |
| 警告 | "[Warning]"形式 | ファイルが見つからない場合等 |

## イベント仕様

### 1-Cソース生成（srcdist）

csourceコマンドが実行されると以下の処理が行われる：

1. main()からactionCSourceを検出
2. srcdist()関数を呼び出し
3. getOutputDir()で出力ディレクトリを決定
4. c_codeディレクトリを作成
5. gatherFiles()でlib/*.hをコピー
6. 各OS・CPUの組み合わせでループ：
   a. buildDir()でディレクトリ名を生成（c_code/{os}_{cpu}）
   b. nimコンパイラを呼び出し（--compileonly --gen_mapping）
   c. readCFiles()でmapping.txtを解析
   d. Cソースファイルをディレクトリにコピー
7. deduplicateFiles()で重複ファイルを排除
8. generateBuildShellScript()でbuild.shを生成
9. generateMakefile()でmakefileを生成
10. generateBuildBatchScript()でbuild.batを生成
11. writeInstallScripts()でインストールスクリプトを生成

### 2-Nimコンパイラ呼び出し

各プラットフォーム向けにNimコンパイラを呼び出す：

```
nim compile -f --incremental:off --d:nimKochBootstrap --compileonly --gen_mapping --cc:gcc --skipUserCfg --os:{os} --cpu:{cpu} {nimArgs} {mainfile}
```

### 3-mapping.txt解析

コンパイラが生成するmapping.txtを解析し、Cファイルリストを取得：

1. readCFiles()でファイルをオープン
2. [cfiles]セクションからfileキーを抽出
3. [ccompiler]セクションからパス・フラグを取得
4. [linker]セクションからリンカ情報を取得

## データベース更新仕様

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

本ツールはファイルシステム操作のみを行い、データベースは使用しない。

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| Cソース生成 | c_code/{os}_{cpu}/*.c | 生成 | 各プラットフォーム向けCソース |
| ヘッダコピー | c_code/*.h | コピー | 共通ヘッダファイル |
| スクリプト生成 | build.sh, makefile等 | 生成 | ビルドスクリプト |

### 出力ディレクトリ構造

```
build/
  c_code/
    *.h                    # 共通ヘッダ
    1_1/                   # OS=1, CPU=1（例：windows_i386）
      @m*.c                # Cソースファイル
    1_2/                   # OS=1, CPU=2（例：windows_amd64）
      @m*.c
    2_1/                   # OS=2, CPU=1（例：linux_i386）
      @m*.c
    ...
  build.sh
  build.bat
  build32.bat
  build64.bat
  makefile
  install.sh
  deinstall.sh
```

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 情報 | "{コンパイルコマンド}" | nimコンパイラ呼び出し時 |
| MSG002 | エラー | "Error: call to nim compiler failed" | コンパイル失敗時 |
| MSG003 | エラー | "Cannot open: {file}" | mapping.txtが開けない場合 |

## 例外処理

| 例外条件 | 処理内容 | エラーメッセージ |
|----------|----------|-----------------|
| コンパイル失敗 | プログラム終了 | "Error: call to nim compiler failed" |
| mapping.txtが存在しない | プログラム終了 | "Cannot open: {file}" |
| 出力ディレクトリ作成失敗 | OS例外 | createDirのエラー |

## 備考

- c_codeディレクトリ内のファイル名は@mプレフィックスで始まる（@m{モジュール名}.c）
- 重複排除により、同一内容のCファイルは1つのみ保持され、他は参照となる
- build.shはBourne Shell互換、build.batはWindowsバッチ形式
- makefileはGNU Make互換
- -d:dangerオプションを使用すると最適化されたCソースが生成される

---

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

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

### 推奨読解順序

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

まず、Cファイル管理のデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | niminst.nim | `tools/niminst/niminst.nim` | ConfigData.cfiles（61行目）で各OS・CPU別のCファイルリストを管理 |
| 1-2 | niminst.nim | `tools/niminst/niminst.nim` | ConfigData.platforms（62行目）で対象プラットフォームを管理 |

**読解のコツ**: cfilesは`array[1..maxOS, array[1..maxCPU, seq[string]]]`の3次元配列で、OS・CPUの組み合わせごとにCファイルリストを保持。

#### Step 2: srcdist関数を理解する

Cソース生成のメイン処理を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | niminst.nim | `tools/niminst/niminst.nim` | srcdist()関数（529-573行目）がメイン処理 |

**主要処理フロー**:
1. **530行目**: getOutputDir()で出力ディレクトリ取得
2. **531行目**: createDir(cCodeDir)
3. **532行目**: gatherFiles()でヘッダをコピー
4. **536-559行目**: OS・CPUループでnimコンパイラ呼び出し
5. **561行目**: deduplicateFiles()で重複排除
6. **562-573行目**: ビルドスクリプト生成

#### Step 3: Nimコンパイラ呼び出しを理解する

コンパイラの呼び出しコマンドを把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | niminst.nim | `tools/niminst/niminst.nim` | 547-550行目でコンパイラコマンドを構築 |

**コンパイルコマンド**:
```nim
var cmd = ("$# compile -f --incremental:off --d:nimKochBootstrap --compileonly " &
           "--gen_mapping --cc:gcc --skipUserCfg" &
           " --os:$# --cpu:$# $# $#") %
           [findNim(), osname, cpuname, c.nimArgs, c.mainfile]
```

#### Step 4: mapping.txt解析を理解する

コンパイラが生成するマッピングファイルの解析を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | niminst.nim | `tools/niminst/niminst.nim` | readCFiles()関数（431-464行目）でmapping.txtを解析 |

**主要処理フロー**:
- **433行目**: mapping.txtのパスを構築
- **444行目**: [cfiles]セクションからCファイルを抽出
- **447-454行目**: [ccompiler]/[linker]セクションの処理

#### Step 5: 重複排除を理解する

SHA1ハッシュによる重複ファイル排除を把握。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | niminst.nim | `tools/niminst/niminst.nim` | deduplicateFiles()関数（482-497行目）で重複排除 |

**主要処理フロー**:
- **489行目**: secureHashFile()でSHA1ハッシュ計算
- **493-494行目**: 同一ハッシュのファイルを削除し、参照に置換

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

```
main()
    │
    └─ [actionCSource] srcdist()
            │
            ├─ getOutputDir() / 出力ディレクトリ取得
            │
            ├─ createDir() / c_codeディレクトリ作成
            │
            ├─ gatherFiles() / ヘッダファイルコピー
            │
            ├─ [OS×CPUループ]
            │       │
            │       ├─ buildDir() / ディレクトリ名生成
            │       │
            │       ├─ createDir() / プラットフォームディレクトリ作成
            │       │
            │       ├─ execShellCmd() / nimコンパイラ呼び出し
            │       │
            │       ├─ readCFiles() / mapping.txt解析
            │       │
            │       └─ copyFile() / Cソースコピー
            │
            ├─ deduplicateFiles() / 重複排除
            │
            ├─ generateBuildShellScript() / build.sh生成
            │
            ├─ generateMakefile() / makefile生成
            │
            ├─ generateBuildBatchScript() / build.bat生成
            │
            └─ writeInstallScripts() / install.sh生成
```

### データフロー図

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

Nimソースコード ─────▶ nimコンパイラ ───▶ Cソース + mapping.txt
       │                                │
       ▼                                ▼
mapping.txt ─────────▶ readCFiles() ───▶ Cファイルリスト
       │                                │
       ▼                                ▼
Cソースファイル ─────▶ copyFile() ───▶ c_code/{os}_{cpu}/
       │                                │
       ▼                                ▼
全Cファイル ──────────▶ deduplicateFiles() ───▶ 重複排除済Cファイル
       │                                │
       ▼                                ▼
ConfigData ──────────▶ generateBuild*() ───▶ build.sh/bat/makefile
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| niminst.nim | `tools/niminst/niminst.nim` | ソース | メインプログラム、srcdist()実装 |
| buildsh.nimf | `tools/niminst/buildsh.nimf` | テンプレート | build.shテンプレート |
| makefile.nimf | `tools/niminst/makefile.nimf` | テンプレート | makefileテンプレート |
| buildbat.nimf | `tools/niminst/buildbat.nimf` | テンプレート | build.batテンプレート |
| install.nimf | `tools/niminst/install.nimf` | テンプレート | install.shテンプレート |
| checksums/sha1 | `dist/checksums/src/checksums/sha1` | ライブラリ | SHA1ハッシュ計算 |
| nim.ini | プロジェクトルート | 設定 | プロジェクト設定ファイル |
