開発者IDであるmacOSインストーラーパッケージを準備する


188

注:これはOS Xインストーラーパッケージ専用で、Mac App Storeに提出するパッケージはさまざまなルールに従います。

マウンテンライオンのゲートキーパーのため、私はようやくPackageMakerビルドスクリプトを納屋の後ろに置いて撮影する必要がありました。PackageMakerはすでにXcodeから削除されており、「Xcodeの補助ツール」に移動されているので、すぐに忘れられるでしょう。

質問はどのように私は使用しないでpkgbuildproductbuildpkgutilそれを交換しますか?


それで、packagemakerの問題は、マウンテンライオンのゲートキーパーで使用するためにpkgファイルに適切に署名できないと思いますか?
JasonZ

1
可能ですが、PackageMakerは常にバグが多く、Mac OS X 10.6 Snow Leopardで非推奨になりました。新しいツールに慣れるだけで、長期的には時間を節約できます。
カトラン

@catlan:packagemakerが10.6で非推奨になったという公式リンクはありますか?
カール

2
@carleeto:Xcodeから削除され、ビルマの抗議者のように「姿を消した」だけで、非推奨として発表されたことはありません。
バグ

5
Xcodeの4.6のリリースノート:パッケージメーカーの廃止adcdownload.apple.com/Developer_Tools/xcode_4.6/...
catlan

回答:


343

サンプルプロジェクトには、HelloWorld.appとHelper.appの2つのビルドターゲットがあります。それぞれのコンポーネントパッケージを作成し、それらを製品アーカイブに結合します

コンポーネントパッケージは、 OS Xインストーラによりインストールされるペイロードを含みます。コンポーネントパッケージは単独でインストールできますが、通常は製品アーカイブに組み込まれます

私たちのツール: 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が提供されます。値の説明は、「コンポーネントプロパティリスト」セクションにあります。pkgbuild -rootコンポーネントパッケージをます。デフォルトのプロパティを変更する必要がない場合は、次のコマンドで--component-plistパラメータを省略できます。

productbuild-合成すると、配布定義が作成されます。

$ 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、ライセンスなどを変更できます。あなたは、あなたのターンのコンポーネントパッケージ Aには、このコマンドを使用して、流通の定義を製品アーカイブ

$ 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、リソース、スクリプトなどが含まれています。

「Generate Package」という名前の実行スクリプトビルドフェーズを追加します。これは、インストール時にのみスクリプト実行するように設定されています

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 --expandpkgutil --flattenステップとステップを取り除くことができます。また、productsignを実行する代わりに、productbuildで--sign パラメータを使用することもできます。

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

パッケージは、開発者証明書ユーティリティからダウンロードできる開発者IDインストーラー証明書で署名されています

それらの署名は--sign "Developer ID Installer: John Doe"pkgbuildproductbuildまたはproductsignのパラメーターで行われます

productbuildを使用して署名付きの製品アーカイブを作成する場合は、コンポーネントパッケージに署名する必要はありません。

開発者証明書ユーティリティ

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

Xcode Archiveに何かをコピーするために、Run Script Build Phaseを使用することはできません。そのためには、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スキーム情報が保存されていない場合は、これをシェルスクリプトとしてプロジェクトに追加して、スクリプトをワークスペースからポストアクションにドラッグするだけでアクションを簡単に復元できるようにすることをお勧めします。

スクリプティング

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

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

追加の読書

既知の問題と回避策

宛先選択ペイン

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

インストーラーのバグを示す例

Apples Documentationを使用することをお勧めします<domains enable_anywhere ... />が、これにより、Appleがパッケージで使用しない、よりバグの多いDestination Select Paneがトリガーされます。

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


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

短い答え:試さないでください!

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

まず最初に、上記の宛先選択ペインのバグを時々見ました。それは私を止めるべきでしたが、私はそれを無視しました。ソフトウェアをリリースしてから1週間を費やしたくない場合は、サポート用の電子メールに返信して、青色の選択項目を1回クリックする必要があります。これは使用しないでください。

あなたは今、ユーザーがパネルを理解するのに十分賢いと考えていますね。ここで、ホームフォルダーのインストールに関するもう1つのことは、機能しません。

OSのバージョンが異なる約10種類のマシンで2週間テストしましたが、失敗したことはありませんでしたが、失敗することはありませんでした。発送しました。リリースから1時間以内に、それをインストールできなかったユーザーから心を奪われました。修正できない権限の問題を示唆するログ。

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


Welcome、Read-me、License and Conclusionの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で行われます。また、インストーラーツールまたはApple Remote Desktopを使用して、コマンドラインインストールでない場合にのみ実行します



