diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 32a70928..3303de89 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -115,8 +115,10 @@ jobs: run: sudo xcode-select -switch /Applications/Xcode_12.4.app - name: Build UTM run: | - ./scripts/build_utm.sh -p macos -a "arm64 x86_64" -o UTM + ./scripts/build_utm.sh -t "$SIGNING_TEAM_ID" -p macos -a "arm64 x86_64" -o UTM tar cf UTM.xcarchive.tgz UTM.xcarchive + env: + SIGNING_TEAM_ID: ${{ secrets.SIGNING_TEAM_ID }} - name: Upload UTM uses: actions/upload-artifact@v2 with: diff --git a/Documentation/MacDevelopment.md b/Documentation/MacDevelopment.md index 953ce86e..5d04e308 100644 --- a/Documentation/MacDevelopment.md +++ b/Documentation/MacDevelopment.md @@ -41,11 +41,13 @@ If you are developing QEMU and wish to pass in a custom path to QEMU, you can us You can build UTM with the script: ``` -./scripts/build_utm.sh -p macos -a ARCH -o /path/to/output/directory +./scripts/build_utm.sh -t TEAMID -p macos -a ARCH -o /path/to/output/directory ``` `ARCH` can be `x86_64` or `arm64` or `"arm64 x86_64"` (quotes are required) for a universal binary. The built artifact is an unsigned `.xcarchive` which you can use with the package tool (see below). +`TEAMID` is optional and only used if you are going to sign it. + ### Packaging Artifacts built with `build_utm.sh` (includes Github Actions artifacts) must be re-signed before it can be used. To properly use all features, you must be a paid Apple Developer with access to a provisioning profile with the Hypervisor entitlements. However, non-registered developers can build "unsigned" packages which lack certain features (such as USB and network bridging support). @@ -61,17 +63,17 @@ This builds `UTM.dmg` in `/path/to/output` which can be installed to `/Applicati #### Signed packages ``` -./scripts/package_mac.sh developer-id /path/to/UTM.xcarchive /path/to/output TEAM_ID PROFILE_UUID HELPER_PROFILE_UUID +./scripts/package_mac.sh developer-id /path/to/UTM.xcarchive /path/to/output TEAM_ID PROFILE_UUID HELPER_PROFILE_UUID LAUNCHER_PROFILE_UUID ``` -To build a signed package, you need to be a registered Apple Developer. From the developer portal, create a certificate for "Developer ID Application" (and install it into your Keychain). Also create two provisioning profiles with that certificate with Hypervisor entitlements (you need to manually request these entitlements and be approved by Apple) for both UTM and QEMUHelper. `TEAM_ID` should be the same as in the certificate, `PROFILE_UUID` should be the UUID of the profile installed by Xcode (open the profile in Xcode), and `HELPER_PROFILE_UUID` is the UUID of a separate profile for the XPC helper. +To build a signed package, you need to be a registered Apple Developer. From the developer portal, create a certificate for "Developer ID Application" (and install it into your Keychain). Also create three provisioning profiles with that certificate with Hypervisor entitlements (you need to manually request these entitlements and be approved by Apple) for UTM, QEMUHelper, and QEMULauncher. `TEAM_ID` should be the same as in the certificate, `PROFILE_UUID` should be the UUID of the profile installed by Xcode (open the profile in Xcode), and `HELPER_PROFILE_UUID` is the UUID of a separate profile for the XPC helper. `LAUNCHER_PROFILE_UUID` is the UUID of a profile for the launcher. Once properly signed, you can ask Apple to notarize the DMG. #### Mac App Store ``` -./scripts/package_mac.sh app-store /path/to/UTM.xcarchive /path/to/output TEAM_ID PROFILE_UUID HELPER_PROFILE_UUID +./scripts/package_mac.sh app-store /path/to/UTM.xcarchive /path/to/output TEAM_ID PROFILE_UUID HELPER_PROFILE_UUID LAUNCHER_PROFILE_UUID ``` Similar to the above but builds a `UTM.pkg` for submission to the Mac App Store. You need a certificate for "Apple Distribution" and a certificate for "Mac App Distribution" as well as a provisioning profile with the right entitlements. diff --git a/scripts/build_utm.sh b/scripts/build_utm.sh index dd0e35b5..856e073c 100755 --- a/scripts/build_utm.sh +++ b/scripts/build_utm.sh @@ -7,8 +7,9 @@ command -v realpath >/dev/null 2>&1 || realpath() { BASEDIR="$(dirname "$(realpath $0)")" usage () { - echo "Usage: $(basename $0) [-p platform] [-a architecture] [-t targetversion] [-o output]" + echo "Usage: $(basename $0) [-t teamid] [-p platform] [-a architecture] [-t targetversion] [-o output]" echo "" + echo " -t teamid Team Identifier for app groups. Optional for iOS. Required for macOS." echo " -p platform Target platform. Default ios. [ios|ios_simulator|ios-tci|ios_simulator-tci|macos]" echo " -a architecture Target architecture. Default arm64. [armv7|armv7s|arm64|i386|x86_64]" echo " -o output Output archive path. Default is current directory." @@ -16,6 +17,7 @@ usage () { exit 1 } +TEAM_IDENTIFIER= ARCH=arm64 PLATFORM=ios OUTPUT=$PWD @@ -24,6 +26,10 @@ SCHEME= while [ "x$1" != "x" ]; do case $1 in + -t ) + TEAM_IDENTIFIER=$2 + shift + ;; -a ) ARCH=$2 shift @@ -74,5 +80,8 @@ macos ) esac ARCH_ARGS=$(echo $ARCH | xargs printf -- "-arch %s ") +if [ ! -z "$TEAM_IDENTIFIER" ]; then + TEAM_IDENTIFIER_PREFIX="TeamIdentifierPrefix=${TEAM_IDENTIFIER}." +fi -xcodebuild archive -archivePath "$OUTPUT" -scheme "$SCHEME" -sdk "$SDK" $ARCH_ARGS -configuration Release CODE_SIGNING_ALLOWED=NO +xcodebuild archive -archivePath "$OUTPUT" -scheme "$SCHEME" -sdk "$SDK" $ARCH_ARGS -configuration Release CODE_SIGNING_ALLOWED=NO $TEAM_IDENTIFIER_PREFIX diff --git a/scripts/package_mac.sh b/scripts/package_mac.sh index 6ab685b0..b5641116 100755 --- a/scripts/package_mac.sh +++ b/scripts/package_mac.sh @@ -33,6 +33,7 @@ UTM_ENTITLEMENTS="/tmp/utm.entitlements" LAUNCHER_ENTITLEMENTS="/tmp/launcher.entitlements" HELPER_ENTITLEMENTS="/tmp/helper.entitlements" INPUT_COPY="/tmp/UTM.xcarchive" +PRODUCT_BUNDLE_PREFIX="com.utmapp" cat >"$OPTIONS" < @@ -47,11 +48,11 @@ cat >"$OPTIONS" <${MODE} provisioningProfiles - com.utmapp.UTM + ${PRODUCT_BUNDLE_PREFIX}.UTM ${PROFILE_NAME} - com.utmapp.QEMUHelper + ${PRODUCT_BUNDLE_PREFIX}.QEMUHelper ${HELPER_PROFILE_NAME} - com.utmapp.QEMULauncher + ${PRODUCT_BUNDLE_PREFIX}.QEMULauncher ${LAUNCHER_PROFILE_NAME} signingStyle @@ -79,6 +80,13 @@ if [ "$MODE" == "unsigned" ]; then /usr/libexec/PlistBuddy -c "Add :com.apple.security.cs.disable-library-validation bool true" "$HELPER_ENTITLEMENTS" fi +if [ ! -z "$TEAM_ID" ]; then + TEAM_ID_PREFIX="${TEAM_ID}." +fi + +/usr/libexec/PlistBuddy -c "Set :com.apple.security.application-groups:0 ${TEAM_ID_PREFIX}${PRODUCT_BUNDLE_PREFIX}" "$UTM_ENTITLEMENTS" +/usr/libexec/PlistBuddy -c "Set :com.apple.security.application-groups:0 ${TEAM_ID_PREFIX}${PRODUCT_BUNDLE_PREFIX}" "$HELPER_ENTITLEMENTS" + # ad-hoc sign with the right entitlements rm -rf "$INPUT_COPY" cp -a "$INPUT" "$INPUT_COPY"