# バッチ設計書 31-delete-all-rpaths.sh

## 概要

本ドキュメントは、macOS（Darwin）環境においてMach-Oバイナリから全てのLC_RPATH（ランタイムライブラリ検索パス）エントリを削除するシェルスクリプト `contrib/delete-all-rpaths.sh` のバッチ設計書である。

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

本バッチは、macOS上でJuliaのバイナリ配布物やフレームワークパッケージを作成する際に、既存のRPATHを全て除去し、新しいRPATHを正確に設定するための前処理として使用されるユーティリティスクリプトである。

**業務上の目的・背景**：macOSではダイナミックリンクライブラリの検索パスとしてRPATH（`@rpath`）が使用される。ビルド環境で設定されたRPATHがそのまま配布バイナリに残ると、ユーザー環境で正しくライブラリを解決できない、あるいはセキュリティ上の問題（意図しないパスからライブラリがロードされる）が発生する。本スクリプトはビルド時に付与されたRPATHを全て削除し、配布用に適切なRPATHを再設定する際のクリーンアップ処理を担う。特にmacOSフレームワーク形式でのJulia配布において不可欠な工程である。

**バッチの実行タイミング**：JuliaのmacOSフレームワークビルド時（`contrib/mac/framework/Makefile`のframeworknoinstallターゲット実行時）に、`make install`完了後の後処理として実行される。手動でも実行可能。

**主要な処理内容**：
1. 実行環境がDarwin（macOS）であることを検証する
2. 引数として渡されたバイナリファイル群からシンボリックリンクを除外する
3. 各バイナリに対して`otool -l`でLC_RPATHエントリを列挙する
4. 正規表現でRPATHのパスを抽出し、`install_name_tool -delete_rpath`で各RPATHを削除する

**前後の処理との関連**：本スクリプトは`contrib/mac/framework/Makefile`内のframeworknoinstallターゲットにおいて、`install_name_tool -add_rpath`による新しいRPATH設定の直前に実行される。前提として`make install`によるバイナリのインストールが完了している必要がある。後続処理として`contrib/fixup-libgfortran.sh`によるlibgfortranの修正が実行される。

**影響範囲**：処理対象のMach-Oバイナリファイルのヘッダ情報（LC_RPATHセクション）が変更される。対象にはjuliaバイナリ、libjuliaダイナミックライブラリ、sys.dylib、および各種フレームワークライブラリが含まれる。

## バッチ種別

ユーティリティ処理（バイナリ後処理）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（ビルド・リリース時） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | macOSフレームワークビルド時にMakefileから自動呼出し、または手動実行 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| macOS（Darwin）環境 | `uname`コマンドがDarwinを返す環境でのみ実行可能 |
| otoolの利用可能性 | Xcode Command Line Toolsがインストールされていること |
| install_name_toolの利用可能性 | Xcode Command Line Toolsがインストールされていること |
| 対象バイナリの存在 | 処理対象のMach-Oバイナリが引数として1つ以上指定されること |

### 実行可否判定

1. `uname`コマンドの結果がDarwinでない場合、エラーメッセージを出力して終了（exit 1）
2. 引数が1つ未満の場合、使用方法を出力して終了（exit 1）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| lib1 [lib2 ...] | ファイルパス（可変長） | Yes | なし | RPATHを削除する対象のMach-Oバイナリファイルパス（1つ以上） |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| Mach-Oバイナリファイル | バイナリ | 引数で指定されたダイナミックライブラリまたは実行ファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 対象バイナリファイル（インプレース更新） | バイナリ | LC_RPATHエントリが削除されたMach-Oバイナリ |
| 標準出力 | テキスト | 削除したRPATHの情報（ファイル名、削除パス） |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 入力と同一（インプレース更新） |
| 出力先 | 入力と同一パス |
| 文字コード | N/A（バイナリファイル） |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. 環境チェック
   └─ unameでDarwinかどうかを判定。Darwin以外ならエラー終了
2. 引数チェック
   └─ 引数が1つ未満ならusageを出力してエラー終了
3. シンボリックリンクフィルタリング
   └─ 引数のファイル群からシンボリックリンクを除外してLIBS変数に格納
4. RPATHの列挙と削除（各バイナリについてループ）
   4.1 otool -l でMach-Oヘッダのロードコマンドを取得
   4.2 grep LC_RPATH -A2 でLC_RPATHセクションを抽出
   4.3 正規表現でpathフィールドを抽出
   4.4 install_name_tool -delete_rpath で該当RPATHを削除
   4.5 削除情報を標準出力に表示
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{uname = Darwin?}
    B -->|No| C[エラー: Requires Darwin]
    B -->|Yes| D{引数 >= 1?}
    D -->|No| E[エラー: usage表示]
    D -->|Yes| F[引数からシンボリックリンクを除外]
    F --> G[各バイナリについてループ開始]
    G --> H[otool -l でロードコマンド取得]
    H --> I[LC_RPATHエントリを抽出]
    I --> J{RPATHあり?}
    J -->|Yes| K[install_name_tool -delete_rpath で削除]
    K --> L[削除情報を出力]
    L --> J
    J -->|No| M{次のバイナリあり?}
    M -->|Yes| G
    M -->|No| N[バッチ終了]
    C --> O[終了 exit 1]
    E --> O
```

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

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

本バッチはデータベースを使用しない。対象はファイルシステム上のMach-Oバイナリファイルのみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| exit 1 | 環境エラー | macOS以外の環境で実行 | macOS環境で再実行する |
| exit 1 | 引数エラー | 引数が0個 | 対象バイナリファイルを引数に指定して再実行 |
| N/A | install_name_tool失敗 | 対象ファイルが書き込み不可、またはコード署名済み | ファイルのパーミッションを確認、またはcodesign --remove-signatureで署名除去後に再実行 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ機構未実装） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

バッチ失敗時は、対象バイナリの一部のみRPATHが削除された不整合状態となる可能性がある。`make install`からやり直し、再度スクリプトを実行することで復旧する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | ファイル単位（各バイナリのRPATH削除は個別に実行） |
| コミットタイミング | 各`install_name_tool`コマンド実行時に即時反映 |
| ロールバック条件 | ロールバック機構なし。`make install`からの再実行が必要 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 数個〜数十個のバイナリファイル |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 特に制約なし（otoolとinstall_name_toolのメモリ使用量に依存） |

## 排他制御

同一バイナリに対して複数のinstall_name_toolプロセスが同時に実行されないことが前提。Makefileの依存関係により順序制御される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | 各RPATH削除時 | `{ファイル名} deleting rpath {パス} "{フルパス}"` |
| エラーログ | 環境チェック失敗時 | `Requires Darwin.` |
| エラーログ | 引数チェック失敗時 | `usage: delete-all-rpaths.sh lib1 [lib2 ...]` |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 0以外 | ビルドプロセス（Makefileが検出） |

## 備考

- 本スクリプトはmacOS固有のツール（`otool`、`install_name_tool`）に依存しており、Linux/Windowsでは使用できない。
- シンボリックリンクは自動的にスキップされる。これはシンボリックリンク先の実体ファイルが別途処理されることを前提としている。
- `contrib/mac/framework/Makefile`では、本スクリプトで全RPATHを削除した後、`install_name_tool -add_rpath`で配布用の適切なRPATH（`@executable_path/...`や`@loader_path/...`）を再設定する構成になっている。