9
これは優れたチュートリアルですが、プレハブバンドルの存在を前提としています。たとえば、/tmpポストフライトスクリプトで後で処理するために単一のファイルをインストールする場合、コンポーネントリストを構造化するにはどうすればよいですか?入手可能なすべてのドキュメント--analyzeは、少なくとも最初は開発者がで生成したと想定しているようです。
バグ

1
を変更Component Property Listする必要がない場合は、を実行する必要はありません--analyze。後処理ファイルについては、それらすべてをpkgに入れ、そのpkgインストール場所をに設定することをお勧めし/tmpます。しかし、多分私はあなたの質問を誤解しています。その場合は、SOのより詳細なバージョンで投稿してください。
カトラン2012年

2
コマンドラインでパッケージを作成しても、パッケージングアプリのすべてのバグを回避しようとしてもまったく意味がないことに注意してください。むしろ、すべての問題を解決するStéphaneSudreの "Packages"アプリケーションの使用に関する以下の私のコメントを参照してください。
Bram de Jong

5
@BramdeJongは「意味がありません」。同意しません。Appleはコマンドラインツールを保守しています。Packagesは、コミュニティでサポートされていないサードパーティのアプリであり、Appleが大幅な変更を行うと、将来的に機能しなくなる可能性があります。私にとっては、コマンドラインテクニックを知っているので、Appleが何かを大幅に変更した場合でも、実行し続けることができます。
Volomike、2015年

5
$ pkgbuild --root ./HelloWorld.appが間違っています(.appが実際のApp Bundleであると想定しています)。pkgbuildは宛先ルート:ie:xcodeツールチェーンによって生成されたバンドルを含むフォルダーで動作します。したがって、pkgbuildの引数は、パッケージ化するバンドルを含むフォルダーへのパスです。これを正しく行わないと、アプリのコンテンツフォルダーのみが含まれるパッケージになります。実際のApp Bundleとしてはインストールされません。プレゼントはコンポーネントのplistにあります。アプリのバンドルを指定するRootRelativeBundlePathエントリが含まれていない場合は、失敗しています。
ジョナサンミッチェル

185

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

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

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

パッケージアプリケーションのスクリーンショット


11
この投稿にこれ以上の意味がないとは思えない。そのソフトウェアは驚くべきものであり、コマンドラインからのビルドをサポートしています。
Cesar Mendoza

1
誰かがこのツールでパッケージに署名しようとしましたか?私は....有効にするには、「設定証明書」メニュー項目を取得することはできません
GTAE86

2
@ user283182:非常に遅いバンプです。きっとあなたはすでにそれを理解しているでしょうが、多分これは他の人を助けるでしょう-あなたが直面している問題は[Mac App Store Review Guidelines](developer.apple.com/app- store / review / guidelines / mac /…)、ルール2.14:「アプリは、Xcodeに含まれているAppleのパッケージテクノロジーを使用してパッケージ化および送信する必要があります-サードパーティのインストーラーは許可されていません。」
長老

4
これが有料アプリであり、開発者が常に更新とパッチを適用していることを願っています。Packages.appは、特にアプリをすばやくデプロイしたい場合に最適です。インストールに概要を読み、プロジェクトを設定して、インストール可能なパッケージを作成するには、合計3分かかりました。ステファンへの大きな称賛。
ニコライクリストフ2014

1
このアプリは素晴らしいです!
スペンサー・ミュラーDiniz

3

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

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

2
参考までに、.pkgの作成と、ようこそ画面やライセンスなどを使用した実際のインストーラーの作成には違いがあります。
カトラン2015

ええ、承知しました。プラグイン用のpkgインストーラーを作成するための参照が見つからなかったため、ここに配置しました。
gngrwzrd 2015

これは私を転がらせました。接地を行うための最小値。
uchuugaka

3

受け入れられた答えへの+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で試したところ、問題なく動作しているようです。


これはうまくいきますが、GOT'CHAの場合:最初にユーザーごとにインストールし、次にマシンごとにインストールすると、インストールはmachine-dirではなく、user-dirで行われ、sudo権限で行われます。逆は当てはまりません。マシンごとにインストールし、その後ユーザーごとにインストールして、両方の場所にインストールできます。
Terje Dahl、

@TerjeDahlはいこれは、インストール後にバンドルが同じバンドルIDが以前にインストーラーによってインストールされた場所に移動されるためです(そしてインストーラーはそれを知っています)。これは、今は覚えていないマニフェストファイルの設定によって回避できます。
PnotNP

@ PnotNPああ。あなたが覚えていて、あなたがそれらの設定で戻ってくるほど親切であるならば、それは素晴らしいでしょう!
Terje Dahl

2

以下は、ビルドルートから署名されたインストーラパッケージを作成するビルドスクリプトです。

#!/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

1
はい、pkgbuildは.pkgインストーラーを作成します。
Doug Richardson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.