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

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

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

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



답변

예제 프로젝트에는 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을 사용 하여 명령 행 설치가 아닌 경우에만 실행합니다 .



답변

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

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

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

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


답변

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

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


답변

허용되는 답변에 +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에서 완벽하게 작동하는 것 같습니다.


답변

다음은 빌드 루트에서 서명 된 설치 프로그램 패키지를 작성 하는 빌드 스크립트 입니다.

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


답변