productbuildによるインストーラ作成
この記事は、2011年12月の「packagemakerコマンドでインストーラをつくる」の改訂版です。
Package MakerがDEPRECATEDになってしまったので、こないだRubyCocoaのインストーラ作成をproductbuildに移行しました。ついでなので、その際に調べたことなどをまとめておきます。
インストーラを使う理由(前回のコピペ)
通常のアプリケーションはインストーラでなく、ディスクイメージなどの中に.appファイルを入れておき、ユーザが自由に配置できるようにしておくのが一般的です。インストーラを使用したインストールが適しているのは、「決められた位置にファイルをインストールする」ことが求められる場合です。たとえば、
- 環境設定パネル(.prefPane) - Library/PreferencePanes/
- かな漢字変換などのインプットメソッド(.app) - Library/Input Methods/
- サービス(.app, .service) - Library/Services/
- 汎用のフレームワーク(.framework) - Library/Frameworks/
- 多数のファイルをそれぞれ配置する(Xcode, MacPortsなど)
などです。これらを配布するときは、ユーザに適切な場所にコピーするよう依頼するよりも、インストーラで自動的に決められた場所に配置されるようになっているほうが親切ってもんです。
インストーラファイルの中身
インストーラファイル(.pkg)がどのようになっているかを見てみます。旧来の.pkgはディレクトリでその中にさまざまなファイルが配置されていましたが、現在では単一のファイルになっています。
% ls -la RubyCocoa-1.0.7-OSX10.9.pkg -rw-r--r--@ 1 kimuraw staff 1614451 Oct 26 20:52 RubyCocoa-1.0.7-OSX10.9.pkg
最近ではこの手のファイルは単一ファイルと見せかけてzipでパッケージしたものが多かったりしますが、これはどうでしょう。
% file RubyCocoa-1.0.7-OSX10.9.pkg RubyCocoa-1.0.7-OSX10.9.pkg: xar archive version 1, SHA-1 checksum
xarで固めたファイルのようですね。じゃあxarコマンドを使って中身を見てみましょう。
% xar -tvf RubyCocoa-1.0.7-OSX10.9.pkg drwx------ root/wheel 0 1970-01-01 00:00:00 RubyCocoa-1.0.7-OSX10.9.pkg -rw-r--r-- kimuraw/staff 250682 2013-10-26 11:52:18 RubyCocoa-1.0.7-OSX10.9.pkg/Bom -rw-r--r-- kimuraw/staff 1548524 2013-10-26 11:52:18 RubyCocoa-1.0.7-OSX10.9.pkg/Payload ?????????? unknown/unknown 7664 1970-01-01 00:00:00 RubyCocoa-1.0.7-OSX10.9.pkg/PackageInfo drwx------ root/wheel 0 1970-01-01 00:00:00 Resources drwx------ root/wheel 0 1970-01-01 00:00:00 Resources/en.lproj ?????????? unknown/unknown 2817 1970-01-01 00:00:00 Resources/en.lproj/ReadMe.html drwx------ root/wheel 0 1970-01-01 00:00:00 Resources/ja.lproj ?????????? unknown/unknown 3932 1970-01-01 00:00:00 Resources/ja.lproj/ReadMe.html ?????????? unknown/unknown 2552 1970-01-01 00:00:00 Resources/License.txt ?????????? unknown/unknown 5434 1970-01-01 00:00:00 Distribution
概ね以前の形式と同じようなものが入っていますね。Payloadが配布物の実体で、Bomにファイルリストが入っているのでしょう。
productbuildによる.pkg作成
DEPRECATED: Package Maker app.と、Xcodeのリリースノートあるように、productbuildコマンドが新しいインストーラ作成ツールになります。
Use the productbuild command to create installer packages
こういったApple独自のツール(xcodebuildやibtoolとか)はmanの最後に"EXAMPLES"として使用例が書いてあることが多いので、そこをまず見るのがおすすめです。
EXAMPLES productbuild --component build/Release/Sample.app /Applications Product.pkg Build the archive Product.pkg to install Sample.app under /Applications, synthesizing a distri-bution. distribution. bution. This is typical for building a Mac App Store archive. productbuild --product def.plist --component \ build/Release/Sample.app /Applications Product.pkg : productbuild --distribution Product.dist --resources Resources Product.pkg :
オプションを指定して、最後に出力する(もしくは更新する)Product.pkgファイル名を書くということのようです。ちょっと試しにやってみましょう。アプリを用意するのもめんどうなので、テキストエディットをパッケージしちゃいましょう。
% productbuild --component /Applications/TextEdit.app TextEdit.pkg productbuild: Adding component at /Applications/TextEdit.app productbuild: Inferred install-location of /Applications productbuild: Wrote product to TextEdit.pkg productbuild: Supported OS versions: [10.8, ) % ls -la TextEdit.pkg -rw-r--r-- 1 kimuraw staff 7147430 Oct 29 19:59 TextEdit.pkg % xar -tvf TextEdit.pkg drwx------ root/wheel 0 1970-01-01 00:00:00 com.apple.TextEdit.pkg -rw-r--r-- kimuraw/staff 186384 2013-10-29 10:59:13 com.apple.TextEdit.pkg/Bom -rw-r--r-- kimuraw/staff 7102446 2013-10-29 10:59:13 com.apple.TextEdit.pkg/Payload ?????????? unknown/unknown 934 1970-01-01 00:00:00 com.apple.TextEdit.pkg/PackageInfo drwx------ root/wheel 0 1970-01-01 00:00:00 Resources drwx------ root/wheel 0 1970-01-01 00:00:00 Resources/ar.lproj ?????????? unknown/unknown 25 1970-01-01 00:00:00 Resources/ar.lproj/Localizable.strings : % xar -xvf TextEdit.pkg com.apple.TextEdit.pkg/Bom com.apple.TextEdit.pkg/Bom % lsbom com.apple.TextEdit.pkg/Bom . 0 0/0 ./TextEdit.app 40755 0/0 ./TextEdit.app/Contents 40755 0/0 ./TextEdit.app/Contents/Info.plist 100644 0/0 7868 477219676 ./TextEdit.app/Contents/MacOS 40755 0/0 ./TextEdit.app/Contents/MacOS/TextEdit 100755 0/0 174640 1115714015 ./TextEdit.app/Contents/PkgInfo 100644 0/0 8 842486447 :
ちゃんと、TextEdit.appのインストーラが作成されたようですね。あとはEXAMPLESとmanを見ながらほしいオプションを足していけばお好みのインストーラが作成できます。
たとえば、--product オプションで指定したplistファイルでは
などを指定することができます。詳細はmanの"PRE-INSTALL REQUIREMENTS PROPERTY LIST"を参照してください。
また、Macのバンドル形式(.appなど)でないファイルはproductbuildではパッケージすることはできません。
% productbuild --component ~/.vim vimdir.pkg productbuild: error: The component at "/Users/kimuraw/.vim" is not a bundle.
そういったファイルをインストーラとして作成したい場合は、pkgbuildコマンドの--rootオプションを使います。
% pkgbuild --root ~/.vim --identifier kimuraw vimdir.pkg pkgbuild: Inferring bundle components from contents of /Users/kimuraw/.vim pkgbuild: Wrote package to vimdir.pkg % xar -tvf vimdir.pkg -rw-r--r-- kimuraw/staff 1049333 2013-10-29 11:23:17 Bom -rw-r--r-- kimuraw/staff 12038167 2013-10-29 11:23:18 Payload ?????????? unknown/unknown 452 1970-01-01 00:00:00 PackageInfo %
これで配布ファイルを.pkgにまとめて、productbuildで仕上げていくという手順になります。
XMLでの各種設定
productbuildの--distributionオプションに渡すXMLファイルでは、productbuildの各オプションや--productオプションのplistより多くの指定を行うことができます。
その設定内容はAppleのDistribution XML Referenceで説明されています。項目は一部、--productのplistと重複しています。
RubyCocoaでは、次の設定を使用しています。
- "allowed-os-versions" インストール可能なOSバージョンの設定
- こちらでは対象バージョンの上限(未満)も指定することができます。
- "readme" 「大切な情報」として表示されます。
- "license" 「使用許諾契約」として表示されます。
productbuildコマンドの--synthesizeオプションで最小限設定されたXMLファイルを生成することができます。初回はこれで生成して、そこに設定を追加したファイルを使う、というのが便利ではないかと思います。
署名
Mac OS X 10.7.5から導入されたGatekeeperの初期設定では、AppleのDeveloper IDで署名されていないインストーラからインストールすることができません。
MacのDeveloper Programに加入していれば、必要な証明書を用意できるのでそれを利用して署名することができます。先日のRubyCocoa 1.0.7では私のIDで署名したので、Gatekeeperが有効でもインストールすることができるはずです。
証明書を準備する手順は次のとおりです。
- MacのDeveloper Programに加入する。
- XcodeのAccounts > View Detailsの[+]ボタンで"Developer ID Install Distribution"を選択する。
- キーチェーンにインストーラ用の証明書が追加されているので確認する。
これで、productbuildの--signオプションを使って署名することができます。
まとめ
productbuildによるインストーラ作成手法を紹介しました。productbuildはSnow Leopardなど古い環境でも利用可能です。
また、Package Makerで提供されていた機能も、私が把握している範囲ではひととおり利用可能なようです。今でもPackage Makerを使っている方がいたら、この期に移行を検討してみてはいかがでしょうか。