개발자 ID가 준비된 macOS 설치 프로그램 패키지 만들기


189

참고 : 이것은 OS X Installer 패키지에만 해당되며 Mac App Store 에 제출할 패키지는 다른 규칙을 따릅니다.

Mountain Lion의 Gatekeeper로 인해 마침내 PackageMaker 빌드 스크립트를 헛간 뒤에서 가져와야 했습니다. PackageMaker는 이미 Xcode에서 제거되어 "Xcode 용 보조 도구"로 옮겨 졌으므로 곧 잊혀 질 것입니다.

문제는 내가 사용합니까 어떻게 pkgbuild, productbuild그리고 pkgutil그것을 대체?


그래서 패키지 메이커의 문제가 Mountain Lion에서 게이트 키퍼와 함께 사용할 pkg 파일에 올바르게 서명 할 수 없다고 생각합니까?
JasonZ

1
가능하지만 PackageMaker는 항상 버그가 많았으며 Mac OS X 10.6 Snow Leopard에서 더 이상 사용되지 않습니다. 새로운 도구에 익숙해지기 위해 장기적으로 시간을 절약 할 수 있습니다.
catlan

@catlan : packagemaker가 10.6에서 더 이상 사용되지 않는다는 공식 링크가 있습니까?
Carl

2
@carleeto : 더 이상 사용되지 않는다고 발표 된 적이 없으며 Xcode에서 제거되어 결국 버마 시위자처럼 사라졌습니다.
bug

5
Xcode 4.6 릴리스 노트 : Package Maker의 사용 중단 adcdownload.apple.com/Developer_Tools/xcode_4.6/…
catlan

답변:


344

예제 프로젝트에는 HelloWorld.app 및 Helper.app라는 두 가지 빌드 대상이 있습니다. 우리는 각각에 대한 구성 요소 패키지 를 만들어 제품 아카이브에 결합합니다. .

구성 요소 패키지 는 OS X 설치 프로그램에 의해 설치 될 페이로드 포함되어 있습니다. 구성 요소 패키지는 자체적으로 설치 될 수 있지만 일반적으로 제품 아카이브에 통합됩니다 .

우리의 도구 : pkgbuild , productbuildpkgutil

"빌드 및 아카이브"에 성공하면 터미널에서 $ 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 -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 당신은 그래서 제목, 배경, 환영, 추가 정보, 라이센스, 그리고 같은 상황을 타개 할 수 있습니다. 이 명령을 사용 하여 구성 요소 패키지 및 분배 정의를 제품 아카이브로 전환하십시오 .

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

가능한 것을 확인하려면 iTunes Installers Distribution.xml을 살펴 보는 것이 좋습니다 . 다음을 사용하여 "Install iTunes.pkg"를 추출 할 수 있습니다.

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

함께합시다

일반적으로 프로젝트에는 Distribution.xml, component-plists, resources 및 scripts를 포함하는 Package라는 폴더가 있습니다.

"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 paramenter를 사용할 수 있습니다 .

OS X 설치 프로그램 서명

패키지는 개발자 인증서 유틸리티 에서 다운로드 할 수 있는 개발자 ID 설치 프로그램 인증서 로 서명됩니다. .

서명은 pkgbuild , productbuild 또는 productsign--sign "Developer ID Installer: John Doe" 매개 변수로 수행됩니다 .

productbuild 를 사용하여 서명 된 제품 아카이브 를 작성하려는 경우 구성 요소 패키지 에 서명 할 이유가 없습니다 .

개발자 인증서 유틸리티

모든 방법 : Xcode 아카이브로 패키지 복사

Xcode Archive에 무언가를 복사하기 위해 Run Script Build Phase를 사용할 수 없습니다 . 이를 위해 Scheme 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 Scheme 정보가 저장되어 있지 않은 경우이 스크립트를 프로젝트에 셸 스크립트로 추가하여 작업 영역에서 사후 조치로 스크립트를 끌어서 조치를 간단하게 복원 할 수 있습니다.

스크립팅

스크립트에는 배포 정의 파일의 JavaScript 와 셸 스크립트 의 두 가지 종류가 있습니다.

