# 機能設計書 140-GMP_jll

## 概要

本ドキュメントは、Julia の `GMP_jll` パッケージによる GMP（GNU Multiple Precision）ライブラリの JLL バイナリラッパーについて、その設計・処理仕様を記述するものである。

### 本機能の処理概要

`GMP_jll` は、GMP（GNU Multiple Precision Arithmetic Library）の共有ライブラリ（libgmp / libgmpxx）を Julia から利用するための JLL（Julia Library Linking）パッケージである。プラットフォーム固有のライブラリパス解決、遅延ロード、依存ライブラリ管理を提供する。

**業務上の目的・背景**：Julia の BigInt 型（任意精度整数演算）は GMP ライブラリに依存している。GMP_jll は、この外部 C ライブラリを Julia のパッケージシステムに統合し、プラットフォーム間の差異を吸収してシームレスなライブラリアクセスを提供する。

**機能の利用シーン**：BigInt 演算時の内部的な GMP 関数呼び出し、ccall による GMP 関数の直接利用、GMP に依存する他の JLL パッケージ（MPFR_jll 等）からの利用。

**主要な処理内容**：
1. `libgmp` / `libgmpxx` の `LazyLibrary` による遅延ライブラリパス解決
2. プラットフォーム固有のライブラリファイル名選択（.dll / .dylib / .so）
3. `CompilerSupportLibraries_jll` への依存管理（非 macOS プラットフォーム）
4. `eager_mode()` による即時ライブラリロード
5. `__init__()` によるライブラリパスとアーティファクトディレクトリの設定
6. `is_available()` によるライブラリ利用可能性チェック

**関連システム・外部連携**：GMP C ライブラリ、CompilerSupportLibraries_jll（libstdcxx / libgcc_s）、Libdl（動的ライブラリロード）、base/gmp.jl（BigInt 実装）。

**権限による制御**：特に権限による制御はない。

## 関連画面

本機能は特定の画面との紐付けはない。

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | BigInt 演算時に内部的に利用される |

## 機能種別

ライブラリ連携 / パッケージ管理

## 入力仕様

### 入力パラメータ

本モジュールは直接のユーザー入力を受け取らない。システム情報とプラットフォームに基づいて自動的にライブラリパスを解決する。

### 入力データソース

`Sys.iswindows()` / `Sys.isapple()` / `Sys.isfreebsd()` によるプラットフォーム検出、`Sys.BINDIR` によるインストールパスの取得。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| libgmp | LazyLibrary | GMP C ライブラリへのハンドル |
| libgmpxx | LazyLibrary | GMP C++ ライブラリへのハンドル |
| libgmp_path | String | libgmp のファイルシステムパス |
| libgmpxx_path | String | libgmpxx のファイルシステムパス |
| artifact_dir | String | アーティファクトディレクトリのパス |

### 出力先

モジュールのグローバル変数として公開。`ccall` でライブラリハンドルとして使用。

## 処理フロー

### 処理シーケンス

```
1. モジュール定義（baremodule GMP_jll）
   └─ baremodule により最小限のスコープで定義
2. LazyLibrary によるライブラリパス設定
   └─ プラットフォーム判定に基づくライブラリファイル名の選択
3. 依存関係の設定
   └─ libgmpxx は libgmp と CompilerSupportLibraries_jll のライブラリに依存
4. __init__() の実行
   └─ libgmp_path / libgmpxx_path / artifact_dir / LIBPATH の設定
5. eager_mode() の呼び出し（必要時）
   └─ dlopen で即時ロード
```

### フローチャート

