web-dev-qa-db-ja.com

ProのようなOS Xインストーラーパッケージの作成-Xcode開発者ID対応パッケージ

注:これは OS Xインストーラー パッケージのみ、 Mac App Store に提出するためのパッケージは異なるルールに従います。

Mountain Lionの Gatekeeper のおかげで、ついに PackageMaker 納屋の後ろにスクリプトを作成して撮影しなければなりませんでした。 PackageMakerはすでにXcodeから削除されており、「Xcodeの補助ツール」に移行されているため、すぐに忘れられることを願っています。

問題は、pkgbuildproductbuild、およびpkgutilを使用してそれを置き換える方法ですか?

175
catlan

サンプルプロジェクトには、HelloWorld.appとHelper.appの2つのビルドターゲットがあります。それぞれに対してcomponent packageを作成し、それらをproduct archiveに結合します。

コンポーネントパッケージには、OS Xインストーラーによってインストールされるペイロードが含まれます。コンポーネントパッケージは単独でインストールできますが、通常はproduct archiveに組み込まれます。

ツール: pkgbuildproductbuild 、および pkgutil

「ビルドとアーカイブ」が成功したら、ターミナルで$ BUILT_PRODUCTS_DIRを開きます。

$ cd ~/Library/Developer/Xcode/DerivedData/.../InstallationBuildProductsLocation
$ pkgbuild --analyze --root ./HelloWorld.app HelloWorldAppComponents.plist
$ pkgbuild --analyze --root ./Helper.app HelperAppComponents.plist

これにより、component-plistが得られます。値の説明は "Component Property List" セクションにあります。 pkgbuild -rootcomponent packagesを生成します。デフォルトのプロパティを変更する必要がない場合は、-component-plistを省略できます。 =次のコマンドのパラメーター。

productbuild --synthesizeDistribution Definition になります。

$ pkgbuild --root ./HelloWorld.app \
    --component-plist HelloWorldAppComponents.plist \
    HelloWorld.pkg
$ pkgbuild --root ./Helper.app \
    --component-plist HelperAppComponents.plist \
    Helper.pkg
$ productbuild --synthesize \
    --package HelloWorld.pkg --package Helper.pkg \
    Distribution.xml 

Distribution.xml で、タイトル、背景、ようこそ、readme、ライセンスなどを変更できます。このコマンドでcomponent packagesと配布定義をproduct archiveに変換します。

$ productbuild --distribution ./Distribution.xml \
    --package-path . \
    ./Installer.pkg

iTunes Installers Distribution.xmlを見て、可能なことを確認することをお勧めします。 「Install iTunes.pkg」を次のように抽出できます。

$ pkgutil --expand "Install iTunes.pkg" "Install iTunes"

まとめましょう

通常、プロジェクトにはPackageという名前のフォルダーがあり、Distribution.xml、component-plists、リソース、スクリプトなどが含まれています。

スクリプトのビルドフェーズを実行という名前の「パッケージの生成」を追加します。これはインストール時にのみスクリプトを実行に設定されます。

VERSION=$(defaults read "${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/Contents/Info" CFBundleVersion)

PACKAGE_NAME=`echo "$PRODUCT_NAME" | sed "s/ /_/g"`
TMP1_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp1.pkg"
TMP2_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp2"
TMP3_ARCHIVE="${BUILT_PRODUCTS_DIR}/$PACKAGE_NAME-tmp3.pkg"
ARCHIVE_FILENAME="${BUILT_PRODUCTS_DIR}/${PACKAGE_NAME}.pkg"

pkgbuild --root "${INSTALL_ROOT}" \
    --component-plist "./Package/HelloWorldAppComponents.plist" \
    --scripts "./Package/Scripts" \
    --identifier "com.test.pkg.HelloWorld" \
    --version "$VERSION" \
    --install-location "/" \
    "${BUILT_PRODUCTS_DIR}/HelloWorld.pkg"
pkgbuild --root "${BUILT_PRODUCTS_DIR}/Helper.app" \
    --component-plist "./Package/HelperAppComponents.plist" \
    --identifier "com.test.pkg.Helper" \
    --version "$VERSION" \
    --install-location "/" \
    "${BUILT_PRODUCTS_DIR}/Helper.pkg"
productbuild --distribution "./Package/Distribution.xml"  \
    --package-path "${BUILT_PRODUCTS_DIR}" \
    --resources "./Package/Resources" \
    "${TMP1_ARCHIVE}"

pkgutil --expand "${TMP1_ARCHIVE}" "${TMP2_ARCHIVE}"

