Skip to content

package_mac: expand the utmctl scripting target before signing - #7860

Open
LayerTM wants to merge 1 commit into
utmapp:mainfrom
LayerTM:fix/utmctl-entitlement-unsigned
Open

LayerTM wants to merge 1 commit into
utmapp:mainfrom
LayerTM:fix/utmctl-entitlement-unsigned

Conversation

@LayerTM

@LayerTM LayerTM commented Sep 11, 2026

Copy link
Copy Markdown

In a package built with scripts/package_mac.sh unsigned, every utmctl command fails, although AppleScript to the same running UTM works.

Steps

  1. Build with ./scripts/build_utm.sh -k macosx -s macOS -a arm64 -o out and package with ./scripts/package_mac.sh unsigned out.xcarchive pkg.
  2. Install the app, open UTM, run UTM.app/Contents/MacOS/utmctl list.

Result

warning: failed to get scripting definition from /Applications/UTM.app; it may not be scriptable.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SBApplication virtualMachines]: unrecognized selector sent to instance …'

Exit code 134. osascript -e 'tell application "/Applications/UTM.app" to get name of every virtual machine' works in the same state.

Cause and fix
utmctl's scripting-targets entitlement names the target app as a dictionary key built from $(PRODUCT_BUNDLE_PREFIX:default=com.utmapp). Xcode expands it only when it signs; package_mac.sh re-signs utmctl from a copy of the raw file, so in an unsigned package the key stays literal and utmctl is not allowed to script UTM at all.

This replaces the build-setting reference with the script's PRODUCT_BUNDLE_PREFIX in the copied utmctl entitlements before signing. It runs in every mode; for signed modes the value is the same one Xcode would have produced.

The app-group strings in macOS-unsigned.entitlements and QEMUHelper-unsigned.entitlements carry the same kind of literal, but they match each other, so UTM and the helper still share the group; changing them would move the group container of existing unsigned installs, so they are left as they are.

Tested: after packaging, codesign -d --entitlements - --xml UTM.app/Contents/MacOS/utmctl shows the target com.utmapp.UTM, codesign --verify --deep --strict passes, and utmctl start / utmctl status work against a running unsigned UTM on macOS 26 (before the change both failed as described above).

The scripting-targets entitlement names the target app as a dictionary key built from $(PRODUCT_BUNDLE_PREFIX:default=com.utmapp). Xcode expands it only when it signs, and the unsigned package re-signs from the raw file, so utmctl in an unsigned build was allowed to script an app with that literal name and no other: every command failed with "failed to get scripting definition" and an unrecognized selector. Expand the key before signing.
@osy osy added this to the v5.0 milestone Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants