packagemakerコマンドでインストーラをつくる
この記事は Mac Dev JP Advent Calendar の参加記事(17日目)です。
今日は私が開発に参加しているRubyCocoaをモデルに、packagemakerコマンドでインストーラパッケージを作成する手順を紹介します。
PackageMakerとは
PackageMakerは「インストーラ」アプリケーションでインストールするときに使う、.pkgや.mpkgといったパッケージを作成するソフトウェアです。
通常のアプリケーションはインストーラでなく、ディスクイメージなどの中に.appファイルを入れておき、ユーザが自由に配置できるようにしておくのが一般的です。インストーラを使用したインストールが適しているのは、「決められた位置にファイルをインストールする」ことが求められる場合です。たとえば、
- 環境設定パネル(.prefPane) - Library/PreferencePanes/
- かな漢字変換などのインプットメソッド(.app) - Library/Input Methods/
- サービス(.app, .service) - Library/Services/
- 汎用のフレームワーク(.framework) - Library/Frameworks/
- 多数のファイルをそれぞれ配置する(Xcode, MacPortsなど)
などです。これらを配布するときは、ユーザに適切な場所にコピーするよう依頼するよりも、インストーラで自動的に決められた場所に配置されるようになっているほうが親切ってもんです。
GUIでなくコマンドを使う理由
PackageMakerにはここで紹介するコマンドの他に、GUIのアプリケーションがあります。というかそちらが本家です。
一般論ではありますが、コマンドのほうが自動化や繰り返しのオペレーションに適しています。これはPackageMakerにもあてはまり、RubyCocoaでは2006年ごろからリリース用のインストーラの作成は以下のコマンド一発になっています。
% ruby install.rb package # または rake package
packagemakerコマンドの使い方
なにはともあれmanです。packagemaker(1)。最後にあるEXAMPLESを見ると感じがつかめるのではないかと思います。
- packagemaker -root: 新しい書き方(10.5-)
- packagemaker -build: 古い書き方(-10.4) manの下のほう
どちらでもインストーラを同様に作成できますが、10.5以降の1ファイル(バンドルでなくフラット)のインストーラは新しい書き方でしか作成できません。新スタイルのほうは.pkgが単一のファイルとなるため、配布に.dmgや.zipで固めなくてもよい、署名できるというメリットがあります。
フラットな.pkg
% ls -l InstallXcodeLion.pkg -rw-r--r-- 1 kimuraw staff 3189834552 Jul 19 12:08 /Volumes/Install Xcode/InstallXcodeLion.pkg % xar -t -f InstallXcodeLion.pkg Distribution InstallXcodeLion.pkg InstallXcodeLion.pkg/Bom InstallXcodeLion.pkg/PackageInfo InstallXcodeLion.pkg/Payload Resources Resources/English.lproj Resources/English.lproj/License.rtf Resources/English.lproj/Localizable.strings
バンドル形式の.pkg
% ls -la RubyCocoa-1.0.2-OSX10.7.pkg total 0 drwxr-xr-x 3 kimuraw staff 102 Dec 17 14:29 ./ drwxr-xr-x 6 kimuraw staff 204 Dec 17 14:29 ../ drwxr-xr-x 7 kimuraw staff 238 Dec 17 14:29 Contents/
RubyCocoaでは古い書き方のころにパッケージスクリプトを作成して、そのまま問題も起きてないということで、そのままになっています。
実際の使用
- インストールするファイル
- ReadMe, Licenseなどのインストーラに表示する内容
- Info.plist
- Description.plist
これらを用意して、packagemakerコマンドで.pkgファイルを作成します。
Info.plist
Info.plistではバージョンや識別子のほかに、インストールに必要な要件を指定することができます。たとえば、RubyCocoaではインストールできるシステムのバージョンを制限しています。
<key>IFRequirementDicts</key> <array> <dict> <key>SpecArgument</key> <string>/System/Library/CoreServices/SystemVersion.plist</string> <key>SpecProperty</key> <string>ProductVersion</string> <key>SpecType</key> <string>plist</string> <key>TestObject</key> <string>10.7</string> <key>TestOperator</key> <string>>=</string> </dict> <dict> <key>SpecArgument</key> <string>/System/Library/CoreServices/SystemVersion.plist</string> <key>SpecProperty</key> <string>ProductVersion</string> <key>SpecType</key> <string>plist</string> <key>TestObject</key> <string>10.8</string> <key>TestOperator</key> <string><</string> </dict> </array>
残念ながら現在のAppleのドキュメントにはこれらの詳細は記載されていません。TigerやLeopardごろのドキュメントにはあったと思います。
コマンド実行
それぞれ用意したらあとはコマンドの実行です。
% packagemaker -build \ -p work/RubyCocoa-1.0.2-OSX10.7/RubyCocoa-1.0.2-OSX10.7.pkg \ -f work/files \ -r work/resources \ -i work/Info.plist \ -d work/Description.plist
終わりに
こんかいこの記事を書くにあたって、新しい-rootオプションを使用したコマンドも試してみたのですが、ReadMeやLicenseを表示させる手順がわかりませんでした(-resourcesに指定した場所に置いてもダメ)。ご存知の方は教えてください!
新しいpkgbuildコマンドについても知りたいです!