# Patches and Workarounds

pkgutil --flatten "${TMP2_ARCHIVE}" "${TMP3_ARCHIVE}"

productsign --sign "Developer ID Installer: John Doe" \
    "${TMP3_ARCHIVE}" "${ARCHIVE_FILENAME}"

productbuildで生成されたパッケージを変更する必要がない場合は、pkgutil --expandおよびpkgutil --flattenステップを削除できます。また、productsignを実行する代わりにproductbuild-signパラメーターを使用することもできます。

OS Xインストーラーに署名する

パッケージは開発者IDインストーラーで署名されます。この証明書は Developer Certificate Utility からダウンロードできます。

これらの署名は、pkgbuildproductbuild、またはproductsign--sign "Developer ID Installer: John Doe"パラメーターを使用して行われます。

Productbuildを使用して署名済みのproduct archiveを作成する場合、component packagesに署名する理由はないことに注意してください。

Developer Certificate Utility

すべての方法:パッケージをXcodeアーカイブにコピーする

Xcodeアーカイブに何かをコピーするには、スクリプトビルドフェーズの実行を使用できません。このために、Schemeアクションを使用する必要があります。

スキームを編集し、アーカイブを展開します。次に、ポストアクションをクリックして、新しいスクリプト実行アクションを追加します。

Xcode 6の場合:

#!/bin/bash

PACKAGES="${ARCHIVE_PATH}/Packages"

PACKAGE_NAME=`echo "$PRODUCT_NAME" | sed "s/ /_/g"`
ARCHIVE_FILENAME="$PACKAGE_NAME.pkg"
PKG="${OBJROOT}/../BuildProductsPath/${CONFIGURATION}/${ARCHIVE_FILENAME}"

if [ -f "${PKG}" ]; then
    mkdir "${PACKAGES}"
    cp -r "${PKG}" "${PACKAGES}"
fi

Xcode 5では、代わりにPKGに次の値を使用します。

PKG="${OBJROOT}/ArchiveIntermediates/${TARGET_NAME}/BuildProductsPath/${CONFIGURATION}/${ARCHIVE_FILENAME}"

バージョン管理にXcodeスキーム情報が保存されていない場合は、これをシェルスクリプトとしてプロジェクトに追加し、スクリプトをワークスペースから事後アクションにドラッグしてアクションを簡単に復元できるようにすることをお勧めします。

スクリプティング

スクリプティングには2種類あります: 配布定義ファイルのJavaScript とシェルスクリプト。

WhiteBox-PackageMaker How-to で見つけたシェルスクリプトに関する最良のドキュメントですが、古いパッケージ形式を参照しているため、注意して読んでください。

追加の読書

既知の問題と回避策

宛先選択ペイン

ユーザーには、「このコンピューターのすべてのユーザーにインストール」という単一の選択項目のみを含む宛先選択オプションが表示されます。オプションは視覚的に選択されているように見えますが、ユーザーはインストールを続行するためにクリックする必要があり、混乱を招きます。

Example showing the installer bug

Appleのドキュメントでは、<domains enable_anywhere ... />を使用することを推奨していますが、これは、Appleがどのパッケージでも使用していない、よりバグの多い新しいDestination Selectペインをトリガーします。

非推奨の<options rootVolumeOnly="true" />を使用すると、古い宛先選択ペインが表示されます。 Example showing old Destination Select Pane


現在のユーザーのホームフォルダーにアイテムをインストールします。

簡単な答え:やってはいけません!

長い答え:本当に。やってはいけません! インストーラーの問題と解決策 を読んでください。これを読んでも私が何をしたか知っていますか?私はそれを試してみるのに十分愚かだった。 10.7または10.8で問題が修正されたと確信しています。

まず、上記の宛先選択ペインのバグを時々見ました。それは私を止めるはずだったが、私はそれを無視した。あなたがソフトウェアをリリースしてから1週間を費やしたくない場合は、ニースブルーの選択を一度クリックする必要があるというサポートメールに応答します。これは使用しないでください。

あなたは今、あなたのユーザーがパネルを理解するのに十分賢いと思っていますよね?ここで、ホームフォルダーのインストールに関するもう1つのことを説明します。

OSのバージョンが異なる10台前後のマシンで2週間テストしましたが、決して失敗しませんでした。だから私はそれを出荷しました。リリースから1時間以内に、インストールできなかったユーザーに心から感謝します。ログには、修正できない許可の問題が示されています。

もう一度繰り返しましょう。ホームフォルダーのインストールにはインストーラーを使用しません。


