Ariver
2026-07-01 2547282e0942a09b67fccfd53cf62a403ccd4a52
privatevoice.src/scripts/build-local-macos.sh
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# build-local-macos.sh - Build a locally signed macOS app and DMG for PrivateVoice Input.
# build-local-macos.sh - Build a locally signed macOS app and DMG for PrivateVoice Dictation.
#
# This script intentionally does not notarize. It creates or reuses a stable
# local Code Signing identity so macOS TCC permissions, such as Accessibility,
@@ -12,11 +12,15 @@
#
set -euo pipefail
APP_NAME="PrivateVoice Input"
APP_NAME="PrivateVoice Dictation"
DEFAULT_LOCAL_IDENTITY="PrivateVoice Local Code Signing"
LEGACY_LOCAL_IDENTITY="VoiceSnap Local Code Signing"
LOCAL_IDENTITY="${PRIVATEVOICE_LOCAL_SIGN_IDENTITY:-${VOICESNAP_LOCAL_SIGN_IDENTITY:-}}"
KEYCHAIN="${PRIVATEVOICE_LOCAL_KEYCHAIN:-${VOICESNAP_LOCAL_KEYCHAIN:-$HOME/Library/Keychains/login.keychain-db}}"
LOCAL_BUILD_FLAVOR="${PRIVATEVOICE_LOCAL_BUILD_FLAVOR:-local}"
LOCAL_MIN_SYSTEM_VERSION="${PRIVATEVOICE_LOCAL_MIN_SYSTEM_VERSION:-}"
GO_MODFILE="${PRIVATEVOICE_GO_MODFILE:-}"
GO_BUILD_TAGS="${PRIVATEVOICE_GO_BUILD_TAGS:-${PRIVATEVOICE_GO_TAGS:-}}"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
@@ -24,9 +28,27 @@
INFO_PLIST="$PROJECT_DIR/build/darwin/Info.plist"
ENTITLEMENTS="$PROJECT_DIR/build/darwin/entitlements.plist"
GOMODCACHE="$(go env GOMODCACHE)"
GO_MOD_ARG=""
GO_BUILD_TAG_ARG=""
if [[ -n "$GO_MODFILE" ]]; then
  GO_MOD_ARG="-modfile=$GO_MODFILE"
fi
if [[ -n "$GO_BUILD_TAGS" ]]; then
  GO_BUILD_TAG_ARG="-tags=$GO_BUILD_TAGS"
fi
if [[ -n "$GO_MOD_ARG" ]]; then
  SHERPA_MACOS_MODULE_VERSION="$(cd "$PROJECT_DIR" && go list "$GO_MOD_ARG" -m -f '{{.Version}}' github.com/k2-fsa/sherpa-onnx-go-macos)"
else
  SHERPA_MACOS_MODULE_VERSION="$(cd "$PROJECT_DIR" && go list -m -f '{{.Version}}' github.com/k2-fsa/sherpa-onnx-go-macos)"
fi
VERSION="$(defaults read "$INFO_PLIST" CFBundleShortVersionString 2>/dev/null || echo "2.1.1")"
BUILD_ID="$(defaults read "$INFO_PLIST" CFBundleVersion 2>/dev/null || date +%Y%m%d.%H%M)"
DEFAULT_MIN_SYSTEM_VERSION="$(defaults read "$INFO_PLIST" LSMinimumSystemVersion 2>/dev/null || echo "")"
EFFECTIVE_MIN_SYSTEM_VERSION="${LOCAL_MIN_SYSTEM_VERSION:-$DEFAULT_MIN_SYSTEM_VERSION}"
if [[ -n "$EFFECTIVE_MIN_SYSTEM_VERSION" && -z "${MACOSX_DEPLOYMENT_TARGET:-}" ]]; then
  export MACOSX_DEPLOYMENT_TARGET="$EFFECTIVE_MIN_SYSTEM_VERSION"
