試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

シェルスクリプトで自己展開するmakeself

Eawplus音色セットのインストーラを作成」のスクリプトで既に使用しているが、makeself(http://www.megastep.org/makeself/)は、自己展開型の圧縮ファイルを作成するシェルスクリプト。中に含まれる実行ファイルを自動で実行させることも可能で、インストーラを作るのに使える。NVIDIAのグラフィックドライバの配布ファイルなどでも実際に使用されている。
チェックサムのデータを保持しているため、ファイルの中身が正常かどうかを展開時に確かめることもできる。
Debianパッケージの紹介文も参考になる。

ディストリのパッケージと実行ファイル名について

Gentoo/Debian/Ubuntuのいずれにも「makeself」という名前のパッケージが存在する。
実行ファイル名は、Gentooではmakeself.shDebian/Ubuntuではmakeselfとなっている。

使用方法

完全な使用方法はマニュアルページを参照(man makeself)。

$ makeself (オプション) [最上位ディレクトリ] [圧縮ファイル名] [ラベル] (自動起動スクリプトとその引数)

ラベルは展開時に名前として使用される*1が、半角スペースを含む場合はダブルクォートで囲む必要がある。
Eawplus音色セットのインストーラを作成」で作成したデモでは「Eawplus (GUS/patch collection based on Eawpatches)」と表示されている。
自動起動スクリプトについては、

  • スクリプトに実行属性がないと、展開したところでスクリプトを実行できずに止まってしまうため、圧縮前に付けておく
  • makeself実行時の指定の形としては、最上位ディレクトリにスクリプトinstall.shがある場合に「./install.sh」という形になる

という点に注意。

圧縮方式

既定ではtar+gzipだが、--bzip2オプションを付けることでtar+bz2で圧縮することもできる。
.runファイルそのものはシェルスクリプトなので、(広い意味での)UNIX系環境の上であれば、基本的にどこでも動作する。

ヘッダスクリプト

.runファイルの先頭にあるシェルスクリプト部分には、後ろのバイナリ(非テキスト)データ部分を展開するためのコードが含まれている。このヘッダスクリプト部分はある程度変更可能で、オプションを追加したり独自の処理を追加したりできる。NVIDIAドライバのインストーラはこのスクリプト部分が独自に修正されたものとなっている。
変更された独自のヘッダスクリプトを指定するには--header [ヘッダスクリプト]で場所を指定する。
既定のヘッダスクリプトは、本体に同梱されているmakeself-header(.sh)の内容。

一時ディレクトリへの展開をしない(自己展開書庫として展開するだけ)

(2008/3/30)既定では、データは一時ディレクトリに展開され、処理終了後に消される。これはインストーラを作成する場合に便利だが、自己展開書庫としてデータを展開するだけの場合は困る。その場合、--notempオプションを付け、処理部分は空にする。

$ makeself --notemp [最上位ディレクトリ] [.runファイル] [ラベル]

runファイルを実行しないと展開できない?

一般的な自己展開書庫の展開の場合

自己展開書庫というのは、実行ファイルとしてOSやCPUアーキテクチャに依存するものであっても、(形式さえ合えば)それに関係なく開ける場合が多い。

この他に、7z形式の自己展開書庫でも

$ 7z a test.exe -sfx [ファイルやディレクトリ]
$ file test.exe
test.exe: ELF 64-bit LSB executable, x86-64, ...

普通の7zファイルと同様に展開できる。

$ 7z x test.exe
makeselfのファイルは特殊

ところが、makeselfの出力するファイルは「シェルスクリプト + データ」という特殊な形式で、これを扱う方法を知っているツールでないと、.runファイルを直接実行せず、中に入れられたファイルだけを取り出すことは、そのままではできない。
そこで作られたツールがunmakeselfというツール*2で、Gentoo Linuxではパッケージになっているが、他のディストリではパッケージになっていないことが多い。
使い方としては、

$ unmakeself [.runファイル]

で現在のディレクトリ以下にデータが展開される。
また、Gentoo LinuxPortageでは、${PORTDIR}*3/eclass/eutils.eclassunpack_makeself()という関数が.runファイルを展開している。

unmakeselfの手動インストール

事前にlibarchiveの他、bzip2とgzipのサポートライブラリも必要。Debian/Ubuntuでは

  • libarchive-dev
  • libbz2-dev
  • zlib1g-dev

が必要。

バージョン1.0を入れる

Gentoo Linuxのパッケージは、2008年3月現在、バージョン1.0のみを提供している。下はインストール例。

$ wget http://gentooexperimental.org/~genstef/dist/unmakeself-1.0.tar.bz2
$ tar jxf unmakeself-1.0.tar.bz2
$ cd unmakeself-1.0/
$ gcc -O2 -pipe unmakeself.c -larchive -lbz2 -lz -o unmakeself
$ sudo install -s unmakeself /usr/local/bin/

ダウンロードするソースファイルunmakeself-1.0.tar.bz2の情報は

  • ファイルサイズ: 3,015バイト
  • MD5: 571052bca15a041f195ed260bd3a0631
  • SHA-1: 1197d7b1951254646f9c83567d3f79fa4d5c9c81

となっている。ファイル名でWeb検索するとGentoo Linuxの別のミラーサーバが見つかるが、そこから入手することもできる。

バージョン1.1に関して

インストールの流れは下のようになるが

$ wget -O unmakeself.tar.gz "http://cvsweb.freebsd.org/ports/archivers/unmakeself/unmakeself.tar.gz?tarball=1"
$ tar zxf unmakeself.tar.gz
$ cd unmakeself/files/
$ echo "#define HAS_MEMMEM" > config.h
$ gcc -O2 -pipe unmakeself.c -larchive -lbz2 -lz -o unmakeself
$ sudo install -s unmakeself /usr/local/bin/

これで.runファイルを展開しようとすると

[実行したコマンド行]: lseek() error: 無効な引数です

となる場合がある。同じファイルをバージョン1.0で展開すると正常に処理できるため、バージョン1.0のほうがよさそうな気がする。

使用したバージョン:

  • makeself 2.1.4
  • unmakeself 1.0, 1.1

*1:端末上に加え、X上の端末エミュレータのタイトルとしても表示される

*2:元々はFreeBSDのツールっぽい。C言語で書かれているためコンパイルしないと使えない

*3:既定は/usr/portage