<code>install.rb / setup.rb</code> を使ったパッケージを作る

# `install.rb / setup.rb` を使ったパッケージを作る

## `install.rb` の場合

まず `install.rb` はパッケージが以下のようなディレクトリ構造に なっていることを前提にしています。

>     アーカイブのトップ/
>       install.rb
>       bin/
>           コマンド類
>       lib/
>           Ruby ライブラリ
>       ext/
>           拡張モジュール
>       data/
>           その他のデータ

`bin lib ext data` の下には各々インストールされるイメージそのままに ファイルを配置します。たとえば `lib/tmail/header.rb` というファイルを 置くと `RUBYLIB/tmail/header.rb` としてインストールされます。 `bin/ lib/` などは中身が空のときには省略して構いません。

ただし `ext` だけはちょっと特殊で、複数のファイルからひとつの共有 ライブラリができるので、`.so` ができるべき場所にディレクトリを作り、 その中に必要なファイルを入れます。たとえば `RUBYLIB/ARCH/tmail/scanmail.so` が必要ならば、ディレクトリ `ext/tmail/scanmail/` を作ってその中に `scanmail.c` や `extconf.rb depend MANIFEST` を入れます。

`[`注意] `install.rb / setup.rb` は `MANIFEST` があるディレクトリだけを コンパイル対象にします。拡張モジュールのディレクトリには必ず `MANIFEST` を置いてください。

## `setup.rb` の場合

`setup.rb` の場合は、まずトップに `setup.rb` とディレクトリ `packages/` を置き、その下にパッケージ名のディレクトリを好きなだけおきます。 そしてその中に `install.rb` が要求するのと同じディレクトリツリーを 置きます。つまり以下のようになります。

>     アーカイブのトップ/
>         setup.rb
>         packages/
>             tmail/      # tmail パッケージ
>                 bin/
>                 lib/
>                 ext/
>                 data/
>             raccrt/     # raccrt パッケージ
>                 bin/
>                 :
>             strscan/    # strscan パッケージ
>                 :
>             amstd/      # amstd パッケージ
>                 :

これで `packages/` の下にあるディレクトリ名がそのままパッケージ名となり、 --`with` や --`without` でインストールするパッケージをユーザが選択できる ようになります。

## フックファイル

ファイルを上記のとおり配置しておけばあとは `install.rb / setup.rb` が 自動でそれなりの動作を行ってくれます。具体的には、`setup` のときに 以下のことを実行します。

- `bin/` 以下にあるファイルが `#!` で始まっていてかつプログラムに

文字列 `'ruby'` を含む場合は `#!` 行を --`ruby-path` に置き換える

- 拡張モジュールをコンパイルする

これだけでもたいていの場合には通用します。しかし場合によっては インストール時になにか特別な作業をする必要もあるでしょう。その 場合は特別なファイルを置くことで動作を追加することができます。

たとえば `setup` のタイミングに `lib/tmail/` でなにかをしたいとしたら、 `lib/tmail/pre-setup.rb` を作ってその中にやりたいことを書きます。

>     # pre-setup.rb

>     # racc の文法ファイルをその場でコンパイル (普通、やらない)
>     system "racc #{srcdir_root + '/src/mp.y'} -o mailp.rb"

>     # require 'tmail' で tmail/ の中身を全部 require できるようにする
>     list = Dir.glob(curr_srcdir + '/*.rb').collect {|n| File.basename(n) }
>     File.open( '_loadlib.rb', 'w' ) {|f|
>       f.puts list.collect {|n| "require 'tmail/" + n + "'" }
>     }
>     File.open( '../tmail.rb', 'w' ) {|f|
>       f.puts "require 'tmail/_loadlib'"
>     }

一般には、ディレクトリに入った直後に `pre-TASK.rb` を、 ディレクトリを出る直前に `post-TASK.rb` を実行します。 `TASK` の部分に使えるもの（フック可能なタスク）は `config setup install clean` の四つです。