fi
TARGET_ARCH=""
INSTALL_AFTER_BUILD=0
@@ -75,9 +97,11 @@
BUILD_DIR="$PROJECT_DIR/build/local/$DMG_ARCH"
APP_BUNDLE="$BUILD_DIR/$APP_NAME.app"
DMG_PATH="$BUILD_DIR/$APP_NAME-$VERSION-build$BUILD_ID-$DMG_ARCH-local.dmg"
COMPAT_DMG_PATH="$BUILD_DIR/$APP_NAME-$VERSION-$DMG_ARCH-local.dmg"
SHERPA_LIB_DIR="$GOMODCACHE/github.com/k2-fsa/sherpa-onnx-go-macos@v1.12.24/lib/$SHERPA_ARCH"
DMG_PATH="$BUILD_DIR/$APP_NAME-$VERSION-build$BUILD_ID-$DMG_ARCH-$LOCAL_BUILD_FLAVOR.dmg"
COMPAT_DMG_PATH="$BUILD_DIR/$APP_NAME-$VERSION-$DMG_ARCH-$LOCAL_BUILD_FLAVOR.dmg"
SHERPA_LIB_DIR="$GOMODCACHE/github.com/k2-fsa/sherpa-onnx-go-macos@$SHERPA_MACOS_MODULE_VERSION/lib/$SHERPA_ARCH"
ONNXRUNTIME_DYLIB=""
ONNXRUNTIME_DYLIB_NAME=""
ensure_local_identity() {
  if [[ -z "$LOCAL_IDENTITY" ]]; then
@@ -176,11 +200,21 @@
    "$item"
}
step "Resolving Go dependencies"
if [[ -n "$GO_MOD_ARG" ]]; then
  (cd "$PROJECT_DIR" && go mod download "$GO_MOD_ARG" github.com/k2-fsa/sherpa-onnx-go-macos)
else
  (cd "$PROJECT_DIR" && go mod download github.com/k2-fsa/sherpa-onnx-go-macos)
fi
step "Preflight checks"
[[ -f "$INFO_PLIST" ]] || fail "Info.plist not found at $INFO_PLIST"
[[ -f "$ENTITLEMENTS" ]] || fail "entitlements.plist not found at $ENTITLEMENTS"
[[ -f "$PROJECT_DIR/build/darwin/icon.icns" ]] || fail "icon.icns not found"
[[ -d "$SHERPA_LIB_DIR" ]] || fail "sherpa-onnx dylibs not found at $SHERPA_LIB_DIR"
ONNXRUNTIME_DYLIB="$(find "$SHERPA_LIB_DIR" -maxdepth 1 -type f -name 'libonnxruntime.*.dylib' | sort | tail -n 1)"
[[ -f "$ONNXRUNTIME_DYLIB" ]] || fail "onnxruntime dylib not found in $SHERPA_LIB_DIR"
ONNXRUNTIME_DYLIB_NAME="$(basename "$ONNXRUNTIME_DYLIB")"
ensure_local_identity
step "Cleaning old local build"
@@ -196,9 +230,23 @@
step "Building Go binary ($DMG_ARCH)"
cd "$PROJECT_DIR"
CGO_ENABLED=1 GOOS=darwin GOARCH="$GOARCH" \
  go build -buildvcs=false -gcflags=all="-l" -ldflags="-s -w" \
  -o "$BUILD_DIR/$APP_NAME"
if [[ -n "$GO_MOD_ARG" && -n "$GO_BUILD_TAG_ARG" ]]; then
  CGO_ENABLED=1 GOOS=darwin GOARCH="$GOARCH" \
    go build "$GO_MOD_ARG" "$GO_BUILD_TAG_ARG" -buildvcs=false -gcflags=all="-l" -ldflags="-s -w" \
    -o "$BUILD_DIR/$APP_NAME"
