1. ホーム
  2. xcode

[解決済み】Developer IDに対応したmacOSインストーラーパッケージの作成

2022-04-11 09:08:01

質問

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

Mountain Lionの ゲートキーパー 私はついに自分の パッケージメーカー ビルドスクリプトを納屋の裏で撃ってしまった。PackageMakerはすでにXcodeから削除され、"Auxiliary Tools for Xcode"に移動しましたので、すぐに忘れ去られることを望みます。

問題は pkgbuild , productbuild および pkgutil に置き換えるのですか?

解決方法は?

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

A コンポーネントパッケージ には、OS X インストーラによってインストールされるペイロードが含まれています。コンポーネント パッケージは単独でインストールすることもできますが、一般的には 製品アーカイブ .

私たちのツール パッケージビルド , プロダクトビルド および パッケージツール

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

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

これでコンポーネントリストができあがり、値の説明は コンポーネントプロパティ一覧" セクションをご覧ください。 pkgbuild -root が生成されます。 コンポーネントパッケージ もし、デフォルトのプロパティを変更する必要がない場合は -コンポーネントリスト パラメータを指定します。

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 

ディストリビューション.xml で、タイトル、背景、Welcome、Readme、ライセンスなどを変更することができます。あなたの コンポーネントパッケージ とディストリビューション定義に、このコマンドで 製品アーカイブ :

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

を見ることをお勧めします。 iTunesインストーラー Distribution.xmlで何が可能かを確認します。で "Install iTunes.pkg" を展開することができます。

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

まとめよう

私は通常、プロジェクトの中にDistribution.xml、Component-plists、Resources、Scriptsといったものを含む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}"

で生成した後、パッケージを変更する必要がない場合は プロダクトビルド を取り除くことができます。 pkgutil --expandpkgutil --flatten のステップになります。また --記号 のパラメータは プロダクトビルド を実行する代わりに プロダクトサイン .

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

パッケージの署名は デベロッパーIDインストーラー からダウンロードできる証明書です。 開発者向け証明書ユーティリティ .

これらの署名は --sign "Developer ID Installer: John Doe" のパラメータを使用します。 パッケージビルド , プロダクトビルド または プロダクトサイン .

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

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

Xcodeアーカイブに何かをコピーするためには スクリプトのビルドフェーズを実行する . そのためには、Scheme Actionを使用する必要があります。

Schemeを編集してArchiveを展開します。そして、post-actionsをクリックし 新規スクリプト実行アクション :

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 Schemeの情報をバージョン管理で保存していない場合は、これをシェルスクリプトとしてプロジェクトに追加し、ワークスペースからポストアクションにドラッグするだけで簡単にアクションを復元できるようにすることをお勧めします。

スクリプト

スクリプトには2つの種類があります。 ディストリビューション定義ファイル内のJavaScript とシェルスクリプトの2種類があります。

シェルスクリプトに関する最も優れたドキュメントは WhiteBox - PackageMakerハウツー ただし、古いパッケージ形式を参照しているので、注意して読んでください。

アップルシリコン

パッケージが arm64 で動作するためには、Distribution ファイルにある hostArchitectures セクションで arm64 に加えて x86_64 :

<options hostArchitectures="arm64,x86_64" />

追加の読み物

既知の問題点と回避策

デスティネーション選択ペイン

ユーザーにはインストール先の選択オプションが表示され、選択肢は1つだけです - "このコンピュータのすべてのユーザーにインストールします"。このオプションは視覚的に選択されているように見えますが、ユーザーはインストールを続行するためにそれをクリックする必要があり、混乱の原因となっています。

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

非推奨の <options rootVolumeOnly="true" /> を選択すると、以前のデスティネーション選択ペインが表示されます。


カレントユーザーのホームフォルダーにアイテムをインストールしたい。

簡単な答え やめてください !

長い回答です。 本当に、試さないでください。 読む インストーラーのトラブルと解決策 . これを読んだ後でも、私が何をしたか分かりますか?私は愚かにもそれを試してみました。10.7か10.8で問題が修正されているはずだと自分に言い聞かせてね。

まず、上記の送信先選択ペインバグを時々見かけました。それで止めるべきでしたが、無視しました。もし、ソフトをリリースしてから1週間、サポートからのメールに答えるのが嫌なら、青い選択部分を一度クリックする必要があるので、これを使わないでください。

あなたは今、ユーザーはパネルを理解するのに十分なほど賢いと思っているのではないでしょうか?さて、ここでもう一つ、ホームフォルダーのインストールについて説明します。 動作しない !

OSのバージョンなどが異なる10台ほどのマシンで2週間ほどテストしましたが、一度も失敗することはありませんでした。だから、出荷したのです。リリースから1時間以内に、インストールできないユーザーから返信がありました。ログには、あなたが修正できないようなパーミッションの問題が示唆されていました。

では、もう1度繰り返してみましょう。ホームフォルダーへのインストールにインストーラーを使用することはありません。


Welcome、Read-me、License、ConclusionのRTFDは、以下のように受け付けられません。 productbuild .

インストーラは、画像付きのきれいなWelcome画面を作るための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 パス . また、コマンドラインでのインストールでない場合のみ実行するようにしています。 インストーラ ツールまたは Apple Remote Desktop .