202

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

Mountain Lion のGatekeeperのおかげで、私は最終的にPackageMakerビルド スクリプトを納屋の後ろに持って行き、それを撃たなければなりませんでした。PackageMaker はすでに Xcode から削除され、"Auxiliary Tools for Xcode" に移動されているため、すぐに忘れ去られることを願っています。

pkgbuild問題は、 、productbuild、およびをどのように使用pkgutilして置き換えるかです。

4

5 に答える 5

367

サンプル プロジェクトには、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 --synthesizeディストリビューション定義になります。

$ 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、ライセンスなどを変更できます。次のコマンドを使用して、コンポーネント パッケージと配布定義を製品アーカイブに変換します。

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

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

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 インストーラーに署名する

パッケージは、 Developer Certificate UtilityからダウンロードできるDeveloper ID Installer証明書で署名されています。

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

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

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

ずっと: パッケージを Xcode アーカイブにコピーする

何かを Xcode アーカイブにコピーするために、Run Script Build Phaseを使用することはできません。これには、Scheme アクションを使用する必要があります。

スキームを編集し、アーカイブを展開します。次に、post-action をクリックして、New Run Script Actionを追加します。

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で見つけたシェル スクリプトに関する最良のドキュメントですが、これは古いパッケージ形式を参照しているため、注意して読んでください。

アップルシリコン

パッケージを arm64 として実行するには、Distribution ファイルのセクションで、以下に加えhostArchitecturesてサポート対象を指定する必要があります。arm64x86_64

<options hostArchitectures="arm64,x86_64" />

追加資料

既知の問題と回避策

宛先選択ペイン

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

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

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

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


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

簡単な答え:試さないでください。

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

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

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

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

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


ようこそ、Read-me、ライセンス、結論の 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を使用して、コマンド ライン インストールでない場合にのみ実行します。


于 2012-07-14T21:54:45.790 に答える
196

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

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

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

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

于 2013-04-04T15:50:39.817 に答える
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 で問題なく動作しているようです。

于 2017-02-11T02:55:28.380 に答える
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
于 2015-02-06T19:49:13.167 に答える