```mermaid
flowchart TD
    A["GMP_jll モジュール定義"] --> B{"Sys.isapple()?"}
    B -->|Yes| C["CompilerSupportLibraries_jll 不使用"]
    B -->|No| D["using CompilerSupportLibraries_jll"]
    C --> E["LazyLibrary(libgmp) 設定"]
    D --> E
    E --> F{"プラットフォーム判定"}
    F -->|Windows| G["libgmp-10.dll"]
    F -->|macOS| H["libgmp.10.dylib"]
    F -->|Linux等| I["libgmp.so.10"]
    G --> J["LazyLibrary(libgmpxx) 設定"]
    H --> J
    I --> J
    J --> K["__init__() でパス設定"]
    K --> L["モジュール使用可能"]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-140-01 | プラットフォーム依存ファイル名 | Windows: .dll、macOS: .dylib、その他: .so | ライブラリロード時 |
| BR-140-02 | macOS CSL 不要 | macOS では CompilerSupportLibraries_jll を使用しない | Sys.isapple() |
| BR-140-03 | libgmpxx 依存 | libgmpxx は libgmp と CSL ライブラリ（libstdcxx / libgcc_s）に依存 | 非 macOS |
| BR-140-04 | FreeBSD 特殊依存 | FreeBSD では libgmpxx は libgmp と libgcc_s のみに依存 | Sys.isfreebsd() |
| BR-140-05 | 遅延ロード | ライブラリは LazyLibrary で遅延ロードされる | デフォルト |
| BR-140-06 | バージョン | GMP バージョン 6.3.0+2 | 常時 |

### 計算ロジック

特になし。

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

本機能はデータベース操作を行わない。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | dlopen エラー | ライブラリファイルが見つからない | Julia のインストールを確認 |
| - | 依存解決エラー | CompilerSupportLibraries_jll が利用不可 | パッケージの再インストール |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- LazyLibrary による遅延ロードで起動時間を最小化
- precompile でeager_mode / is_available を事前コンパイル（65-67行目）
- dlopen は初回呼び出し時のみ実行される

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

- バンドルされたバイナリはチェックサムで検証済み
- dlopen は Julia インストールディレクトリ内のライブラリのみをロード

## 備考

- `baremodule` で定義されているため、Base の名前空間汚染を避けている
- `BundledLazyLibraryPath` は Julia インストールディレクトリからの相対パスを解決する
- GMP は BigInt 演算の基盤であり、Julia のコア機能に不可欠なライブラリ
- MPFR_jll（BigFloat 用）は GMP_jll に依存している

---

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

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

### 推奨読解順序

#### Step 1: モジュール構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **4行目**: `baremodule GMP_jll` -- baremodule による最小スコープ定義 |
| 1-2 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **5-8行目**: using Base, Libdl, CompilerSupportLibraries_jll（条件付き） |
| 1-3 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **10行目**: `export libgmp, libgmpxx` |

**読解のコツ**: `baremodule` は `using Base` を暗黙的に行わない最小モジュール。JLL パッケージではモジュールの軽量化のために使用される。`@static if` でプラットフォーム固有のコードを選択する。

#### Step 2: ライブラリパス定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **20-28行目**: `libgmp` の LazyLibrary 定義 -- プラットフォーム別ファイル名 |
| 2-2 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **31-46行目**: `libgmpxx` の LazyLibrary 定義 -- 依存ライブラリの設定 |

**主要処理フロー**:
- **20-28行目**: libgmp は BundledLazyLibraryPath で定義。Windows/macOS/Linux で異なるファイル名
- **31-46行目**: libgmpxx は libgmp に依存。さらにプラットフォームに応じて libstdcxx / libgcc_s にも依存

#### Step 3: 初期化とユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **48-54行目**: `eager_mode()` -- CSL の eager_mode + libgmp/libgmpxx の dlopen |
| 3-2 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **55行目**: `is_available() = true` |
| 3-3 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **57-63行目**: `__init__()` -- パスとディレクトリの設定 |
| 3-4 | GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | **65-68行目**: precompile 対象の宣言 |

#### Step 4: パッケージメタデータを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Project.toml | `stdlib/GMP_jll/Project.toml` | **1-3行目**: パッケージ名・UUID・バージョン (6.3.0+2) |
| 4-2 | Project.toml | `stdlib/GMP_jll/Project.toml` | **5-8行目**: 依存パッケージ（Artifacts, CSL_jll, Libdl） |

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

```
GMP_jll
    |
    +-- libgmp (LazyLibrary)
    |       +-- BundledLazyLibraryPath("libgmp-10.dll" / "libgmp.10.dylib" / "libgmp.so.10")
    |
    +-- libgmpxx (LazyLibrary)
    |       +-- BundledLazyLibraryPath("libgmpxx-4.dll" / "libgmpxx.4.dylib" / "libgmpxx.so.4")
    |       +-- dependencies:
    |               +-- libgmp
    |               +-- [非macOS] libstdcxx (CSL_jll)
    |               +-- [非macOS] libgcc_s (CSL_jll)
    |
    +-- eager_mode()
    |       +-- CompilerSupportLibraries_jll.eager_mode() [非macOS]
    |       +-- dlopen(libgmp)
    |       +-- dlopen(libgmpxx)
    |
    +-- __init__()
    |       +-- libgmp_path = string(libgmp.path)
    |       +-- libgmpxx_path = string(libgmpxx.path)
    |       +-- artifact_dir = dirname(Sys.BINDIR)
    |       +-- LIBPATH / LIBPATH_list の設定
    |
    +-- [利用側] base/gmp.jl
            +-- ccall((:__gmpz_init, libgmp), ...)
```

### データフロー図

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

Sys.iswindows()         --> プラットフォーム判定
Sys.isapple()               +-- ファイル名選択         --> LazyLibrary パス
Sys.isfreebsd()             +-- 依存ライブラリ選択

LazyLibrary パス         --> dlopen (初回アクセス時)    --> ライブラリハンドル

ccall((:func, libgmp))  --> ハンドル経由で C 関数呼出  --> GMP 計算結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| GMP_jll.jl | `stdlib/GMP_jll/src/GMP_jll.jl` | ソース | GMP_jll モジュールの全実装 |
| Project.toml | `stdlib/GMP_jll/Project.toml` | 設定 | パッケージメタデータ（バージョン・依存関係） |
| runtests.jl | `stdlib/GMP_jll/test/runtests.jl` | テスト | GMP_jll のテスト |
| gmp.jl | `base/gmp.jl` | ソース | BigInt 実装（GMP_jll の主要利用者） |
| gmp.mk | `deps/gmp.mk` | ビルド | GMP ライブラリのソースビルドルール |
| gmp.version | `deps/gmp.version` | 設定 | GMP のバージョン番号 |
