Files
osy 29a3c1f62b terminal: update SwiftTerm and adopt its new renderer and find bar
SwiftTerm 2 no longer exposes the underlying Terminal from TerminalView, so
move the terminal views to the copied view APIs: terminalDimensions,
resize(cols:rows:), setCursorStyle, softReset and resetToInitialState. The
view's resize also soft resets the terminal now, so only call it when the
saved size differs, otherwise every resume would reset the guest's modes.

Track SwiftTerm from the osy/SwiftTerm fork's fix/visionos-build branch
for now: upstream main reads UIWindow.screen, which does not exist on
visionOS, and the fork reads the display scale from the trait collection
instead so the visionOS build works again.

SwiftTerm now ships a build tool plugin, which needs two changes to
build_utm.sh for CI. Xcode refuses to run a package plugin the machine has
not trusted, so pass -skipPackagePluginValidation. And -sdk also applies
to host tools, so the plugin's generator was built for the target platform
instead of the Mac and the build could not find it; pick the platform
with a generic destination and the architectures with ARCHS instead.
Also match the SDK name macosx when picking the default macOS scheme.

Take advantage of what the update brings:

- Render with Metal on macOS and iOS, falling back to Core Graphics if the
  GPU pipeline cannot be created. visionOS stays on Core Graphics because
  SwiftTerm's Metal path draws at the wrong scale there.
- Release the renderer with updateUiClosed() when the terminal window
  closes or the iOS view is dismantled, as SwiftTerm now requires.
- Feed guest output straight from the serial port thread; feed() is
  thread-safe now, so the hop to the main queue is no longer needed.
- Add the standard Edit > Find menu on macOS, which the terminal's new
  find bar is driven from.
- Open only http(s) links from the terminal. SwiftTerm now also turns host
  file paths printed by the guest into links, and its default handler on
  macOS opens any URL or existing host path, so clicking one could launch
  a host app. On iOS, let the bell use SwiftTerm's default haptic instead
  of an empty override.

Assisted-by: Claude:claude-opus-5
Assisted-by: Claude:claude-opus-5-5
2026-09-22 14:52:14 -05:00

143 lines
5.3 KiB
Bash
Executable File