またフックスクリプトの実行中に例外が起きた場合はインストーラ 全体が即座に失敗します。逆に言うと、処理失敗の時は例外を投げれば よいということです。`exit` はしないでください。

またフックファイルの例で `srcdir_root` や `curr_srcdir` という メソッドを使っていることに注意してください。これは、 `install.rb / setup.rb` には作ったファイルだけを別のディレクトリに 置く仕組みがある（`srcdir` と `objdir` が区別されている）ためです。 この仕組みは、

- 読みこみは常にカレント `srcdir (curr_srcdir)` から
- 書きこみは常にカレント `objdir (curr_objdir` または `".")` に

行うことで達成できます。

`srcdir/objdir` の仕組み

>     archive_top/                  srcdir は変更しないで
>         ext/tmail/scanmail/
>             MANIFEST
>             depend
>             extconf.rb
>             scanmail.c

>     OBJ/                          対応する objdir に作ったものを置く
>         ext/tmail/scanmail/
>             Makefile
>             scanmail.o
>             scanmail.so

この場合 `archive_top/` を「`srcdir` のルート」、 `OBJ/` を「`objdir` のルート」と言います。 また `archive_top/ext/tmail/scanmail/` を「カレント `srcdir`」、 `OBJ/ext/tmail/scanmail/` を「カレント `objdir`」と呼びます。

こうしておくと、`srcdir` に対しては読み出ししか行われないので、 `clean` などしなくても常に `srcdir` を最小限のファイルのきれいな 状態に保てます。またマニアックなところでは複数のクロスコンパイルを 同時に行ったりもできるようになります。そこまでいかなくとも、 コンパイルオプションだけを変えていくつものバージョンを作ったりする ことはあるでしょう。この仕組みはそのような場合に便利なのです。

`srcdir/objdir` 対応は絶対必要というわけではありませんが、対応して おいて損はありません。

また `curr_srcdir` や `srcdir_root` などフックファイル中で使用可能な `API` については別ページの フック `API` リファレンス を参照してください。

## メタコンフィグ

`install.rb / setup.rb` では、`config` のタスクオプションを 後付けで増やすことができます。このためにはまず、`install.rb` を 置くのと同じディレクトリに `metaconfig` というファイルを作ります。 そしてこの中にたとえば以下のような Ruby スクリプトを書きます。

>     add_path_config 'libc', '/lib/libc.so', 'path to the C standard library'
>     add_bool_config 'win32', false, 'compile with Win32 support'

これで、パスを指定するオプション --`libc` と、真偽値を取る オプション--`win32` が追加され、以下のように `config` に与える ことができるようになります。

>     ruby install.rb config --libc=/lib/libc-devel.so --win32

また `install.rb --help` にも自動的に表示されます。

`metaconfig` で使える `API` については metaconfig API Reference Manual を参照してください。

## 以前のバージョンとの互換性

インストーラというものの特殊性を考え、 互換性はまったく保っていません。`2.0` 以前とは別物と思ってください。 前バージョンの動作が必要ならばそのバージョンを使いましょう。 以前のバージョンとは以下の点で非互換です。

- ディレクトリ構造が完全に違う
- `PATHCONV` がない
- `share/` → `data/`
- フックの形式が違う
- `dryrun` コマンドがない → --`prefix` 使ってインストールしてください。

## ライセンスについて

`install.rb / setup.rb` 自体は `GNU Lesser General Public License` `(LGPL) version 2` に従って配布します。詳細はファイル `LGPL` を見て ください。また、`install.rb / setup.rb` を使ってインストールする プログラムが `LGPL` である必要は全くありません。完全にユーザの自由です。

## インストールマニュアル

このアーカイブに含まれている `usage.{txt,html}` は自由にコピー・編集 して自分のパッケージに使ってください。`Copyright` 表示が入って いますが、これは単に自動化が楽だから入っているだけなので消しても 構いません。