elif [[ -n "$GO_MOD_ARG" ]]; then
  CGO_ENABLED=1 GOOS=darwin GOARCH="$GOARCH" \
    go build "$GO_MOD_ARG" -buildvcs=false -gcflags=all="-l" -ldflags="-s -w" \
    -o "$BUILD_DIR/$APP_NAME"
elif [[ -n "$GO_BUILD_TAG_ARG" ]]; then
  CGO_ENABLED=1 GOOS=darwin GOARCH="$GOARCH" \
    go build "$GO_BUILD_TAG_ARG" -buildvcs=false -gcflags=all="-l" -ldflags="-s -w" \
    -o "$BUILD_DIR/$APP_NAME"
else
  CGO_ENABLED=1 GOOS=darwin GOARCH="$GOARCH" \
    go build -buildvcs=false -gcflags=all="-l" -ldflags="-s -w" \
    -o "$BUILD_DIR/$APP_NAME"
fi
step "Assembling $APP_NAME.app"
mkdir -p "$APP_BUNDLE/Contents/MacOS"
@@ -206,21 +254,27 @@
mkdir -p "$APP_BUNDLE/Contents/Resources"
cp "$INFO_PLIST" "$APP_BUNDLE/Contents/Info.plist"
if [[ -n "$EFFECTIVE_MIN_SYSTEM_VERSION" ]]; then
  /usr/libexec/PlistBuddy -c "Set :LSMinimumSystemVersion $EFFECTIVE_MIN_SYSTEM_VERSION" "$APP_BUNDLE/Contents/Info.plist" >/dev/null 2>&1 \
    || /usr/libexec/PlistBuddy -c "Add :LSMinimumSystemVersion string $EFFECTIVE_MIN_SYSTEM_VERSION" "$APP_BUNDLE/Contents/Info.plist"
fi
cp "$BUILD_DIR/$APP_NAME" "$APP_BUNDLE/Contents/MacOS/$APP_NAME"
cp "$PROJECT_DIR/build/darwin/icon.icns" "$APP_BUNDLE/Contents/Resources/icon.icns"
find "$PROJECT_DIR/build/darwin" -maxdepth 1 -type d -name "*.lproj" \
  -exec cp -R {} "$APP_BUNDLE/Contents/Resources/" \;
cp "$SHERPA_LIB_DIR/libsherpa-onnx-c-api.dylib" "$APP_BUNDLE/Contents/Frameworks/"
cp "$SHERPA_LIB_DIR/libonnxruntime.1.23.2.dylib" "$APP_BUNDLE/Contents/Frameworks/"
cp "$ONNXRUNTIME_DYLIB" "$APP_BUNDLE/Contents/Frameworks/"
step "Fixing rpaths"
install_name_tool -add_rpath @executable_path/../Frameworks \
  "$APP_BUNDLE/Contents/MacOS/$APP_NAME" 2>/dev/null || true
install_name_tool -id @rpath/libsherpa-onnx-c-api.dylib \
  "$APP_BUNDLE/Contents/Frameworks/libsherpa-onnx-c-api.dylib"
install_name_tool -id @rpath/libonnxruntime.1.23.2.dylib \
  "$APP_BUNDLE/Contents/Frameworks/libonnxruntime.1.23.2.dylib"
install_name_tool -id "@rpath/$ONNXRUNTIME_DYLIB_NAME" \
  "$APP_BUNDLE/Contents/Frameworks/$ONNXRUNTIME_DYLIB_NAME"
step "Code signing with stable local identity"
sign_item "$APP_BUNDLE/Contents/Frameworks/libonnxruntime.1.23.2.dylib"
sign_item "$APP_BUNDLE/Contents/Frameworks/$ONNXRUNTIME_DYLIB_NAME"
sign_item "$APP_BUNDLE/Contents/Frameworks/libsherpa-onnx-c-api.dylib"
sign_item "$APP_BUNDLE/Contents/MacOS/$APP_NAME"
sign_item "$APP_BUNDLE"