ようこそ、Readme、ライセンス、および結論のRTFDは、productbuildでは受け入れられません。

インストーラーは最初のRTFDファイルから画像付きのきれいなウェルカム画面を作成することをサポートしていましたが、productbuildはそれらを受け入れません。

回避策:ダミーのrtfファイルを使用し、productbuildの実行後にパッケージ内で置き換えます。

注:RTFDファイル内にRetina画像を含めることもできます。これにはマルチイメージTIFFファイルを使用します:tiffutil -cat Welcome.tif Welcome_2x.tif -out FinalWelcome.tif。もっと 詳細


BundlePostInstallScriptPathスクリプトでインストールが完了したら、アプリケーションを起動します。

#!/bin/bash

LOGGED_IN_USER_ID=`id -u "${USER}"`

if [ "${COMMAND_LINE_INSTALL}" = "" ]
then
    /bin/launchctl asuser "${LOGGED_IN_USER_ID}" /usr/bin/open -g PATH_OR_BUNDLE_ID
fi

exit 0

インストーラーユーザーとしてではなく、ログインユーザーとしてアプリを実行することが重要です。これはlaunchctl asuser uid pathで行われます。また、コマンドラインインストールではない場合にのみ実行し、installer toolまたはApple Remote Desktopで実行します。


314
catlan

StéphaneSudreによる非常に興味深いアプリケーションが1つあります。これは、すべてをスクリプト化/コマンドラインからのビルドをサポートし、素晴らしいNice GUIを備え、無料です。悲しいことに、それは「パッケージ」と呼ばれ、Googleで見つけることができなくなります。

http://s.sudre.free.fr/Software/Packages/about.html

自分のスクリプトを手作りする前に、それについて知っていたらよかったのに。

Packages application screenshot

178
Bram de Jong

受け入れられた回答への+1:

インストーラーでの宛先の選択

ドメイン(宛先)の選択がユーザードメインとシステムドメイン間で必要な場合は、<domains enable_anywhere="true">を試すのではなく、次を使用します。

<domains enable_currentUserHome="true" enable_localSystem="true"/>

enable_currentUserHome アプリケーションアプリを~/Applications/の下にインストールし、enable_localSystemによりアプリケーションを/Applicationの下にインストールできます

El Capitan 10.11.6(15G1217)でこれを試しましたが、1台の開発マシンと2台の異なるVMで試したところ、まったく問題なく動作しているようです。

3
PnotNP

ここにビルドスクリプトがあります ビルドルートから署名付きインストーラーパッケージを作成します。

#!/bin/bash
# TRIMCheck build script
# Copyright Doug Richardson 2015
# Usage: build.sh
#
# The result is a disk image that contains the TRIMCheck installer.
#

DSTROOT=/tmp/trimcheck.dst
SRCROOT=/tmp/trimcheck.src

INSTALLER_PATH=/tmp/trimcheck
INSTALLER_PKG="TRIMCheck.pkg"
INSTALLER="$INSTALLER_PATH/$INSTALLER_PKG"

#
# Clean out anything that doesn't belong.
#
echo Going to clean out build directories
rm -rf build $DSTROOT $SRCROOT $INSTALLER_PATH
echo Build directories cleaned out


#
# Build
#
echo ------------------
echo Installing Sources
echo ------------------
xcodebuild -project TRIMCheck.xcodeproj installsrc SRCROOT=$SRCROOT || exit 1

echo ----------------
echo Building Project
echo ----------------
pushd $SRCROOT
xcodebuild -project TRIMCheck.xcodeproj -target trimcheck -configuration Release install || exit 1
popd

echo ------------------
echo Building Installer
echo ------------------
mkdir -p "$INSTALLER_PATH" || exit 1

echo "Runing pkgbuild. Note you must be connected to Internet for this to work as it"
echo "has to contact a time server in order to generate a trusted timestamp. See"
echo "man pkgbuild for more info under SIGNED PACKAGES."
pkgbuild --identifier "com.delicioussafari.TRIMCheck" \
    --sign "Developer ID Installer: Douglas Richardson (4L84QT8KA9)" \
    --root "$DSTROOT" \
    "$INSTALLER" || exit 1


echo Successfully built TRIMCheck
open "$INSTALLER_PATH"

exit 0
3
Doug Richardson

バンドルまたはプラグイン用のパッケージインストーラーを作成しようとしている人の参考までに、それは簡単です。

pkgbuild --component "Color Lists.colorPicker" --install-location ~/Library/ColorPickers ColorLists.pkg
2
gngrwzrd