#!/bin/sh
set -e
command -v realpath >/dev/null 2>&1 || realpath() {
[[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
}
BASEDIR="$(dirname "$(realpath $0)")"
usage () {
echo "Usage: $(basename $0) [-t teamid] [-k SDK] [-s scheme] [-a architecture] [-o output]"
echo ""
echo " -t teamid Team Identifier for app groups. Optional for iOS. Required for macOS."
echo " -k sdk Target SDK. Default iphoneos. [iphoneos|iphonesimulator|xros|xrsimulator|macosx]"
echo " -s scheme Target scheme. Default iOS/macOS depending on platform. [iOS|iOS-TCI|iOS-Remote|macOS]"
echo " -a architecture Target architecture. Default arm64. [arm64|x86_64]"
echo " -o output Output archive path. Default is current directory."
echo ""
exit 1
}
PRODUCT_BUNDLE_PREFIX="com.utmapp"
TEAM_IDENTIFIER=
ARCH=arm64
OUTPUT=$PWD
SDK=iphoneos
SCHEME=
while [ "x$1" != "x" ]; do
case $1 in
-t )
TEAM_IDENTIFIER=$2
shift
;;
-a )
ARCH=$2
shift
;;
-k )
SDK=$2
shift
;;
-s )
SCHEME=$2
shift
;;
-o )
OUTPUT=$2
shift
;;
* )
usage
;;
esac
shift
done
case $SDK in
macosx )
SCHEME="macOS"
;;
* )
if [ -z "$SCHEME" ]; then
SCHEME="iOS"
fi
;;
esac
# -sdk would also apply to host tools such as package build plugins, so select
# the platform with a destination instead
case $SDK in
iphoneos )
PLATFORM="iOS"
;;
iphonesimulator )
PLATFORM="iOS Simulator"
;;
xros )
PLATFORM="visionOS"
;;
xrsimulator )
PLATFORM="visionOS Simulator"
;;
macosx )
PLATFORM="macOS"
;;
* )
usage
;;
esac
if [ ! -z "$TEAM_IDENTIFIER" ]; then
TEAM_IDENTIFIER_PREFIX="TeamIdentifierPrefix=${TEAM_IDENTIFIER}."
fi
xcodebuild archive -archivePath "$OUTPUT" -scheme "$SCHEME" -destination "generic/platform=$PLATFORM" ARCHS="$ARCH" -configuration Release -skipPackagePluginValidation CODE_SIGNING_ALLOWED=NO $TEAM_IDENTIFIER_PREFIX
BUILT_PATH=$(find $OUTPUT.xcarchive -name '*.app' -type d | head -1)
# Only retain the target architecture to address < iOS 15 crash & save disk space
if [ "$SDK" == "iphoneos" ]; then
find "$BUILT_PATH" -type f -path '*/Frameworks/*.dylib' | while read FILE; do
if [[ $(lipo -info "$FILE") =~ "Architectures in the fat file" ]]; then
lipo -thin $ARCH "$FILE" -output "$FILE"
fi
done
find "$BUILT_PATH" -type d -path '*/Frameworks/*.framework' | while read FRAMEWORK; do
FILE="${FRAMEWORK}"/$(basename "${FRAMEWORK%.*}")
if [[ $(lipo -info "$FILE") =~ "Architectures in the fat file" ]]; then
lipo -thin $ARCH "$FILE" -output "$FILE"
fi
done
fi
find "$BUILT_PATH" -type d -path '*/Frameworks/*.framework' -exec codesign --force --sign - --timestamp=none \{\} \;
if [ "$SDK" == "macosx" ]; then
# always build with vm entitlements, package_mac.sh can strip it later
# this way we can import into Xcode and re-sign from there
UTM_ENTITLEMENTS="/tmp/utm.$$.entitlements"
LAUNCHER_ENTITLEMENTS="/tmp/launcher.$$.entitlements"
RENDERER_ENTITLEMENTS="/tmp/renderer.$$.entitlements"
HELPER_ENTITLEMENTS="/tmp/helper.$$.entitlements"
CLI_ENTITLEMENTS="/tmp/cli.$$.entitlements"
cp "$BASEDIR/../Platform/macOS/macOS.entitlements" "$UTM_ENTITLEMENTS"
cp "$BASEDIR/../QEMULauncher/QEMULauncher.entitlements" "$LAUNCHER_ENTITLEMENTS"
cp "$BASEDIR/../QEMURenderServer/QEMURenderServer.entitlements" "$RENDERER_ENTITLEMENTS"
cp "$BASEDIR/../QEMUHelper/QEMUHelper.entitlements" "$HELPER_ENTITLEMENTS"
cp "$BASEDIR/../utmctl/utmctl.entitlements" "$CLI_ENTITLEMENTS"
if [ ! -z "$TEAM_IDENTIFIER" ]; then
TEAM_ID_PREFIX="${TEAM_IDENTIFIER}."
fi
/usr/libexec/PlistBuddy -c "Set :com.apple.security.application-groups:0 ${TEAM_ID_PREFIX}${PRODUCT_BUNDLE_PREFIX}.UTM" "$UTM_ENTITLEMENTS"
/usr/libexec/PlistBuddy -c "Set :com.apple.security.application-groups:0 ${TEAM_ID_PREFIX}${PRODUCT_BUNDLE_PREFIX}.UTM" "$HELPER_ENTITLEMENTS"
/usr/libexec/PlistBuddy -c "Set :com.apple.security.application-groups:0 ${TEAM_ID_PREFIX}${PRODUCT_BUNDLE_PREFIX}.UTM" "$CLI_ENTITLEMENTS"
# nested bundles must be signed before the XPC service that contains them
codesign --force --sign - --entitlements "$LAUNCHER_ENTITLEMENTS" --timestamp=none --options runtime "$BUILT_PATH/Contents/XPCServices/QEMUHelper.xpc/Contents/MacOS/QEMULauncher.app/Contents/MacOS/QEMULauncher"
codesign --force --sign - --entitlements "$RENDERER_ENTITLEMENTS" --timestamp=none --options runtime "$BUILT_PATH/Contents/XPCServices/QEMUHelper.xpc/Contents/MacOS/QEMURenderServer.app/Contents/MacOS/QEMURenderServer"
codesign --force --sign - --entitlements "$HELPER_ENTITLEMENTS" --timestamp=none --options runtime "$BUILT_PATH/Contents/XPCServices/QEMUHelper.xpc/Contents/MacOS/QEMUHelper"
codesign --force --sign - --entitlements "$CLI_ENTITLEMENTS" --timestamp=none --options runtime "$BUILT_PATH/Contents/MacOS/utmctl"
codesign --force --sign - --entitlements "$UTM_ENTITLEMENTS" --timestamp=none --options runtime "$BUILT_PATH/Contents/MacOS/UTM"
rm "$UTM_ENTITLEMENTS"
rm "$LAUNCHER_ENTITLEMENTS"
rm "$RENDERER_ENTITLEMENTS"
rm "$HELPER_ENTITLEMENTS"
rm "$CLI_ENTITLEMENTS"
fi