WhiteBox-PackageMaker How-to 에서 찾은 Shell Scripts에 대한 가장 좋은 문서 는 이전 패키지 형식 을 나타내 므로주의 깊게 읽으십시오.

추가 자료

알려진 문제 및 해결 방법

대상 선택 창

사용자에게 "이 컴퓨터의 모든 사용자를위한 설치"라는 단일 선택 항목 만있는 대상 선택 옵션이 제공됩니다. 이 옵션은 시각적으로 선택된 것으로 나타나지만 설치를 계속하려면 사용자가 해당 옵션을 클릭해야하므로 혼동을 일으킬 수 있습니다.

설치 프로그램 버그를 보여주는 예

Apples 설명서를 사용하는 <domains enable_anywhere ... />것이 좋지만 이로 인해 Apple이 패키지에서 사용하지 않는 새로운 버그가 많은 Destination Select Pane이 트리거됩니다.

사용 중단을 사용하면 <options rootVolumeOnly="true" />이전 대상 선택 창이 나타납니다. 이전 대상 선택 창을 보여주는 예


현재 사용자의 홈 폴더에 항목을 설치하려고합니다.

짧은 대답 : 시도하지 마십시오!

긴 대답 : 정말; 시도하지 마십시오! 설치 프로그램 문제 및 솔루션 읽기 . 이걸 읽은 후에도 내가 한 일을 알고 있습니까? 나는 그것을 시도하기에 충분히 바보였다. 자신에게 10.7 또는 10.8에서 문제를 해결했다고 확신합니다.

우선 위에서 언급 한 대상 선택 창 버그를 때때로 보았습니다. 그것은 나를 막았어야했지만 무시했습니다. 소프트웨어를 출시 한 후 일주일을 보내지 않으려면 멋진 파란색 선택을 한 번 클릭해야하는 지원 전자 메일에 응답하지 마십시오.

당신은 이제 사용자가 패널을 알아낼 정도로 똑똑하다고 생각하고 있습니까? 홈 폴더 설치에 관한 또 다른 것이 있습니다. 작동하지 않습니다!

나는 다른 OS 버전을 가진 약 10 개의 다른 컴퓨터에서 2 주 동안 테스트했지만 실패하지 않았습니다. 그래서 배송했습니다. 릴리스 후 1 시간 이내에 설치를 할 수 없었던 사용자들의 마음을 사로 잡았습니다. 로그는 수정할 수없는 권한 문제를 암시했습니다.

한 번 더 반복하겠습니다 : 홈 폴더 설치에는 설치 프로그램을 사용하지 않습니다!


Welcome, 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을 사용 하여 명령 행 설치가 아닌 경우에만 실행합니다 .



9
이것은 훌륭한 튜토리얼이지만 조립식 번들이 있다고 가정합니다. 예를 들어 /tmp포스트 플라이트 스크립트에서 나중에 처리하기 위해 단일 파일을 설치하려는 경우 구성 요소 목록을 어떻게 구성합니까? 사용 가능한 모든 문서는 개발자가 --analyze적어도 초기 에을 (를) 사용하여 문서를 생성했다고 가정합니다 .
bug

1
당신이 아무것도 변경할 필요가 없다면 당신은 Component Property List실행할 필요가 없습니다 --analyze. 포스트 프로세싱 파일의 경우 pkg에 모두 넣고 pkg 설치 위치를로 설정하는 것이 좋습니다 /tmp. 그러나 나는 당신의 질문을 오해 할 것입니다. 그렇다면 SO에 대한 자세한 버전으로 게시하십시오.
catlan

2
패키징 앱의 모든 버그를 피하기 위해 명령 행을 통해 패키지를 만드는 것은 절대 의미가 없습니다. 오히려 Stéphane Sudre의 "패키지"응용 프로그램 사용에 대한 아래의 내 의견을 참조하십시오.
Bram de Jong

5
@BramdeJong은 "말도 안돼". 동의하지 않습니다. Apple은 명령 줄 도구를 유지 관리합니다. 패키지는 커뮤니티 지원되지 않으며 Apple이 과감한 변화를 겪을 경우 향후 중단 될 수있는 타사 앱입니다. 저에게는 커맨드 라인 기술을 알고 싶습니다. 그래서 Apple이 과감한 것을 바꾸면 계속 실행할 수 있습니다.
Volomike

5
$ pkgbuild --root ./HelloWorld.app가 잘못되었습니다 (.app가 실제 앱 번들이라고 가정). pkgbuild는 대상 루트, 즉 xcode 툴 체인에 의해 생성 된 번들을 포함하는 폴더에서 작동합니다. 따라서 pkgbuild에 대한 인수는 패키지하려는 번들의 포함 폴더에 대한 경로입니다. 이 권한을 얻지 못하면 앱 컨텐츠 폴더 만 포함 된 패키지가 생성됩니다. 실제 앱 번들로 설치되지 않습니다. 공짜는 구성 요소 plist에 있습니다. 앱 번들을 지정하는 RootRelativeBundlePath 항목이 포함되어 있지 않으면 문제가 해결 된 것입니다.
Jonathan Mitchell

185

Stéphane Sudre의 매우 흥미로운 응용 프로그램이 있습니다.이 모든 작업은 스크립트 가능 / 명령 줄에서 빌드 지원, 멋진 멋진 GUI가 있으며 무료입니다. 안타깝게도 구글에서 찾을 수없는 "패키지"라고 불립니다.

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

나는 내 자신의 대본을 만들기 시작하기 전에 그것에 대해 알고 있었으면 좋겠다.

패키지 애플리케이션 스크린 샷


11
이 게시물에 더 이상 언급이 없다고 믿을 수 없습니다. 이 소프트웨어는 훌륭하며 명령 줄에서 빌드를 지원합니다.
Cesar Mendoza

1
이 도구로 패키지에 서명하려고 한 사람이 있습니까? "인증서 설정"메뉴 항목을 활성화 할 수 없습니다 ...
GTAE86

2
@ user283182 : 매우 늦었습니다. 이미 알아 차 렸지만 다른 사람들에게 도움이 될 것입니다. 직면 한 문제는 [Mac App Store Review 지침] ( developer.apple.com/app- store / review / guidelines / mac /… ), 규칙 2.14 : "앱은 Xcode에 포함 된 Apple의 패키징 기술을 사용하여 패키징 및 제출되어야합니다. 타사 설치 프로그램은 허용되지 않습니다."
장로

4
유료 앱이고 개발자가 지속적으로 업데이트하고 패치하기를 바랍니다. Packages.app는 앱을 빠르게 배포하려는 경우 특히 좋습니다. 설치하는 데 개요를 읽고 프로젝트를 설정하고 설치 가능한 패키지를 만드는 데 총 3 분이 걸렸습니다. 스테판에 큰 명성.
Nikolay Christov

1
이 응용 프로그램은 굉장합니다!
스펜서 ül 러 디 니즈

3

참고로 번들 또는 플러그인 용 패키지 설치 프로그램을 작성하려는 사람들은 간단합니다.

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

2
참고로 .pkg를 만드는 것과 환영 화면, 라이센스 등을 사용하여 실제 설치 프로그램을 만드는 것에는 차이가 있습니다.
catlan

그래, 나는 플러그인을위한 pkg 설치 프로그램을 만드는 것에 대한 참조를 찾을 수 없기 때문에 이것을 여기에 넣었다.
gngrwzrd

이것은 나에게 굴러 갔다. 최소한의 접지 만 제공하십시오.
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 대의 dev 시스템과 2 개의 다른 VM에서 완벽하게 작동하는 것 같습니다.


이것은 잘 작동하지만 GOT'CHA와 함께 작동합니다. 사용자별로 먼저 설치 한 다음 컴퓨터별로 설치하면 설치는 machine-dir이 아니라 sudo-rights와 함께 user-dir에있게됩니다. 그 반대의 경우는 아닙니다. 기계별로 설치 한 다음 사용자별로 설치하여 두 곳에 둘 수 있습니다.
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.