Spaces:
Running
Running
whisper: add xcframework build script (#2873)
Browse files* whisper: add xcframework build script
* added apple validation scripts
* fixed Readme
* validation script fix
- .github/workflows/build.yml +29 -6
- Package.swift +0 -19
- Sources/whisper/module.modulemap +0 -5
- Sources/whisper/whisper.h +0 -4
- build-xcframework.sh +519 -0
- examples/whisper.swiftui/README.md +23 -1
- examples/whisper.swiftui/whisper.swiftui.xcodeproj/project.pbxproj +20 -12
- scripts/apple/validate-apps.sh +5 -0
- scripts/apple/validate-ios.sh +817 -0
- scripts/apple/validate-macos.sh +778 -0
- scripts/apple/validate-tvos.sh +810 -0
- scripts/apple/validate-visionos.sh +808 -0
- spm-headers/ggml-alloc.h +0 -1
- spm-headers/ggml-backend.h +0 -1
- spm-headers/ggml-cpp.h +0 -1
- spm-headers/ggml-cpu.h +0 -1
- spm-headers/ggml-metal.h +0 -1
- spm-headers/ggml.h +0 -1
- spm-headers/whisper.h +0 -1
.github/workflows/build.yml
CHANGED
|
@@ -97,10 +97,21 @@ jobs:
|
|
| 97 |
macOS-latest:
|
| 98 |
runs-on: macOS-latest
|
| 99 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
steps:
|
| 101 |
- name: Clone
|
|
|
|
| 102 |
uses: actions/checkout@v4
|
| 103 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
- name: Dependencies
|
| 105 |
run: |
|
| 106 |
brew update
|
|
@@ -108,8 +119,21 @@ jobs:
|
|
| 108 |
|
| 109 |
- name: Build
|
| 110 |
run: |
|
| 111 |
-
|
| 112 |
-
cmake
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
|
| 114 |
# freeBSD-latest:
|
| 115 |
# runs-on: macos-12
|
|
@@ -671,18 +695,17 @@ jobs:
|
|
| 671 |
-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \
|
| 672 |
-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=ggml
|
| 673 |
cmake --build . --config Release -j $(sysctl -n hw.logicalcpu) -- CODE_SIGNING_ALLOWED=NO
|
| 674 |
-
sudo cmake --install . --config Release
|
| 675 |
|
| 676 |
- name: xcodebuild for swift package
|
| 677 |
id: xcodebuild
|
| 678 |
run: |
|
| 679 |
-
|
| 680 |
|
| 681 |
- name: Build objc example
|
| 682 |
-
run: xcodebuild -project examples/whisper.objc/whisper.objc.xcodeproj -scheme whisper.objc -configuration ${{ matrix.build }} -sdk iphoneos CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO build
|
| 683 |
|
| 684 |
- name: Build swiftui example
|
| 685 |
-
run: xcodebuild -project examples/whisper.swiftui/whisper.swiftui.xcodeproj -scheme WhisperCppDemo -configuration ${{ matrix.build }} -sdk iphoneos CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -destination 'generic/platform=iOS' build
|
| 686 |
|
| 687 |
android:
|
| 688 |
runs-on: ubuntu-22.04
|
|
|
|
| 97 |
macOS-latest:
|
| 98 |
runs-on: macOS-latest
|
| 99 |
|
| 100 |
+
strategy:
|
| 101 |
+
matrix:
|
| 102 |
+
destination: ['generic/platform=macOS', 'generic/platform=iOS', 'generic/platform=tvOS']
|
| 103 |
+
|
| 104 |
steps:
|
| 105 |
- name: Clone
|
| 106 |
+
id: checkout
|
| 107 |
uses: actions/checkout@v4
|
| 108 |
|
| 109 |
+
- name: ccache
|
| 110 |
+
uses: hendrikmuhs/[email protected]
|
| 111 |
+
with:
|
| 112 |
+
key: macOS-latest-swift
|
| 113 |
+
evict-old-files: 1d
|
| 114 |
+
|
| 115 |
- name: Dependencies
|
| 116 |
run: |
|
| 117 |
brew update
|
|
|
|
| 119 |
|
| 120 |
- name: Build
|
| 121 |
run: |
|
| 122 |
+
sysctl -a
|
| 123 |
+
cmake -B build -G Xcode \
|
| 124 |
+
-DGGML_METAL_USE_BF16=ON \
|
| 125 |
+
-DGGML_METAL_EMBED_LIBRARY=ON \
|
| 126 |
+
-DWHISPER_BUILD_EXAMPLES=OFF \
|
| 127 |
+
-DWHISPER_BUILD_TESTS=OFF \
|
| 128 |
+
-DWHISPER_BUILD_SERVER=OFF \
|
| 129 |
+
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64"
|
| 130 |
+
cmake --build build --config Release -j $(sysctl -n hw.logicalcpu)
|
| 131 |
+
|
| 132 |
+
- name: xcodebuild for swift package
|
| 133 |
+
id: xcodebuild
|
| 134 |
+
run: |
|
| 135 |
+
./build-xcframework.sh
|
| 136 |
+
|
| 137 |
|
| 138 |
# freeBSD-latest:
|
| 139 |
# runs-on: macos-12
|
|
|
|
| 695 |
-DCMAKE_OSX_DEPLOYMENT_TARGET=14.0 \
|
| 696 |
-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=ggml
|
| 697 |
cmake --build . --config Release -j $(sysctl -n hw.logicalcpu) -- CODE_SIGNING_ALLOWED=NO
|
|
|
|
| 698 |
|
| 699 |
- name: xcodebuild for swift package
|
| 700 |
id: xcodebuild
|
| 701 |
run: |
|
| 702 |
+
./build-xcframework.sh
|
| 703 |
|
| 704 |
- name: Build objc example
|
| 705 |
+
run: xcodebuild -project examples/whisper.objc/whisper.objc.xcodeproj -scheme whisper.objc -configuration ${{ matrix.build }} -sdk iphoneos CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO FRAMEWORK_FOLDER_PATH=./build-ios build
|
| 706 |
|
| 707 |
- name: Build swiftui example
|
| 708 |
+
run: xcodebuild -project examples/whisper.swiftui/whisper.swiftui.xcodeproj -scheme WhisperCppDemo -configuration ${{ matrix.build }} -sdk iphoneos CODE_SIGNING_REQUIRED=NO CODE_SIGN_IDENTITY= -destination 'generic/platform=iOS' FRAMEWORK_FOLDER_PATH=./build-ios build
|
| 709 |
|
| 710 |
android:
|
| 711 |
runs-on: ubuntu-22.04
|
Package.swift
DELETED
|
@@ -1,19 +0,0 @@
|
|
| 1 |
-
// swift-tools-version:5.5
|
| 2 |
-
|
| 3 |
-
import PackageDescription
|
| 4 |
-
|
| 5 |
-
let package = Package(
|
| 6 |
-
name: "whisper",
|
| 7 |
-
platforms: [
|
| 8 |
-
.macOS(.v12),
|
| 9 |
-
.iOS(.v14),
|
| 10 |
-
.watchOS(.v4),
|
| 11 |
-
.tvOS(.v14)
|
| 12 |
-
],
|
| 13 |
-
products: [
|
| 14 |
-
.library(name: "whisper", targets: ["whisper"]),
|
| 15 |
-
],
|
| 16 |
-
targets: [
|
| 17 |
-
.systemLibrary(name: "whisper", pkgConfig: "whisper"),
|
| 18 |
-
]
|
| 19 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Sources/whisper/module.modulemap
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
module whisper [system] {
|
| 2 |
-
header "whisper.h"
|
| 3 |
-
link "whisper"
|
| 4 |
-
export *
|
| 5 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Sources/whisper/whisper.h
DELETED
|
@@ -1,4 +0,0 @@
|
|
| 1 |
-
#pragma once
|
| 2 |
-
|
| 3 |
-
#include <whisper.h>
|
| 4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
build-xcframework.sh
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
#
|
| 3 |
+
# Options
|
| 4 |
+
IOS_MIN_OS_VERSION=16.4
|
| 5 |
+
MACOS_MIN_OS_VERSION=13.3
|
| 6 |
+
VISIONOS_MIN_OS_VERSION=1.0
|
| 7 |
+
TVOS_MIN_OS_VERSION=16.4
|
| 8 |
+
|
| 9 |
+
BUILD_SHARED_LIBS=OFF
|
| 10 |
+
WHISPER_BUILD_EXAMPLES=OFF
|
| 11 |
+
WHISPER_BUILD_TESTS=OFF
|
| 12 |
+
WHISPER_BUILD_SERVER=OFF
|
| 13 |
+
GGML_METAL=ON
|
| 14 |
+
GGML_METAL_EMBED_LIBRARY=ON
|
| 15 |
+
GGML_BLAS_DEFAULT=ON
|
| 16 |
+
GGML_METAL_USE_BF16=ON
|
| 17 |
+
GGML_OPENMP=OFF
|
| 18 |
+
|
| 19 |
+
COMMON_C_FLAGS="-Wno-macro-redefined -Wno-shorten-64-to-32 -Wno-unused-command-line-argument -g"
|
| 20 |
+
COMMON_CXX_FLAGS="-Wno-macro-redefined -Wno-shorten-64-to-32 -Wno-unused-command-line-argument -g"
|
| 21 |
+
|
| 22 |
+
# Common options for all builds
|
| 23 |
+
COMMON_CMAKE_ARGS=(
|
| 24 |
+
-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=NO
|
| 25 |
+
-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY=""
|
| 26 |
+
-DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=NO
|
| 27 |
+
-DCMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"
|
| 28 |
+
-DCMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS=YES
|
| 29 |
+
-DCMAKE_XCODE_ATTRIBUTE_COPY_PHASE_STRIP=NO
|
| 30 |
+
-DCMAKE_XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT=NO
|
| 31 |
+
-DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=ggml
|
| 32 |
+
-DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
|
| 33 |
+
-DWHISPER_BUILD_EXAMPLES=${WHISPER_BUILD_EXAMPLES}
|
| 34 |
+
-DWHISPER_BUILD_TESTS=${WHISPER_BUILD_TESTS}
|
| 35 |
+
-DWHISPER_BUILD_SERVER=${WHISPER_BUILD_SERVER}
|
| 36 |
+
-DGGML_METAL_EMBED_LIBRARY=${GGML_METAL_EMBED_LIBRARY}
|
| 37 |
+
-DGGML_BLAS_DEFAULT=${GGML_BLAS_DEFAULT}
|
| 38 |
+
-DGGML_METAL=${GGML_METAL}
|
| 39 |
+
-DGGML_METAL_USE_BF16=${GGML_METAL_USE_BF16}
|
| 40 |
+
-DGGML_NATIVE=OFF
|
| 41 |
+
-DGGML_OPENMP=${GGML_OPENMP}
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
check_required_tool() {
|
| 45 |
+
local tool=$1
|
| 46 |
+
local install_message=$2
|
| 47 |
+
|
| 48 |
+
if ! command -v $tool &> /dev/null; then
|
| 49 |
+
echo "Error: $tool is required but not found."
|
| 50 |
+
echo "$install_message"
|
| 51 |
+
exit 1
|
| 52 |
+
fi
|
| 53 |
+
}
|
| 54 |
+
echo "Checking for required tools..."
|
| 55 |
+
check_required_tool "cmake" "Please install CMake 3.28.0 or later (brew install cmake)"
|
| 56 |
+
check_required_tool "xcodebuild" "Please install Xcode and Xcode Command Line Tools (xcode-select --install)"
|
| 57 |
+
check_required_tool "libtool" "Please install libtool which should be available with Xcode Command Line Tools (CLT). Make sure Xcode CLT is installed (xcode-select --install)"
|
| 58 |
+
check_required_tool "dsymutil" "Please install Xcode and Xcode Command Line Tools (xcode-select --install)"
|
| 59 |
+
|
| 60 |
+
set -e
|
| 61 |
+
|
| 62 |
+
## Clean up previous builds
|
| 63 |
+
rm -rf build-apple
|
| 64 |
+
rm -rf build-ios-sim
|
| 65 |
+
rm -rf build-ios-device
|
| 66 |
+
rm -rf build-macos
|
| 67 |
+
rm -rf build-visionos
|
| 68 |
+
rm -rf build-visionos-sim
|
| 69 |
+
rm -rf build-tvos-sim
|
| 70 |
+
rm -rf build-tvos-device
|
| 71 |
+
|
| 72 |
+
# Setup the xcframework build directory structure
|
| 73 |
+
setup_framework_structure() {
|
| 74 |
+
local build_dir=$1
|
| 75 |
+
local min_os_version=$2
|
| 76 |
+
local platform=$3 # "ios", "macos", "visionos", or "tvos"
|
| 77 |
+
local framework_name="whisper"
|
| 78 |
+
|
| 79 |
+
echo "Creating ${platform}-style framework structure for ${build_dir}"
|
| 80 |
+
|
| 81 |
+
if [[ "$platform" == "macos" ]]; then
|
| 82 |
+
# macOS versioned structure uses versioned directories
|
| 83 |
+
mkdir -p ${build_dir}/framework/${framework_name}.framework/Versions/A/Headers
|
| 84 |
+
mkdir -p ${build_dir}/framework/${framework_name}.framework/Versions/A/Modules
|
| 85 |
+
mkdir -p ${build_dir}/framework/${framework_name}.framework/Versions/A/Resources
|
| 86 |
+
|
| 87 |
+
# Create symbolic links
|
| 88 |
+
ln -sf A ${build_dir}/framework/${framework_name}.framework/Versions/Current
|
| 89 |
+
ln -sf Versions/Current/Headers ${build_dir}/framework/${framework_name}.framework/Headers
|
| 90 |
+
ln -sf Versions/Current/Modules ${build_dir}/framework/${framework_name}.framework/Modules
|
| 91 |
+
ln -sf Versions/Current/Resources ${build_dir}/framework/${framework_name}.framework/Resources
|
| 92 |
+
ln -sf Versions/Current/${framework_name} ${build_dir}/framework/${framework_name}.framework/${framework_name}
|
| 93 |
+
|
| 94 |
+
# Set header and module paths
|
| 95 |
+
local header_path=${build_dir}/framework/${framework_name}.framework/Versions/A/Headers/
|
| 96 |
+
local module_path=${build_dir}/framework/${framework_name}.framework/Versions/A/Modules/
|
| 97 |
+
else
|
| 98 |
+
# iOS/VisionOS/tvOS use a flat structure
|
| 99 |
+
mkdir -p ${build_dir}/framework/${framework_name}.framework/Headers
|
| 100 |
+
mkdir -p ${build_dir}/framework/${framework_name}.framework/Modules
|
| 101 |
+
|
| 102 |
+
# Remove any existing structure to ensure clean build
|
| 103 |
+
rm -rf ${build_dir}/framework/${framework_name}.framework/Versions
|
| 104 |
+
|
| 105 |
+
# Set header and module paths
|
| 106 |
+
local header_path=${build_dir}/framework/${framework_name}.framework/Headers/
|
| 107 |
+
local module_path=${build_dir}/framework/${framework_name}.framework/Modules/
|
| 108 |
+
fi
|
| 109 |
+
|
| 110 |
+
# Copy all required headers (common for all platforms)
|
| 111 |
+
cp include/whisper.h ${header_path}
|
| 112 |
+
cp ggml/include/ggml.h ${header_path}
|
| 113 |
+
cp ggml/include/ggml-alloc.h ${header_path}
|
| 114 |
+
cp ggml/include/ggml-backend.h ${header_path}
|
| 115 |
+
cp ggml/include/ggml-metal.h ${header_path}
|
| 116 |
+
cp ggml/include/ggml-cpu.h ${header_path}
|
| 117 |
+
cp ggml/include/ggml-blas.h ${header_path}
|
| 118 |
+
cp ggml/include/gguf.h ${header_path}
|
| 119 |
+
|
| 120 |
+
# Create module map (common for all platforms)
|
| 121 |
+
cat > ${module_path}module.modulemap << EOF
|
| 122 |
+
framework module whisper {
|
| 123 |
+
header "whisper.h"
|
| 124 |
+
header "ggml.h"
|
| 125 |
+
header "ggml-alloc.h"
|
| 126 |
+
header "ggml-backend.h"
|
| 127 |
+
header "ggml-metal.h"
|
| 128 |
+
header "ggml-cpu.h"
|
| 129 |
+
header "ggml-blas.h"
|
| 130 |
+
header "gguf.h"
|
| 131 |
+
|
| 132 |
+
link "c++"
|
| 133 |
+
link framework "Accelerate"
|
| 134 |
+
link framework "Metal"
|
| 135 |
+
link framework "Foundation"
|
| 136 |
+
|
| 137 |
+
export *
|
| 138 |
+
}
|
| 139 |
+
EOF
|
| 140 |
+
|
| 141 |
+
# Platform-specific settings for Info.plist
|
| 142 |
+
local platform_name=""
|
| 143 |
+
local sdk_name=""
|
| 144 |
+
local supported_platform=""
|
| 145 |
+
|
| 146 |
+
case "$platform" in
|
| 147 |
+
"ios")
|
| 148 |
+
platform_name="iphoneos"
|
| 149 |
+
sdk_name="iphoneos${min_os_version}"
|
| 150 |
+
supported_platform="iPhoneOS"
|
| 151 |
+
local plist_path="${build_dir}/framework/${framework_name}.framework/Info.plist"
|
| 152 |
+
local device_family=' <key>UIDeviceFamily</key>
|
| 153 |
+
<array>
|
| 154 |
+
<integer>1</integer>
|
| 155 |
+
<integer>2</integer>
|
| 156 |
+
</array>'
|
| 157 |
+
;;
|
| 158 |
+
"macos")
|
| 159 |
+
platform_name="macosx"
|
| 160 |
+
sdk_name="macosx${min_os_version}"
|
| 161 |
+
supported_platform="MacOSX"
|
| 162 |
+
local plist_path="${build_dir}/framework/${framework_name}.framework/Versions/A/Resources/Info.plist"
|
| 163 |
+
local device_family=""
|
| 164 |
+
;;
|
| 165 |
+
"visionos")
|
| 166 |
+
platform_name="xros"
|
| 167 |
+
sdk_name="xros${min_os_version}"
|
| 168 |
+
supported_platform="XRPlatform"
|
| 169 |
+
local plist_path="${build_dir}/framework/${framework_name}.framework/Info.plist"
|
| 170 |
+
local device_family=""
|
| 171 |
+
;;
|
| 172 |
+
"tvos")
|
| 173 |
+
platform_name="appletvos"
|
| 174 |
+
sdk_name="appletvos${min_os_version}"
|
| 175 |
+
supported_platform="AppleTVOS"
|
| 176 |
+
local plist_path="${build_dir}/framework/${framework_name}.framework/Info.plist"
|
| 177 |
+
local device_family=' <key>UIDeviceFamily</key>
|
| 178 |
+
<array>
|
| 179 |
+
<integer>3</integer>
|
| 180 |
+
</array>'
|
| 181 |
+
;;
|
| 182 |
+
esac
|
| 183 |
+
|
| 184 |
+
# Create Info.plist
|
| 185 |
+
cat > ${plist_path} << EOF
|
| 186 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 187 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 188 |
+
<plist version="1.0">
|
| 189 |
+
<dict>
|
| 190 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 191 |
+
<string>en</string>
|
| 192 |
+
<key>CFBundleExecutable</key>
|
| 193 |
+
<string>whisper</string>
|
| 194 |
+
<key>CFBundleIdentifier</key>
|
| 195 |
+
<string>org.ggml.whisper</string>
|
| 196 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 197 |
+
<string>6.0</string>
|
| 198 |
+
<key>CFBundleName</key>
|
| 199 |
+
<string>whisper</string>
|
| 200 |
+
<key>CFBundlePackageType</key>
|
| 201 |
+
<string>FMWK</string>
|
| 202 |
+
<key>CFBundleShortVersionString</key>
|
| 203 |
+
<string>1.0</string>
|
| 204 |
+
<key>CFBundleVersion</key>
|
| 205 |
+
<string>1</string>
|
| 206 |
+
<key>MinimumOSVersion</key>
|
| 207 |
+
<string>${min_os_version}</string>
|
| 208 |
+
<key>CFBundleSupportedPlatforms</key>
|
| 209 |
+
<array>
|
| 210 |
+
<string>${supported_platform}</string>
|
| 211 |
+
</array>${device_family}
|
| 212 |
+
<key>DTPlatformName</key>
|
| 213 |
+
<string>${platform_name}</string>
|
| 214 |
+
<key>DTSDKName</key>
|
| 215 |
+
<string>${sdk_name}</string>
|
| 216 |
+
</dict>
|
| 217 |
+
</plist>
|
| 218 |
+
EOF
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
# Create dynamic libraries from static libraries.
|
| 222 |
+
combine_static_libraries() {
|
| 223 |
+
local build_dir="$1"
|
| 224 |
+
local release_dir="$2"
|
| 225 |
+
local platform="$3" # "ios", "macos", "visionos", or "tvos"
|
| 226 |
+
local is_simulator="$4"
|
| 227 |
+
local base_dir="$(pwd)"
|
| 228 |
+
local framework_name="whisper"
|
| 229 |
+
|
| 230 |
+
# Determine output path based on platform
|
| 231 |
+
local output_lib=""
|
| 232 |
+
if [[ "$platform" == "macos" ]]; then
|
| 233 |
+
# macOS uses versioned structure
|
| 234 |
+
output_lib="${build_dir}/framework/${framework_name}.framework/Versions/A/${framework_name}"
|
| 235 |
+
else
|
| 236 |
+
# iOS, visionOS, and tvOS use a directory flat structure
|
| 237 |
+
output_lib="${build_dir}/framework/${framework_name}.framework/${framework_name}"
|
| 238 |
+
fi
|
| 239 |
+
|
| 240 |
+
local libs=(
|
| 241 |
+
"${base_dir}/${build_dir}/src/${release_dir}/libwhisper.a"
|
| 242 |
+
"${base_dir}/${build_dir}/ggml/src/${release_dir}/libggml.a"
|
| 243 |
+
"${base_dir}/${build_dir}/ggml/src/${release_dir}/libggml-base.a"
|
| 244 |
+
"${base_dir}/${build_dir}/ggml/src/${release_dir}/libggml-cpu.a"
|
| 245 |
+
"${base_dir}/${build_dir}/ggml/src/ggml-metal/${release_dir}/libggml-metal.a"
|
| 246 |
+
"${base_dir}/${build_dir}/ggml/src/ggml-blas/${release_dir}/libggml-blas.a"
|
| 247 |
+
)
|
| 248 |
+
|
| 249 |
+
# Create temporary directory for processing
|
| 250 |
+
local temp_dir="${base_dir}/${build_dir}/temp"
|
| 251 |
+
mkdir -p "${temp_dir}"
|
| 252 |
+
|
| 253 |
+
# Since we have multiple architectures libtool will find object files that do not
|
| 254 |
+
# match the target architecture. We suppress these warnings.
|
| 255 |
+
libtool -static -o "${temp_dir}/combined.a" "${libs[@]}" 2> /dev/null
|
| 256 |
+
|
| 257 |
+
# Determine SDK, architectures, and install_name based on platform and simulator flag.
|
| 258 |
+
local sdk=""
|
| 259 |
+
local archs=""
|
| 260 |
+
local min_version_flag=""
|
| 261 |
+
local install_name=""
|
| 262 |
+
|
| 263 |
+
case "$platform" in
|
| 264 |
+
"ios")
|
| 265 |
+
if [[ "$is_simulator" == "true" ]]; then
|
| 266 |
+
sdk="iphonesimulator"
|
| 267 |
+
archs="arm64 x86_64"
|
| 268 |
+
min_version_flag="-mios-simulator-version-min=${IOS_MIN_OS_VERSION}"
|
| 269 |
+
else
|
| 270 |
+
sdk="iphoneos"
|
| 271 |
+
archs="arm64"
|
| 272 |
+
min_version_flag="-mios-version-min=${IOS_MIN_OS_VERSION}"
|
| 273 |
+
fi
|
| 274 |
+
install_name="@rpath/whisper.framework/whisper"
|
| 275 |
+
;;
|
| 276 |
+
"macos")
|
| 277 |
+
sdk="macosx"
|
| 278 |
+
archs="arm64 x86_64"
|
| 279 |
+
min_version_flag="-mmacosx-version-min=${MACOS_MIN_OS_VERSION}"
|
| 280 |
+
install_name="@rpath/whisper.framework/Versions/Current/whisper"
|
| 281 |
+
;;
|
| 282 |
+
"visionos")
|
| 283 |
+
if [[ "$is_simulator" == "true" ]]; then
|
| 284 |
+
sdk="xrsimulator"
|
| 285 |
+
archs="arm64 x86_64"
|
| 286 |
+
min_version_flag="-mtargetos=xros${VISIONOS_MIN_OS_VERSION}-simulator"
|
| 287 |
+
else
|
| 288 |
+
sdk="xros"
|
| 289 |
+
archs="arm64"
|
| 290 |
+
min_version_flag="-mtargetos=xros${VISIONOS_MIN_OS_VERSION}"
|
| 291 |
+
fi
|
| 292 |
+
# Use flat structure for visionOS, same as iOS
|
| 293 |
+
install_name="@rpath/whisper.framework/whisper"
|
| 294 |
+
;;
|
| 295 |
+
"tvos")
|
| 296 |
+
if [[ "$is_simulator" == "true" ]]; then
|
| 297 |
+
sdk="appletvsimulator"
|
| 298 |
+
archs="arm64 x86_64"
|
| 299 |
+
min_version_flag="-mtvos-simulator-version-min=${TVOS_MIN_OS_VERSION}"
|
| 300 |
+
else
|
| 301 |
+
sdk="appletvos"
|
| 302 |
+
archs="arm64"
|
| 303 |
+
min_version_flag="-mtvos-version-min=${TVOS_MIN_OS_VERSION}"
|
| 304 |
+
fi
|
| 305 |
+
install_name="@rpath/whisper.framework/whisper"
|
| 306 |
+
;;
|
| 307 |
+
esac
|
| 308 |
+
|
| 309 |
+
# Build architecture flags
|
| 310 |
+
local arch_flags=""
|
| 311 |
+
for arch in $archs; do
|
| 312 |
+
arch_flags+=" -arch $arch"
|
| 313 |
+
done
|
| 314 |
+
|
| 315 |
+
# Create dynamic library
|
| 316 |
+
echo "Creating dynamic library for ${platform}."
|
| 317 |
+
xcrun -sdk $sdk clang++ -dynamiclib \
|
| 318 |
+
-isysroot $(xcrun --sdk $sdk --show-sdk-path) \
|
| 319 |
+
$arch_flags \
|
| 320 |
+
$min_version_flag \
|
| 321 |
+
-Wl,-force_load,"${temp_dir}/combined.a" \
|
| 322 |
+
-framework Foundation -framework Metal -framework Accelerate \
|
| 323 |
+
-install_name "$install_name" \
|
| 324 |
+
-o "${base_dir}/${output_lib}"
|
| 325 |
+
|
| 326 |
+
# Platform-specific post-processing for device builds
|
| 327 |
+
if [[ "$is_simulator" == "false" ]]; then
|
| 328 |
+
if command -v vtool &>/dev/null; then
|
| 329 |
+
case "$platform" in
|
| 330 |
+
"ios")
|
| 331 |
+
echo "Marking binary as a framework binary for iOS..."
|
| 332 |
+
vtool -set-build-version ios ${IOS_MIN_OS_VERSION} ${IOS_MIN_OS_VERSION} -replace \
|
| 333 |
+
-output "${base_dir}/${output_lib}" "${base_dir}/${output_lib}"
|
| 334 |
+
;;
|
| 335 |
+
"visionos")
|
| 336 |
+
echo "Marking binary as a framework binary for visionOS..."
|
| 337 |
+
vtool -set-build-version xros ${VISIONOS_MIN_OS_VERSION} ${VISIONOS_MIN_OS_VERSION} -replace \
|
| 338 |
+
-output "${base_dir}/${output_lib}" "${base_dir}/${output_lib}"
|
| 339 |
+
;;
|
| 340 |
+
"tvos")
|
| 341 |
+
echo "Marking binary as a framework binary for tvOS..."
|
| 342 |
+
vtool -set-build-version tvos ${TVOS_MIN_OS_VERSION} ${TVOS_MIN_OS_VERSION} -replace \
|
| 343 |
+
-output "${base_dir}/${output_lib}" "${base_dir}/${output_lib}"
|
| 344 |
+
;;
|
| 345 |
+
esac
|
| 346 |
+
else
|
| 347 |
+
echo "Warning: vtool not found. Binary may not pass App Store validation."
|
| 348 |
+
fi
|
| 349 |
+
fi
|
| 350 |
+
|
| 351 |
+
echo "Creating properly formatted dSYM..."
|
| 352 |
+
# Create a separate directory for dSYMs for all platforms
|
| 353 |
+
mkdir -p "${base_dir}/${build_dir}/dSYMs"
|
| 354 |
+
|
| 355 |
+
# iOS and visionOS style dSYM (flat structure)
|
| 356 |
+
if [[ "$platform" == "ios" || "$platform" == "visionos" || "$platform" == "tvos" ]]; then
|
| 357 |
+
# Generate dSYM in the dSYMs directory
|
| 358 |
+
xcrun dsymutil "${base_dir}/${output_lib}" -o "${base_dir}/${build_dir}/dSYMs/whisper.dSYM"
|
| 359 |
+
|
| 360 |
+
# Create a copy of the binary that will be stripped
|
| 361 |
+
cp "${base_dir}/${output_lib}" "${temp_dir}/binary_to_strip"
|
| 362 |
+
|
| 363 |
+
# Strip debug symbols from the copy
|
| 364 |
+
xcrun strip -S "${temp_dir}/binary_to_strip" -o "${temp_dir}/stripped_lib"
|
| 365 |
+
|
| 366 |
+
# Replace the original with the stripped version
|
| 367 |
+
mv "${temp_dir}/stripped_lib" "${base_dir}/${output_lib}"
|
| 368 |
+
else
|
| 369 |
+
# macOS style dSYM
|
| 370 |
+
# First strip debug info to a separate file
|
| 371 |
+
xcrun strip -S "${base_dir}/${output_lib}" -o "${temp_dir}/stripped_lib"
|
| 372 |
+
|
| 373 |
+
# Generate dSYM in the dSYMs directory
|
| 374 |
+
xcrun dsymutil "${base_dir}/${output_lib}" -o "${base_dir}/${build_dir}/dSYMs/whisper.dSYM"
|
| 375 |
+
|
| 376 |
+
# Replace original binary with stripped version
|
| 377 |
+
mv "${temp_dir}/stripped_lib" "${base_dir}/${output_lib}"
|
| 378 |
+
fi
|
| 379 |
+
|
| 380 |
+
# Remove any automatically generated dSYM files in the framework structure as they will
|
| 381 |
+
# otherwise case Invalid Bundle Structure validation errors.
|
| 382 |
+
if [ -d "${base_dir}/${output_lib}.dSYM" ]; then
|
| 383 |
+
echo "Removing generated dSYM file in framework structure: ${base_dir}/${output_lib}.dSYM"
|
| 384 |
+
rm -rf "${base_dir}/${output_lib}.dSYM"
|
| 385 |
+
fi
|
| 386 |
+
|
| 387 |
+
# Clean up
|
| 388 |
+
rm -rf "${temp_dir}"
|
| 389 |
+
}
|
| 390 |
+
|
| 391 |
+
echo "Building for iOS simulator..."
|
| 392 |
+
cmake -B build-ios-sim -G Xcode \
|
| 393 |
+
"${COMMON_CMAKE_ARGS[@]}" \
|
| 394 |
+
-DCMAKE_OSX_DEPLOYMENT_TARGET=${IOS_MIN_OS_VERSION} \
|
| 395 |
+
-DIOS=ON \
|
| 396 |
+
-DCMAKE_SYSTEM_NAME=iOS \
|
| 397 |
+
-DCMAKE_OSX_SYSROOT=iphonesimulator \
|
| 398 |
+
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
| 399 |
+
-DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=iphonesimulator \
|
| 400 |
+
-DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
|
| 401 |
+
-DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
|
| 402 |
+
-S .
|
| 403 |
+
cmake --build build-ios-sim --config Release -- -quiet
|
| 404 |
+
|
| 405 |
+
echo "Building for iOS devices..."
|
| 406 |
+
cmake -B build-ios-device -G Xcode \
|
| 407 |
+
"${COMMON_CMAKE_ARGS[@]}" \
|
| 408 |
+
-DCMAKE_OSX_DEPLOYMENT_TARGET=${IOS_MIN_OS_VERSION} \
|
| 409 |
+
-DCMAKE_OSX_SYSROOT=iphoneos \
|
| 410 |
+
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
| 411 |
+
-DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=iphoneos \
|
| 412 |
+
-DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
|
| 413 |
+
-DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
|
| 414 |
+
-S .
|
| 415 |
+
cmake --build build-ios-device --config Release -- -quiet
|
| 416 |
+
|
| 417 |
+
echo "Building for macOS..."
|
| 418 |
+
cmake -B build-macos -G Xcode \
|
| 419 |
+
"${COMMON_CMAKE_ARGS[@]}" \
|
| 420 |
+
-DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOS_MIN_OS_VERSION} \
|
| 421 |
+
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
| 422 |
+
-DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
|
| 423 |
+
-DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
|
| 424 |
+
-S .
|
| 425 |
+
cmake --build build-macos --config Release -- -quiet
|
| 426 |
+
|
| 427 |
+
echo "Building for visionOS..."
|
| 428 |
+
cmake -B build-visionos -G Xcode \
|
| 429 |
+
"${COMMON_CMAKE_ARGS[@]}" \
|
| 430 |
+
-DCMAKE_OSX_DEPLOYMENT_TARGET=${VISIONOS_MIN_OS_VERSION} \
|
| 431 |
+
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
| 432 |
+
-DCMAKE_SYSTEM_NAME=visionOS \
|
| 433 |
+
-DCMAKE_OSX_SYSROOT=xros \
|
| 434 |
+
-DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=xros \
|
| 435 |
+
-DCMAKE_C_FLAGS="-D_XOPEN_SOURCE=700 -Du_int=unsigned\ int -Du_char=unsigned\ char -Du_short=unsigned\ short ${COMMON_C_FLAGS}" \
|
| 436 |
+
-DCMAKE_CXX_FLAGS="-D_XOPEN_SOURCE=700 -Du_int=unsigned\ int -Du_char=unsigned\ char -Du_short=unsigned\ short ${COMMON_CXX_FLAGS}" \
|
| 437 |
+
-S .
|
| 438 |
+
cmake --build build-visionos --config Release -- -quiet
|
| 439 |
+
|
| 440 |
+
echo "Building for visionOS simulator..."
|
| 441 |
+
cmake -B build-visionos-sim -G Xcode \
|
| 442 |
+
"${COMMON_CMAKE_ARGS[@]}" \
|
| 443 |
+
-DCMAKE_OSX_DEPLOYMENT_TARGET=${VISIONOS_MIN_OS_VERSION} \
|
| 444 |
+
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
| 445 |
+
-DCMAKE_SYSTEM_NAME=visionOS \
|
| 446 |
+
-DCMAKE_OSX_SYSROOT=xrsimulator \
|
| 447 |
+
-DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=xrsimulator \
|
| 448 |
+
-DCMAKE_C_FLAGS="-D_XOPEN_SOURCE=700 -Du_int=unsigned\ int -Du_char=unsigned\ char -Du_short=unsigned\ short ${COMMON_C_FLAGS}" \
|
| 449 |
+
-DCMAKE_CXX_FLAGS="-D_XOPEN_SOURCE=700 -Du_int=unsigned\ int -Du_char=unsigned\ char -Du_short=unsigned\ short ${COMMON_CXX_FLAGS}" \
|
| 450 |
+
-S .
|
| 451 |
+
cmake --build build-visionos-sim --config Release -- -quiet
|
| 452 |
+
|
| 453 |
+
# Add tvOS builds (might need the same u_int definitions as watchOS and visionOS)
|
| 454 |
+
echo "Building for tvOS simulator..."
|
| 455 |
+
cmake -B build-tvos-sim -G Xcode \
|
| 456 |
+
"${COMMON_CMAKE_ARGS[@]}" \
|
| 457 |
+
-DCMAKE_OSX_DEPLOYMENT_TARGET=${TVOS_MIN_OS_VERSION} \
|
| 458 |
+
-DCMAKE_SYSTEM_NAME=tvOS \
|
| 459 |
+
-DCMAKE_OSX_SYSROOT=appletvsimulator \
|
| 460 |
+
-DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
|
| 461 |
+
-DGGML_METAL=ON \
|
| 462 |
+
-DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=appletvsimulator \
|
| 463 |
+
-DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
|
| 464 |
+
-DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
|
| 465 |
+
-S .
|
| 466 |
+
cmake --build build-tvos-sim --config Release -- -quiet
|
| 467 |
+
|
| 468 |
+
echo "Building for tvOS devices..."
|
| 469 |
+
cmake -B build-tvos-device -G Xcode \
|
| 470 |
+
"${COMMON_CMAKE_ARGS[@]}" \
|
| 471 |
+
-DCMAKE_OSX_DEPLOYMENT_TARGET=${TVOS_MIN_OS_VERSION} \
|
| 472 |
+
-DCMAKE_SYSTEM_NAME=tvOS \
|
| 473 |
+
-DCMAKE_OSX_SYSROOT=appletvos \
|
| 474 |
+
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
| 475 |
+
-DGGML_METAL=ON \
|
| 476 |
+
-DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=appletvos \
|
| 477 |
+
-DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
|
| 478 |
+
-DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
|
| 479 |
+
-S .
|
| 480 |
+
cmake --build build-tvos-device --config Release -- -quiet
|
| 481 |
+
|
| 482 |
+
# Setup frameworks and copy binaries and headers
|
| 483 |
+
echo "Setting up framework structures..."
|
| 484 |
+
setup_framework_structure "build-ios-sim" ${IOS_MIN_OS_VERSION} "ios"
|
| 485 |
+
setup_framework_structure "build-ios-device" ${IOS_MIN_OS_VERSION} "ios"
|
| 486 |
+
setup_framework_structure "build-macos" ${MACOS_MIN_OS_VERSION} "macos"
|
| 487 |
+
setup_framework_structure "build-visionos" ${VISIONOS_MIN_OS_VERSION} "visionos"
|
| 488 |
+
setup_framework_structure "build-visionos-sim" ${VISIONOS_MIN_OS_VERSION} "visionos"
|
| 489 |
+
setup_framework_structure "build-tvos-sim" ${TVOS_MIN_OS_VERSION} "tvos"
|
| 490 |
+
setup_framework_structure "build-tvos-device" ${TVOS_MIN_OS_VERSION} "tvos"
|
| 491 |
+
|
| 492 |
+
# Create dynamic libraries from static libraries
|
| 493 |
+
echo "Creating dynamic libraries from static libraries..."
|
| 494 |
+
combine_static_libraries "build-ios-sim" "Release-iphonesimulator" "ios" "true"
|
| 495 |
+
combine_static_libraries "build-ios-device" "Release-iphoneos" "ios" "false"
|
| 496 |
+
combine_static_libraries "build-macos" "Release" "macos" "false"
|
| 497 |
+
combine_static_libraries "build-visionos" "Release-xros" "visionos" "false"
|
| 498 |
+
combine_static_libraries "build-visionos-sim" "Release-xrsimulator" "visionos" "true"
|
| 499 |
+
combine_static_libraries "build-tvos-sim" "Release-appletvsimulator" "tvos" "true"
|
| 500 |
+
combine_static_libraries "build-tvos-device" "Release-appletvos" "tvos" "false"
|
| 501 |
+
|
| 502 |
+
# Create XCFramework with correct debug symbols paths
|
| 503 |
+
echo "Creating XCFramework..."
|
| 504 |
+
xcodebuild -create-xcframework \
|
| 505 |
+
-framework $(pwd)/build-ios-sim/framework/whisper.framework \
|
| 506 |
+
-debug-symbols $(pwd)/build-ios-sim/dSYMs/whisper.dSYM \
|
| 507 |
+
-framework $(pwd)/build-ios-device/framework/whisper.framework \
|
| 508 |
+
-debug-symbols $(pwd)/build-ios-device/dSYMs/whisper.dSYM \
|
| 509 |
+
-framework $(pwd)/build-macos/framework/whisper.framework \
|
| 510 |
+
-debug-symbols $(pwd)/build-macos/dSYMS/whisper.dSYM \
|
| 511 |
+
-framework $(pwd)/build-visionos/framework/whisper.framework \
|
| 512 |
+
-debug-symbols $(pwd)/build-visionos/dSYMs/whisper.dSYM \
|
| 513 |
+
-framework $(pwd)/build-visionos-sim/framework/whisper.framework \
|
| 514 |
+
-debug-symbols $(pwd)/build-visionos-sim/dSYMs/whisper.dSYM \
|
| 515 |
+
-framework $(pwd)/build-tvos-device/framework/whisper.framework \
|
| 516 |
+
-debug-symbols $(pwd)/build-tvos-device/dSYMs/whisper.dSYM \
|
| 517 |
+
-framework $(pwd)/build-tvos-sim/framework/whisper.framework \
|
| 518 |
+
-debug-symbols $(pwd)/build-tvos-sim/dSYMs/whisper.dSYM \
|
| 519 |
+
-output $(pwd)/build-apple/whisper.xcframework
|
examples/whisper.swiftui/README.md
CHANGED
|
@@ -1,7 +1,29 @@
|
|
|
|
|
|
|
|
| 1 |
A sample SwiftUI app using [whisper.cpp](https://github.com/ggerganov/whisper.cpp/) to do voice-to-text transcriptions.
|
| 2 |
See also: [whisper.objc](https://github.com/ggerganov/whisper.cpp/tree/master/examples/whisper.objc).
|
| 3 |
|
| 4 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
1. Select a model from the [whisper.cpp repository](https://github.com/ggerganov/whisper.cpp/tree/master/models).[^1]
|
| 7 |
2. Add the model to `whisper.swiftui.demo/Resources/models` **via Xcode**.
|
|
|
|
| 1 |
+
# whisper.cpp/examples/whisper.swiftui
|
| 2 |
+
|
| 3 |
A sample SwiftUI app using [whisper.cpp](https://github.com/ggerganov/whisper.cpp/) to do voice-to-text transcriptions.
|
| 4 |
See also: [whisper.objc](https://github.com/ggerganov/whisper.cpp/tree/master/examples/whisper.objc).
|
| 5 |
|
| 6 |
+
### Building
|
| 7 |
+
First whisper.cpp need to be built and a XCFramework needs to be created. This can be done by running
|
| 8 |
+
the following script from the whisper.cpp project root:
|
| 9 |
+
```console
|
| 10 |
+
$ ./build-xcframework.sh
|
| 11 |
+
```
|
| 12 |
+
|
| 13 |
+
Note: if you get the error "iphoneos is not an iOS SDK" then you probably need to run this command first:
|
| 14 |
+
```console
|
| 15 |
+
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer
|
| 16 |
+
```
|
| 17 |
+
|
| 18 |
+
Open `whisper.swiftui.xcodeproj` project in Xcode and you should be able to build and run the app on
|
| 19 |
+
a simulator or a real device.
|
| 20 |
+
|
| 21 |
+
To use the framework with a different project, the XCFramework can be added to the project by
|
| 22 |
+
adding `build-apple/whisper.xcframework` by dragging and dropping it into the project navigator, or
|
| 23 |
+
by manually selecting the framework in the "Frameworks, Libraries, and Embedded Content" section
|
| 24 |
+
of the project settings.
|
| 25 |
+
|
| 26 |
+
### Usage
|
| 27 |
|
| 28 |
1. Select a model from the [whisper.cpp repository](https://github.com/ggerganov/whisper.cpp/tree/master/models).[^1]
|
| 29 |
2. Add the model to `whisper.swiftui.demo/Resources/models` **via Xcode**.
|
examples/whisper.swiftui/whisper.swiftui.xcodeproj/project.pbxproj
CHANGED
|
@@ -17,11 +17,26 @@
|
|
| 17 |
0AAC5D9F29539CD0003032C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AAC5D9E29539CD0003032C3 /* Assets.xcassets */; };
|
| 18 |
0AAC5DCE2953A05C003032C3 /* WhisperState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5DCD2953A05C003032C3 /* WhisperState.swift */; };
|
| 19 |
0AAC5DD12953A394003032C3 /* LibWhisper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5DD02953A394003032C3 /* LibWhisper.swift */; };
|
|
|
|
|
|
|
| 20 |
7F79E0EE2CE0A78000ACD7BF /* DownloadButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F79E0ED2CE0A78000ACD7BF /* DownloadButton.swift */; };
|
| 21 |
7F79E0F02CE0C6F700ACD7BF /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F79E0EF2CE0C6F700ACD7BF /* Model.swift */; };
|
| 22 |
-
E3F92DC52AFA8E3800A6A9D4 /* whisper in Frameworks */ = {isa = PBXBuildFile; productRef = E3F92DC42AFA8E3800A6A9D4 /* whisper */; };
|
| 23 |
/* End PBXBuildFile section */
|
| 24 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
/* Begin PBXFileReference section */
|
| 26 |
0A8E48FF2954B3F100704C1B /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
| 27 |
0AA751462953AC2E001EE061 /* samples */ = {isa = PBXFileReference; lastKnownFileType = folder; path = samples; sourceTree = "<group>"; };
|
|
@@ -35,9 +50,9 @@
|
|
| 35 |
0AAC5DA029539CD0003032C3 /* WhisperCppDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WhisperCppDemo.entitlements; sourceTree = "<group>"; };
|
| 36 |
0AAC5DCD2953A05C003032C3 /* WhisperState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhisperState.swift; sourceTree = "<group>"; };
|
| 37 |
0AAC5DD02953A394003032C3 /* LibWhisper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibWhisper.swift; sourceTree = "<group>"; };
|
|
|
|
| 38 |
7F79E0ED2CE0A78000ACD7BF /* DownloadButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadButton.swift; sourceTree = "<group>"; };
|
| 39 |
7F79E0EF2CE0C6F700ACD7BF /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = "<group>"; };
|
| 40 |
-
E3F92DC22AFA8DD800A6A9D4 /* whisper.cpp */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = whisper.cpp; path = ../..; sourceTree = "<group>"; };
|
| 41 |
/* End PBXFileReference section */
|
| 42 |
|
| 43 |
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -45,7 +60,7 @@
|
|
| 45 |
isa = PBXFrameworksBuildPhase;
|
| 46 |
buildActionMask = 2147483647;
|
| 47 |
files = (
|
| 48 |
-
|
| 49 |
);
|
| 50 |
runOnlyForDeploymentPostprocessing = 0;
|
| 51 |
};
|
|
@@ -82,7 +97,6 @@
|
|
| 82 |
0AAC5D8E29539CCF003032C3 = {
|
| 83 |
isa = PBXGroup;
|
| 84 |
children = (
|
| 85 |
-
E3F92DC22AFA8DD800A6A9D4 /* whisper.cpp */,
|
| 86 |
0A8E48FF2954B3F100704C1B /* README.md */,
|
| 87 |
0AAC5DCF2953A36C003032C3 /* whisper.cpp.swift */,
|
| 88 |
0AAC5D9929539CCF003032C3 /* whisper.swiftui.demo */,
|
|
@@ -141,6 +155,7 @@
|
|
| 141 |
E3F92DC32AFA8E3800A6A9D4 /* Frameworks */ = {
|
| 142 |
isa = PBXGroup;
|
| 143 |
children = (
|
|
|
|
| 144 |
);
|
| 145 |
name = Frameworks;
|
| 146 |
sourceTree = "<group>";
|
|
@@ -155,6 +170,7 @@
|
|
| 155 |
0AAC5D9329539CCF003032C3 /* Sources */,
|
| 156 |
0AAC5D9429539CCF003032C3 /* Frameworks */,
|
| 157 |
0AAC5D9529539CCF003032C3 /* Resources */,
|
|
|
|
| 158 |
);
|
| 159 |
buildRules = (
|
| 160 |
);
|
|
@@ -162,7 +178,6 @@
|
|
| 162 |
);
|
| 163 |
name = whisper.swiftui;
|
| 164 |
packageProductDependencies = (
|
| 165 |
-
E3F92DC42AFA8E3800A6A9D4 /* whisper */,
|
| 166 |
);
|
| 167 |
productName = WhisperCppDemo;
|
| 168 |
productReference = 0AAC5D9729539CCF003032C3 /* whisper.swiftui.app */;
|
|
@@ -456,13 +471,6 @@
|
|
| 456 |
defaultConfigurationName = Release;
|
| 457 |
};
|
| 458 |
/* End XCConfigurationList section */
|
| 459 |
-
|
| 460 |
-
/* Begin XCSwiftPackageProductDependency section */
|
| 461 |
-
E3F92DC42AFA8E3800A6A9D4 /* whisper */ = {
|
| 462 |
-
isa = XCSwiftPackageProductDependency;
|
| 463 |
-
productName = whisper;
|
| 464 |
-
};
|
| 465 |
-
/* End XCSwiftPackageProductDependency section */
|
| 466 |
};
|
| 467 |
rootObject = 0AAC5D8F29539CCF003032C3 /* Project object */;
|
| 468 |
}
|
|
|
|
| 17 |
0AAC5D9F29539CD0003032C3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AAC5D9E29539CD0003032C3 /* Assets.xcassets */; };
|
| 18 |
0AAC5DCE2953A05C003032C3 /* WhisperState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5DCD2953A05C003032C3 /* WhisperState.swift */; };
|
| 19 |
0AAC5DD12953A394003032C3 /* LibWhisper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AAC5DD02953A394003032C3 /* LibWhisper.swift */; };
|
| 20 |
+
5B3454FF2D8178F80005A3BC /* whisper.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B3454FE2D8178F80005A3BC /* whisper.xcframework */; };
|
| 21 |
+
5B3455002D8178F80005A3BC /* whisper.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5B3454FE2D8178F80005A3BC /* whisper.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
| 22 |
7F79E0EE2CE0A78000ACD7BF /* DownloadButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F79E0ED2CE0A78000ACD7BF /* DownloadButton.swift */; };
|
| 23 |
7F79E0F02CE0C6F700ACD7BF /* Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F79E0EF2CE0C6F700ACD7BF /* Model.swift */; };
|
|
|
|
| 24 |
/* End PBXBuildFile section */
|
| 25 |
|
| 26 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 27 |
+
5B3455012D8178F80005A3BC /* Embed Frameworks */ = {
|
| 28 |
+
isa = PBXCopyFilesBuildPhase;
|
| 29 |
+
buildActionMask = 2147483647;
|
| 30 |
+
dstPath = "";
|
| 31 |
+
dstSubfolderSpec = 10;
|
| 32 |
+
files = (
|
| 33 |
+
5B3455002D8178F80005A3BC /* whisper.xcframework in Embed Frameworks */,
|
| 34 |
+
);
|
| 35 |
+
name = "Embed Frameworks";
|
| 36 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 37 |
+
};
|
| 38 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 39 |
+
|
| 40 |
/* Begin PBXFileReference section */
|
| 41 |
0A8E48FF2954B3F100704C1B /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
|
| 42 |
0AA751462953AC2E001EE061 /* samples */ = {isa = PBXFileReference; lastKnownFileType = folder; path = samples; sourceTree = "<group>"; };
|
|
|
|
| 50 |
0AAC5DA029539CD0003032C3 /* WhisperCppDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WhisperCppDemo.entitlements; sourceTree = "<group>"; };
|
| 51 |
0AAC5DCD2953A05C003032C3 /* WhisperState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhisperState.swift; sourceTree = "<group>"; };
|
| 52 |
0AAC5DD02953A394003032C3 /* LibWhisper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibWhisper.swift; sourceTree = "<group>"; };
|
| 53 |
+
5B3454FE2D8178F80005A3BC /* whisper.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = whisper.xcframework; path = "../../build-apple/whisper.xcframework"; sourceTree = "<group>"; };
|
| 54 |
7F79E0ED2CE0A78000ACD7BF /* DownloadButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadButton.swift; sourceTree = "<group>"; };
|
| 55 |
7F79E0EF2CE0C6F700ACD7BF /* Model.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Model.swift; sourceTree = "<group>"; };
|
|
|
|
| 56 |
/* End PBXFileReference section */
|
| 57 |
|
| 58 |
/* Begin PBXFrameworksBuildPhase section */
|
|
|
|
| 60 |
isa = PBXFrameworksBuildPhase;
|
| 61 |
buildActionMask = 2147483647;
|
| 62 |
files = (
|
| 63 |
+
5B3454FF2D8178F80005A3BC /* whisper.xcframework in Frameworks */,
|
| 64 |
);
|
| 65 |
runOnlyForDeploymentPostprocessing = 0;
|
| 66 |
};
|
|
|
|
| 97 |
0AAC5D8E29539CCF003032C3 = {
|
| 98 |
isa = PBXGroup;
|
| 99 |
children = (
|
|
|
|
| 100 |
0A8E48FF2954B3F100704C1B /* README.md */,
|
| 101 |
0AAC5DCF2953A36C003032C3 /* whisper.cpp.swift */,
|
| 102 |
0AAC5D9929539CCF003032C3 /* whisper.swiftui.demo */,
|
|
|
|
| 155 |
E3F92DC32AFA8E3800A6A9D4 /* Frameworks */ = {
|
| 156 |
isa = PBXGroup;
|
| 157 |
children = (
|
| 158 |
+
5B3454FE2D8178F80005A3BC /* whisper.xcframework */,
|
| 159 |
);
|
| 160 |
name = Frameworks;
|
| 161 |
sourceTree = "<group>";
|
|
|
|
| 170 |
0AAC5D9329539CCF003032C3 /* Sources */,
|
| 171 |
0AAC5D9429539CCF003032C3 /* Frameworks */,
|
| 172 |
0AAC5D9529539CCF003032C3 /* Resources */,
|
| 173 |
+
5B3455012D8178F80005A3BC /* Embed Frameworks */,
|
| 174 |
);
|
| 175 |
buildRules = (
|
| 176 |
);
|
|
|
|
| 178 |
);
|
| 179 |
name = whisper.swiftui;
|
| 180 |
packageProductDependencies = (
|
|
|
|
| 181 |
);
|
| 182 |
productName = WhisperCppDemo;
|
| 183 |
productReference = 0AAC5D9729539CCF003032C3 /* whisper.swiftui.app */;
|
|
|
|
| 471 |
defaultConfigurationName = Release;
|
| 472 |
};
|
| 473 |
/* End XCConfigurationList section */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 474 |
};
|
| 475 |
rootObject = 0AAC5D8F29539CCF003032C3 /* Project object */;
|
| 476 |
}
|
scripts/apple/validate-apps.sh
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
./scripts/apple/validate-ios.sh
|
| 3 |
+
./scripts/apple/validate-macos.sh
|
| 4 |
+
./scripts/apple/validate-visionos.sh
|
| 5 |
+
./scripts/apple/validate-tvos.sh
|
scripts/apple/validate-ios.sh
ADDED
|
@@ -0,0 +1,817 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# validate-ios.sh - Validate iOS Application with embedded whisper.xcframework using SwiftUI
|
| 3 |
+
|
| 4 |
+
# Authentication options (optional) (can be set via environment variables)
|
| 5 |
+
# To use: export [email protected]
|
| 6 |
+
# export APPLE_PASSWORD=your-app-specific-password
|
| 7 |
+
# ./validate-ios.sh
|
| 8 |
+
APPLE_ID=${APPLE_ID:-""}
|
| 9 |
+
APPLE_PASSWORD=${APPLE_PASSWORD:-""}
|
| 10 |
+
|
| 11 |
+
# Ensure the script exits on error
|
| 12 |
+
set -e
|
| 13 |
+
|
| 14 |
+
# Function to print usage instructions
|
| 15 |
+
print_usage() {
|
| 16 |
+
echo "Usage: ./validate-ios.sh [OPTIONS]"
|
| 17 |
+
echo ""
|
| 18 |
+
echo "Options:"
|
| 19 |
+
echo " --help Show this help message"
|
| 20 |
+
echo " --apple-id EMAIL Apple ID email for validation"
|
| 21 |
+
echo " --apple-password PWD App-specific password for Apple ID"
|
| 22 |
+
echo ""
|
| 23 |
+
echo "Environment variables:"
|
| 24 |
+
echo " APPLE_ID Apple ID email for validation"
|
| 25 |
+
echo " APPLE_PASSWORD App-specific password for Apple ID"
|
| 26 |
+
echo ""
|
| 27 |
+
echo "Notes:"
|
| 28 |
+
echo " - Command line options take precedence over environment variables"
|
| 29 |
+
echo " - Authentication is optional. If not provided, alternative validation will be performed"
|
| 30 |
+
echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
# Parse command line arguments
|
| 34 |
+
while [[ $# -gt 0 ]]; do
|
| 35 |
+
case $1 in
|
| 36 |
+
--help)
|
| 37 |
+
print_usage
|
| 38 |
+
exit 0
|
| 39 |
+
;;
|
| 40 |
+
--apple-id)
|
| 41 |
+
APPLE_ID="$2"
|
| 42 |
+
shift 2
|
| 43 |
+
;;
|
| 44 |
+
--apple-password)
|
| 45 |
+
APPLE_PASSWORD="$2"
|
| 46 |
+
shift 2
|
| 47 |
+
;;
|
| 48 |
+
*)
|
| 49 |
+
echo "Unknown option: $1"
|
| 50 |
+
print_usage
|
| 51 |
+
exit 1
|
| 52 |
+
;;
|
| 53 |
+
esac
|
| 54 |
+
done
|
| 55 |
+
|
| 56 |
+
# Function to clean up in case of error
|
| 57 |
+
cleanup() {
|
| 58 |
+
# Don't clean up temp files on error to help with debugging
|
| 59 |
+
echo "===== iOS Validation Process Failed ====="
|
| 60 |
+
exit 1
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
# Set up trap to call cleanup function on error
|
| 64 |
+
trap cleanup ERR
|
| 65 |
+
|
| 66 |
+
set -e # Exit on any error
|
| 67 |
+
|
| 68 |
+
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
| 69 |
+
BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
|
| 70 |
+
|
| 71 |
+
# Configuration
|
| 72 |
+
APP_NAME="iOSWhisperTest"
|
| 73 |
+
BUNDLE_ID="org.ggml.iOSWhisperTest"
|
| 74 |
+
XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/whisper.xcframework"
|
| 75 |
+
TEMP_DIR="${BUILD_DIR}/temp"
|
| 76 |
+
ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
|
| 77 |
+
IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
|
| 78 |
+
VALIDATION_DIR="${BUILD_DIR}/validation"
|
| 79 |
+
|
| 80 |
+
# Create necessary directories
|
| 81 |
+
mkdir -p "${BUILD_DIR}"
|
| 82 |
+
mkdir -p "${TEMP_DIR}"
|
| 83 |
+
mkdir -p "${VALIDATION_DIR}"
|
| 84 |
+
|
| 85 |
+
echo "===== iOS Validation Process Started ====="
|
| 86 |
+
|
| 87 |
+
# 1. Create a simple test app project
|
| 88 |
+
echo "Creating test iOS app project..."
|
| 89 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
|
| 90 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
|
| 91 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 92 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 93 |
+
<plist version="1.0">
|
| 94 |
+
<dict>
|
| 95 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 96 |
+
<string>en</string>
|
| 97 |
+
<key>CFBundleExecutable</key>
|
| 98 |
+
<string>${APP_NAME}</string>
|
| 99 |
+
<key>CFBundleIdentifier</key>
|
| 100 |
+
<string>${BUNDLE_ID}</string>
|
| 101 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 102 |
+
<string>6.0</string>
|
| 103 |
+
<key>CFBundleName</key>
|
| 104 |
+
<string>${APP_NAME}</string>
|
| 105 |
+
<key>CFBundlePackageType</key>
|
| 106 |
+
<string>APPL</string>
|
| 107 |
+
<key>CFBundleShortVersionString</key>
|
| 108 |
+
<string>1.0</string>
|
| 109 |
+
<key>CFBundleVersion</key>
|
| 110 |
+
<string>1</string>
|
| 111 |
+
<key>LSRequiresIPhoneOS</key>
|
| 112 |
+
<true/>
|
| 113 |
+
<key>UILaunchScreen</key>
|
| 114 |
+
<dict/>
|
| 115 |
+
<key>UIRequiredDeviceCapabilities</key>
|
| 116 |
+
<array>
|
| 117 |
+
<string>armv7</string>
|
| 118 |
+
</array>
|
| 119 |
+
<key>UISupportedInterfaceOrientations</key>
|
| 120 |
+
<array>
|
| 121 |
+
<string>UIInterfaceOrientationPortrait</string>
|
| 122 |
+
</array>
|
| 123 |
+
</dict>
|
| 124 |
+
</plist>
|
| 125 |
+
EOF
|
| 126 |
+
|
| 127 |
+
# Create SwiftUI app files
|
| 128 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
|
| 129 |
+
|
| 130 |
+
# Create App.swift
|
| 131 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
|
| 132 |
+
import SwiftUI
|
| 133 |
+
import whisper
|
| 134 |
+
|
| 135 |
+
@main
|
| 136 |
+
struct WhisperTestApp: App {
|
| 137 |
+
var body: some Scene {
|
| 138 |
+
WindowGroup {
|
| 139 |
+
ContentView()
|
| 140 |
+
}
|
| 141 |
+
}
|
| 142 |
+
}
|
| 143 |
+
EOF
|
| 144 |
+
|
| 145 |
+
# Create ContentView.swift
|
| 146 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
|
| 147 |
+
import SwiftUI
|
| 148 |
+
import whisper
|
| 149 |
+
|
| 150 |
+
struct ContentView: View {
|
| 151 |
+
// Test that we can initialize a whisper context params struct
|
| 152 |
+
let params = whisper_context_default_params()
|
| 153 |
+
|
| 154 |
+
var body: some View {
|
| 155 |
+
VStack(spacing: 20) {
|
| 156 |
+
Text("Whisper Framework Test")
|
| 157 |
+
.font(.largeTitle)
|
| 158 |
+
.padding()
|
| 159 |
+
|
| 160 |
+
Text("whisper_context_default_params() created successfully")
|
| 161 |
+
.font(.headline)
|
| 162 |
+
.multilineTextAlignment(.center)
|
| 163 |
+
.padding()
|
| 164 |
+
|
| 165 |
+
// Display some param values to confirm the framework is working
|
| 166 |
+
Text("dtw_n_top: \(params.dtw_n_top)")
|
| 167 |
+
.font(.body)
|
| 168 |
+
|
| 169 |
+
Spacer()
|
| 170 |
+
}
|
| 171 |
+
.padding()
|
| 172 |
+
}
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
struct ContentView_Previews: PreviewProvider {
|
| 176 |
+
static var previews: some View {
|
| 177 |
+
ContentView()
|
| 178 |
+
}
|
| 179 |
+
}
|
| 180 |
+
EOF
|
| 181 |
+
|
| 182 |
+
# Create project.pbxproj, fixing the framework search paths issues
|
| 183 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
|
| 184 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 185 |
+
// !$*UTF8*$!
|
| 186 |
+
{
|
| 187 |
+
archiveVersion = 1;
|
| 188 |
+
classes = {
|
| 189 |
+
};
|
| 190 |
+
objectVersion = 54;
|
| 191 |
+
objects = {
|
| 192 |
+
|
| 193 |
+
/* Begin PBXBuildFile section */
|
| 194 |
+
11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
|
| 195 |
+
33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
|
| 196 |
+
55555555555555555555555 /* whisper.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 197 |
+
77777777777777777777777 /* whisper.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 198 |
+
/* End PBXBuildFile section */
|
| 199 |
+
|
| 200 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 201 |
+
88888888888888888888888 /* Embed Frameworks */ = {
|
| 202 |
+
isa = PBXCopyFilesBuildPhase;
|
| 203 |
+
buildActionMask = 2147483647;
|
| 204 |
+
dstPath = "";
|
| 205 |
+
dstSubfolderSpec = 10;
|
| 206 |
+
files = (
|
| 207 |
+
77777777777777777777777 /* whisper.xcframework in Embed Frameworks */,
|
| 208 |
+
);
|
| 209 |
+
name = "Embed Frameworks";
|
| 210 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 211 |
+
};
|
| 212 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 213 |
+
|
| 214 |
+
/* Begin PBXFileReference section */
|
| 215 |
+
EOF
|
| 216 |
+
|
| 217 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 218 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 219 |
+
99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 220 |
+
22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
| 221 |
+
44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
| 222 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
| 223 |
+
66666666666666666666666 /* whisper.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = whisper.xcframework; sourceTree = "<group>"; };
|
| 224 |
+
/* End PBXFileReference section */
|
| 225 |
+
EOF
|
| 226 |
+
|
| 227 |
+
# Add the rest of the project file with fixed framework search paths
|
| 228 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 229 |
+
/* Begin PBXFrameworksBuildPhase section */
|
| 230 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
|
| 231 |
+
isa = PBXFrameworksBuildPhase;
|
| 232 |
+
buildActionMask = 2147483647;
|
| 233 |
+
files = (
|
| 234 |
+
55555555555555555555555 /* whisper.xcframework in Frameworks */,
|
| 235 |
+
);
|
| 236 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 237 |
+
};
|
| 238 |
+
/* End PBXFrameworksBuildPhase section */
|
| 239 |
+
|
| 240 |
+
/* Begin PBXGroup section */
|
| 241 |
+
EOF
|
| 242 |
+
|
| 243 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 244 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 245 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
|
| 246 |
+
isa = PBXGroup;
|
| 247 |
+
children = (
|
| 248 |
+
99999999999999999999999 /* ${APP_NAME}.app */,
|
| 249 |
+
);
|
| 250 |
+
name = Products;
|
| 251 |
+
sourceTree = "<group>";
|
| 252 |
+
};
|
| 253 |
+
EOF
|
| 254 |
+
|
| 255 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 256 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
|
| 257 |
+
isa = PBXGroup;
|
| 258 |
+
children = (
|
| 259 |
+
66666666666666666666666 /* whisper.xcframework */,
|
| 260 |
+
);
|
| 261 |
+
name = Frameworks;
|
| 262 |
+
sourceTree = "<group>";
|
| 263 |
+
};
|
| 264 |
+
EEEEEEEEEEEEEEEEEEEEEEEE = {
|
| 265 |
+
isa = PBXGroup;
|
| 266 |
+
children = (
|
| 267 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* iOSWhisperTest */,
|
| 268 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
|
| 269 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
|
| 270 |
+
);
|
| 271 |
+
sourceTree = "<group>";
|
| 272 |
+
};
|
| 273 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* iOSWhisperTest */ = {
|
| 274 |
+
isa = PBXGroup;
|
| 275 |
+
children = (
|
| 276 |
+
1111111111111111111111AA /* Sources */,
|
| 277 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
|
| 278 |
+
);
|
| 279 |
+
path = "iOSWhisperTest";
|
| 280 |
+
sourceTree = "<group>";
|
| 281 |
+
};
|
| 282 |
+
1111111111111111111111AA /* Sources */ = {
|
| 283 |
+
isa = PBXGroup;
|
| 284 |
+
children = (
|
| 285 |
+
22222222222222222222222 /* App.swift */,
|
| 286 |
+
44444444444444444444444 /* ContentView.swift */,
|
| 287 |
+
);
|
| 288 |
+
path = Sources;
|
| 289 |
+
sourceTree = "<group>";
|
| 290 |
+
};
|
| 291 |
+
/* End PBXGroup section */
|
| 292 |
+
EOF
|
| 293 |
+
|
| 294 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 295 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 296 |
+
/* Begin PBXNativeTarget section */
|
| 297 |
+
3333333333333333333333AA /* ${APP_NAME} */ = {
|
| 298 |
+
isa = PBXNativeTarget;
|
| 299 |
+
buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
|
| 300 |
+
buildPhases = (
|
| 301 |
+
5555555555555555555555AA /* Sources */,
|
| 302 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
|
| 303 |
+
6666666666666666666666AA /* Resources */,
|
| 304 |
+
88888888888888888888888 /* Embed Frameworks */,
|
| 305 |
+
);
|
| 306 |
+
buildRules = (
|
| 307 |
+
);
|
| 308 |
+
dependencies = (
|
| 309 |
+
);
|
| 310 |
+
name = "${APP_NAME}";
|
| 311 |
+
productName = "${APP_NAME}";
|
| 312 |
+
productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
|
| 313 |
+
productType = "com.apple.product-type.application";
|
| 314 |
+
};
|
| 315 |
+
/* End PBXNativeTarget section */
|
| 316 |
+
|
| 317 |
+
/* Begin PBXProject section */
|
| 318 |
+
7777777777777777777777AA /* Project object */ = {
|
| 319 |
+
isa = PBXProject;
|
| 320 |
+
attributes = {
|
| 321 |
+
LastSwiftUpdateCheck = 1240;
|
| 322 |
+
LastUpgradeCheck = 1240;
|
| 323 |
+
TargetAttributes = {
|
| 324 |
+
3333333333333333333333AA = {
|
| 325 |
+
CreatedOnToolsVersion = 12.4;
|
| 326 |
+
};
|
| 327 |
+
};
|
| 328 |
+
};
|
| 329 |
+
buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
|
| 330 |
+
compatibilityVersion = "Xcode 12.0";
|
| 331 |
+
developmentRegion = en;
|
| 332 |
+
hasScannedForEncodings = 0;
|
| 333 |
+
knownRegions = (
|
| 334 |
+
en,
|
| 335 |
+
Base,
|
| 336 |
+
);
|
| 337 |
+
mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
|
| 338 |
+
productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
|
| 339 |
+
projectDirPath = "";
|
| 340 |
+
projectRoot = "";
|
| 341 |
+
targets = (
|
| 342 |
+
3333333333333333333333AA /* ${APP_NAME} */,
|
| 343 |
+
);
|
| 344 |
+
};
|
| 345 |
+
/* End PBXProject section */
|
| 346 |
+
EOF
|
| 347 |
+
|
| 348 |
+
# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS
|
| 349 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 350 |
+
/* Begin PBXResourcesBuildPhase section */
|
| 351 |
+
6666666666666666666666AA /* Resources */ = {
|
| 352 |
+
isa = PBXResourcesBuildPhase;
|
| 353 |
+
buildActionMask = 2147483647;
|
| 354 |
+
files = (
|
| 355 |
+
);
|
| 356 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 357 |
+
};
|
| 358 |
+
/* End PBXResourcesBuildPhase section */
|
| 359 |
+
|
| 360 |
+
/* Begin PBXSourcesBuildPhase section */
|
| 361 |
+
5555555555555555555555AA /* Sources */ = {
|
| 362 |
+
isa = PBXSourcesBuildPhase;
|
| 363 |
+
buildActionMask = 2147483647;
|
| 364 |
+
files = (
|
| 365 |
+
33333333333333333333333 /* ContentView.swift in Sources */,
|
| 366 |
+
11111111111111111111111 /* App.swift in Sources */,
|
| 367 |
+
);
|
| 368 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 369 |
+
};
|
| 370 |
+
/* End PBXSourcesBuildPhase section */
|
| 371 |
+
|
| 372 |
+
/* Begin XCBuildConfiguration section */
|
| 373 |
+
9999999999999999999999AA /* Debug */ = {
|
| 374 |
+
isa = XCBuildConfiguration;
|
| 375 |
+
buildSettings = {
|
| 376 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 377 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 378 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 379 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 380 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 381 |
+
CLANG_ENABLE_MODULES = YES;
|
| 382 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 383 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 384 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 385 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 386 |
+
CLANG_WARN_COMMA = YES;
|
| 387 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 388 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 389 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 390 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 391 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 392 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 393 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 394 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 395 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 396 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 397 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 398 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 399 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 400 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 401 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 402 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 403 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 404 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 405 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 406 |
+
COPY_PHASE_STRIP = NO;
|
| 407 |
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
| 408 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 409 |
+
ENABLE_TESTABILITY = YES;
|
| 410 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 411 |
+
GCC_DYNAMIC_NO_PIC = NO;
|
| 412 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 413 |
+
GCC_OPTIMIZATION_LEVEL = 0;
|
| 414 |
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
| 415 |
+
"DEBUG=1",
|
| 416 |
+
"$(inherited)",
|
| 417 |
+
);
|
| 418 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 419 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 420 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 421 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 422 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 423 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 424 |
+
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
| 425 |
+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 426 |
+
MTL_FAST_MATH = YES;
|
| 427 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 428 |
+
SDKROOT = iphoneos;
|
| 429 |
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 430 |
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
| 431 |
+
};
|
| 432 |
+
name = Debug;
|
| 433 |
+
};
|
| 434 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
|
| 435 |
+
isa = XCBuildConfiguration;
|
| 436 |
+
buildSettings = {
|
| 437 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 438 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 439 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 440 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 441 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 442 |
+
CLANG_ENABLE_MODULES = YES;
|
| 443 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 444 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 445 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 446 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 447 |
+
CLANG_WARN_COMMA = YES;
|
| 448 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 449 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 450 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 451 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 452 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 453 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 454 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 455 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 456 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 457 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 458 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 459 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 460 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 461 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 462 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 463 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 464 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 465 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 466 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 467 |
+
COPY_PHASE_STRIP = NO;
|
| 468 |
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
| 469 |
+
ENABLE_NS_ASSERTIONS = NO;
|
| 470 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 471 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 472 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 473 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 474 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 475 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 476 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 477 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 478 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 479 |
+
IPHONEOS_DEPLOYMENT_TARGET = 16.4;
|
| 480 |
+
MTL_ENABLE_DEBUG_INFO = NO;
|
| 481 |
+
MTL_FAST_MATH = YES;
|
| 482 |
+
SDKROOT = iphoneos;
|
| 483 |
+
SWIFT_COMPILATION_MODE = wholemodule;
|
| 484 |
+
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
| 485 |
+
VALIDATE_PRODUCT = YES;
|
| 486 |
+
};
|
| 487 |
+
name = Release;
|
| 488 |
+
};
|
| 489 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
|
| 490 |
+
isa = XCBuildConfiguration;
|
| 491 |
+
buildSettings = {
|
| 492 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 493 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 494 |
+
CODE_SIGN_STYLE = Manual;
|
| 495 |
+
DEVELOPMENT_TEAM = "";
|
| 496 |
+
ENABLE_PREVIEWS = YES;
|
| 497 |
+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
| 498 |
+
INFOPLIST_FILE = "iOSWhisperTest/Info.plist";
|
| 499 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 500 |
+
"$(inherited)",
|
| 501 |
+
"@executable_path/Frameworks",
|
| 502 |
+
);
|
| 503 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.iOSWhisperTest";
|
| 504 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 505 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 506 |
+
SWIFT_VERSION = 5.0;
|
| 507 |
+
TARGETED_DEVICE_FAMILY = "1,2";
|
| 508 |
+
};
|
| 509 |
+
name = Debug;
|
| 510 |
+
};
|
| 511 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
|
| 512 |
+
isa = XCBuildConfiguration;
|
| 513 |
+
buildSettings = {
|
| 514 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 515 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 516 |
+
CODE_SIGN_STYLE = Manual;
|
| 517 |
+
DEVELOPMENT_TEAM = "";
|
| 518 |
+
ENABLE_PREVIEWS = YES;
|
| 519 |
+
FRAMEWORK_SEARCH_PATHS = (
|
| 520 |
+
"$(inherited)",
|
| 521 |
+
"$(PROJECT_DIR)",
|
| 522 |
+
);
|
| 523 |
+
INFOPLIST_FILE = "iOSWhisperTest/Info.plist";
|
| 524 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 525 |
+
"$(inherited)",
|
| 526 |
+
"@executable_path/Frameworks",
|
| 527 |
+
);
|
| 528 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.iOSWhisperTest";
|
| 529 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 530 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 531 |
+
SWIFT_VERSION = 5.0;
|
| 532 |
+
TARGETED_DEVICE_FAMILY = "1,2";
|
| 533 |
+
};
|
| 534 |
+
name = Release;
|
| 535 |
+
};
|
| 536 |
+
/* End XCBuildConfiguration section */
|
| 537 |
+
EOF
|
| 538 |
+
|
| 539 |
+
# Finish the project.pbxproj file
|
| 540 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 541 |
+
/* Begin XCConfigurationList section */
|
| 542 |
+
8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
|
| 543 |
+
isa = XCConfigurationList;
|
| 544 |
+
buildConfigurations = (
|
| 545 |
+
9999999999999999999999AA /* Debug */,
|
| 546 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
|
| 547 |
+
);
|
| 548 |
+
defaultConfigurationIsVisible = 0;
|
| 549 |
+
defaultConfigurationName = Release;
|
| 550 |
+
};
|
| 551 |
+
4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
|
| 552 |
+
isa = XCConfigurationList;
|
| 553 |
+
buildConfigurations = (
|
| 554 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
|
| 555 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
|
| 556 |
+
);
|
| 557 |
+
defaultConfigurationIsVisible = 0;
|
| 558 |
+
defaultConfigurationName = Release;
|
| 559 |
+
};
|
| 560 |
+
/* End XCConfigurationList section */
|
| 561 |
+
};
|
| 562 |
+
rootObject = 7777777777777777777777AA /* Project object */;
|
| 563 |
+
}
|
| 564 |
+
EOF
|
| 565 |
+
|
| 566 |
+
# 2. Copy XCFramework to test project
|
| 567 |
+
echo "Copying XCFramework to test project..."
|
| 568 |
+
cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
|
| 569 |
+
|
| 570 |
+
# 3. Build and archive the app
|
| 571 |
+
echo "Building and archiving test app..."
|
| 572 |
+
cd "${TEMP_DIR}/${APP_NAME}"
|
| 573 |
+
|
| 574 |
+
# Create a simple xcscheme file to avoid xcodebuild scheme issues
|
| 575 |
+
mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
|
| 576 |
+
cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
|
| 577 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 578 |
+
<Scheme
|
| 579 |
+
LastUpgradeVersion = "1240"
|
| 580 |
+
version = "1.3">
|
| 581 |
+
<BuildAction
|
| 582 |
+
parallelizeBuildables = "YES"
|
| 583 |
+
buildImplicitDependencies = "YES">
|
| 584 |
+
<BuildActionEntries>
|
| 585 |
+
<BuildActionEntry
|
| 586 |
+
buildForTesting = "YES"
|
| 587 |
+
buildForRunning = "YES"
|
| 588 |
+
buildForProfiling = "YES"
|
| 589 |
+
buildForArchiving = "YES"
|
| 590 |
+
buildForAnalyzing = "YES">
|
| 591 |
+
<BuildableReference
|
| 592 |
+
BuildableIdentifier = "primary"
|
| 593 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 594 |
+
BuildableName = "${APP_NAME}.app"
|
| 595 |
+
BlueprintName = "${APP_NAME}"
|
| 596 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 597 |
+
</BuildableReference>
|
| 598 |
+
</BuildActionEntry>
|
| 599 |
+
</BuildActionEntries>
|
| 600 |
+
</BuildAction>
|
| 601 |
+
<TestAction
|
| 602 |
+
buildConfiguration = "Debug"
|
| 603 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 604 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 605 |
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
| 606 |
+
<Testables>
|
| 607 |
+
</Testables>
|
| 608 |
+
</TestAction>
|
| 609 |
+
<LaunchAction
|
| 610 |
+
buildConfiguration = "Debug"
|
| 611 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 612 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 613 |
+
launchStyle = "0"
|
| 614 |
+
useCustomWorkingDirectory = "NO"
|
| 615 |
+
ignoresPersistentStateOnLaunch = "NO"
|
| 616 |
+
debugDocumentVersioning = "YES"
|
| 617 |
+
debugServiceExtension = "internal"
|
| 618 |
+
allowLocationSimulation = "YES">
|
| 619 |
+
<BuildableProductRunnable
|
| 620 |
+
runnableDebuggingMode = "0">
|
| 621 |
+
<BuildableReference
|
| 622 |
+
BuildableIdentifier = "primary"
|
| 623 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 624 |
+
BuildableName = "${APP_NAME}.app"
|
| 625 |
+
BlueprintName = "${APP_NAME}"
|
| 626 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 627 |
+
</BuildableReference>
|
| 628 |
+
</BuildableProductRunnable>
|
| 629 |
+
</LaunchAction>
|
| 630 |
+
<ProfileAction
|
| 631 |
+
buildConfiguration = "Release"
|
| 632 |
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
| 633 |
+
savedToolIdentifier = ""
|
| 634 |
+
useCustomWorkingDirectory = "NO"
|
| 635 |
+
debugDocumentVersioning = "YES">
|
| 636 |
+
<BuildableProductRunnable
|
| 637 |
+
runnableDebuggingMode = "0">
|
| 638 |
+
<BuildableReference
|
| 639 |
+
BuildableIdentifier = "primary"
|
| 640 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 641 |
+
BuildableName = "${APP_NAME}.app"
|
| 642 |
+
BlueprintName = "${APP_NAME}"
|
| 643 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 644 |
+
</BuildableReference>
|
| 645 |
+
</BuildableProductRunnable>
|
| 646 |
+
</ProfileAction>
|
| 647 |
+
<AnalyzeAction
|
| 648 |
+
buildConfiguration = "Debug">
|
| 649 |
+
</AnalyzeAction>
|
| 650 |
+
<ArchiveAction
|
| 651 |
+
buildConfiguration = "Release"
|
| 652 |
+
revealArchiveInOrganizer = "YES">
|
| 653 |
+
</ArchiveAction>
|
| 654 |
+
</Scheme>
|
| 655 |
+
EOF
|
| 656 |
+
|
| 657 |
+
# Now use xcodebuild with an explicitly defined product name
|
| 658 |
+
xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk iphoneos -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
|
| 659 |
+
|
| 660 |
+
# 4. Create IPA from archive
|
| 661 |
+
echo "Creating IPA from archive..."
|
| 662 |
+
mkdir -p "${TEMP_DIR}/Payload"
|
| 663 |
+
cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
|
| 664 |
+
|
| 665 |
+
# Check and log app structure before zipping
|
| 666 |
+
echo "App structure:"
|
| 667 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
|
| 668 |
+
echo "Frameworks:"
|
| 669 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 670 |
+
|
| 671 |
+
cd "${TEMP_DIR}"
|
| 672 |
+
zip -r "${IPA_PATH}" Payload
|
| 673 |
+
|
| 674 |
+
# Check embedded provisioning profile
|
| 675 |
+
echo "Checking provisioning profile (if any)..."
|
| 676 |
+
PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
|
| 677 |
+
if [ -n "$PROVISIONING_PROFILE" ]; then
|
| 678 |
+
echo "Found embedded provisioning profile:"
|
| 679 |
+
security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
|
| 680 |
+
else
|
| 681 |
+
echo "No embedded provisioning profile found (expected for ad-hoc builds)"
|
| 682 |
+
fi
|
| 683 |
+
|
| 684 |
+
# 5. Validate the IPA
|
| 685 |
+
echo "Validating IPA..."
|
| 686 |
+
VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
|
| 687 |
+
|
| 688 |
+
# Check if authentication credentials are provided
|
| 689 |
+
AUTH_ARGS=""
|
| 690 |
+
if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
|
| 691 |
+
echo "Using Apple ID authentication for validation..."
|
| 692 |
+
AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
|
| 693 |
+
else
|
| 694 |
+
echo "No authentication credentials provided. Will perform basic validation."
|
| 695 |
+
echo "To use your personal developer account, you can run the script with:"
|
| 696 |
+
echo " APPLE_ID='[email protected]' APPLE_PASSWORD='your-app-specific-password' ./validate-ios.sh"
|
| 697 |
+
echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
|
| 698 |
+
fi
|
| 699 |
+
|
| 700 |
+
# Run validation with detailed output
|
| 701 |
+
echo "Running validation with altool..."
|
| 702 |
+
if [ -n "$AUTH_ARGS" ]; then
|
| 703 |
+
# Use eval to properly handle the quoted arguments
|
| 704 |
+
eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type ios --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 705 |
+
else
|
| 706 |
+
xcrun altool --validate-app -f "${IPA_PATH}" --type ios --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 707 |
+
fi
|
| 708 |
+
VALIDATION_RESULT=$?
|
| 709 |
+
|
| 710 |
+
# Final validation result
|
| 711 |
+
FINAL_VALIDATION_RESULT=0
|
| 712 |
+
|
| 713 |
+
# Check if validation failed because the app isn't in App Store Connect
|
| 714 |
+
if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
|
| 715 |
+
echo "β οΈ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
|
| 716 |
+
echo "This is expected for apps that haven't been registered in App Store Connect yet."
|
| 717 |
+
echo "This doesn't indicate a problem with the build or framework."
|
| 718 |
+
|
| 719 |
+
# Perform alternative validation
|
| 720 |
+
echo "Performing alternative validation checks..."
|
| 721 |
+
|
| 722 |
+
# Check if IPA was created successfully
|
| 723 |
+
if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
|
| 724 |
+
echo "β
IPA file created successfully"
|
| 725 |
+
else
|
| 726 |
+
echo "β IPA file not created or empty"
|
| 727 |
+
FINAL_VALIDATION_RESULT=1
|
| 728 |
+
fi
|
| 729 |
+
|
| 730 |
+
# Check if app binary exists and is executable
|
| 731 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
|
| 732 |
+
echo "β
App binary exists and is executable"
|
| 733 |
+
else
|
| 734 |
+
echo "β App binary missing or not executable"
|
| 735 |
+
FINAL_VALIDATION_RESULT=1
|
| 736 |
+
fi
|
| 737 |
+
|
| 738 |
+
# Check if framework was properly embedded
|
| 739 |
+
if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework" ]; then
|
| 740 |
+
echo "β
whisper.framework properly embedded"
|
| 741 |
+
else
|
| 742 |
+
echo "β whisper.framework not properly embedded"
|
| 743 |
+
FINAL_VALIDATION_RESULT=1
|
| 744 |
+
fi
|
| 745 |
+
|
| 746 |
+
# Check if framework binary exists
|
| 747 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework/whisper" ]; then
|
| 748 |
+
echo "β
Framework binary exists"
|
| 749 |
+
|
| 750 |
+
# Further validate framework by checking architecture
|
| 751 |
+
ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework/whisper" 2>/dev/null | grep -o "arm64\\|armv7\\|x86_64" | tr '\n' ' ')
|
| 752 |
+
if [ -n "$ARCHS" ]; then
|
| 753 |
+
echo "β
Framework architecture(s): $ARCHS"
|
| 754 |
+
else
|
| 755 |
+
echo "β οΈ Could not determine framework architecture"
|
| 756 |
+
fi
|
| 757 |
+
else
|
| 758 |
+
echo "β Framework binary missing"
|
| 759 |
+
FINAL_VALIDATION_RESULT=1
|
| 760 |
+
fi
|
| 761 |
+
|
| 762 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 763 |
+
echo "β
Alternative validation PASSED: App built successfully with embedded framework"
|
| 764 |
+
else
|
| 765 |
+
echo "β Alternative validation FAILED: Issues found with the app or framework"
|
| 766 |
+
fi
|
| 767 |
+
elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
|
| 768 |
+
echo "β
iOS Validation PASSED: IPA successfully validated"
|
| 769 |
+
echo "Results saved to ${VALIDATION_OUTPUT}"
|
| 770 |
+
else
|
| 771 |
+
echo "β iOS Validation FAILED: IPA validation found issues"
|
| 772 |
+
echo "See validation output at ${VALIDATION_OUTPUT}"
|
| 773 |
+
echo ""
|
| 774 |
+
echo "==== VALIDATION ERRORS ===="
|
| 775 |
+
|
| 776 |
+
# Try to extract specific errors from the output
|
| 777 |
+
if grep -q "Error" "${VALIDATION_OUTPUT}"; then
|
| 778 |
+
grep -A 5 "Error" "${VALIDATION_OUTPUT}"
|
| 779 |
+
else
|
| 780 |
+
# If no specific error found, show the whole log
|
| 781 |
+
cat "${VALIDATION_OUTPUT}"
|
| 782 |
+
fi
|
| 783 |
+
|
| 784 |
+
# Additional debugging: check IPA contents
|
| 785 |
+
echo ""
|
| 786 |
+
echo "==== IPA CONTENTS ===="
|
| 787 |
+
mkdir -p "${TEMP_DIR}/ipa_contents"
|
| 788 |
+
unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
|
| 789 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
|
| 790 |
+
|
| 791 |
+
# Check for code signing issues
|
| 792 |
+
echo ""
|
| 793 |
+
echo "==== CODE SIGNING INFO ===="
|
| 794 |
+
codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
|
| 795 |
+
|
| 796 |
+
# Check embedded frameworks
|
| 797 |
+
echo ""
|
| 798 |
+
echo "==== FRAMEWORK INFO ===="
|
| 799 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 800 |
+
fi
|
| 801 |
+
|
| 802 |
+
# Don't clean up on error to allow inspection
|
| 803 |
+
if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
|
| 804 |
+
echo ""
|
| 805 |
+
echo "Temporary files kept for inspection at: ${TEMP_DIR}"
|
| 806 |
+
echo "===== iOS Validation Process Failed ====="
|
| 807 |
+
exit 1
|
| 808 |
+
fi
|
| 809 |
+
|
| 810 |
+
# Clean up temporary files but keep build artifacts
|
| 811 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 812 |
+
echo "Cleaning up temporary files..."
|
| 813 |
+
#rm -rf "${TEMP_DIR}"
|
| 814 |
+
fi
|
| 815 |
+
|
| 816 |
+
echo "===== iOS Validation Process Completed ====="
|
| 817 |
+
exit $FINAL_VALIDATION_RESULT
|
scripts/apple/validate-macos.sh
ADDED
|
@@ -0,0 +1,778 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# validate-macos.sh - Validate macOS Application with embedded whisper.xcframework using SwiftUI
|
| 3 |
+
|
| 4 |
+
# Authentication options (optional) (can be set via environment variables)
|
| 5 |
+
# To use: export [email protected]
|
| 6 |
+
# export APPLE_PASSWORD=your-app-specific-password
|
| 7 |
+
# ./validate-macos.sh
|
| 8 |
+
APPLE_ID=${APPLE_ID:-""}
|
| 9 |
+
APPLE_PASSWORD=${APPLE_PASSWORD:-""}
|
| 10 |
+
|
| 11 |
+
# Ensure the script exits on error
|
| 12 |
+
set -e
|
| 13 |
+
|
| 14 |
+
# Function to print usage instructions
|
| 15 |
+
print_usage() {
|
| 16 |
+
echo "Usage: ./validate-macos.sh [OPTIONS]"
|
| 17 |
+
echo ""
|
| 18 |
+
echo "Options:"
|
| 19 |
+
echo " --help Show this help message"
|
| 20 |
+
echo " --apple-id EMAIL Apple ID email for validation"
|
| 21 |
+
echo " --apple-password PWD App-specific password for Apple ID"
|
| 22 |
+
echo ""
|
| 23 |
+
echo "Environment variables:"
|
| 24 |
+
echo " APPLE_ID Apple ID email for validation"
|
| 25 |
+
echo " APPLE_PASSWORD App-specific password for Apple ID"
|
| 26 |
+
echo ""
|
| 27 |
+
echo "Notes:"
|
| 28 |
+
echo " - Command line options take precedence over environment variables"
|
| 29 |
+
echo " - Authentication is optional. If not provided, alternative validation will be performed"
|
| 30 |
+
echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
# Parse command line arguments
|
| 34 |
+
while [[ $# -gt 0 ]]; do
|
| 35 |
+
case $1 in
|
| 36 |
+
--help)
|
| 37 |
+
print_usage
|
| 38 |
+
exit 0
|
| 39 |
+
;;
|
| 40 |
+
--apple-id)
|
| 41 |
+
APPLE_ID="$2"
|
| 42 |
+
shift 2
|
| 43 |
+
;;
|
| 44 |
+
--apple-password)
|
| 45 |
+
APPLE_PASSWORD="$2"
|
| 46 |
+
shift 2
|
| 47 |
+
;;
|
| 48 |
+
*)
|
| 49 |
+
echo "Unknown option: $1"
|
| 50 |
+
print_usage
|
| 51 |
+
exit 1
|
| 52 |
+
;;
|
| 53 |
+
esac
|
| 54 |
+
done
|
| 55 |
+
|
| 56 |
+
# Function to clean up in case of error
|
| 57 |
+
cleanup() {
|
| 58 |
+
# Don't clean up temp files on error to help with debugging
|
| 59 |
+
echo "===== macOS Validation Process Failed ====="
|
| 60 |
+
exit 1
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
# Set up trap to call cleanup function on error
|
| 64 |
+
trap cleanup ERR
|
| 65 |
+
|
| 66 |
+
set -e # Exit on any error
|
| 67 |
+
|
| 68 |
+
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
| 69 |
+
BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
|
| 70 |
+
|
| 71 |
+
# Configuration
|
| 72 |
+
APP_NAME="MacOSWhisperTest"
|
| 73 |
+
BUNDLE_ID="org.ggml.MacOSWhisperTest"
|
| 74 |
+
XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/whisper.xcframework"
|
| 75 |
+
TEMP_DIR="${BUILD_DIR}/temp"
|
| 76 |
+
ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
|
| 77 |
+
APP_PATH="${BUILD_DIR}/${APP_NAME}.app"
|
| 78 |
+
ZIP_PATH="${BUILD_DIR}/${APP_NAME}.zip"
|
| 79 |
+
VALIDATION_DIR="${BUILD_DIR}/validation"
|
| 80 |
+
|
| 81 |
+
# Create necessary directories
|
| 82 |
+
mkdir -p "${BUILD_DIR}"
|
| 83 |
+
mkdir -p "${TEMP_DIR}"
|
| 84 |
+
mkdir -p "${VALIDATION_DIR}"
|
| 85 |
+
|
| 86 |
+
echo "===== macOS Validation Process Started ====="
|
| 87 |
+
|
| 88 |
+
# 1. Create a simple test app project
|
| 89 |
+
echo "Creating test macOS app project..."
|
| 90 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
|
| 91 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
|
| 92 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 93 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 94 |
+
<plist version="1.0">
|
| 95 |
+
<dict>
|
| 96 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 97 |
+
<string>en</string>
|
| 98 |
+
<key>CFBundleExecutable</key>
|
| 99 |
+
<string>${APP_NAME}</string>
|
| 100 |
+
<key>CFBundleIdentifier</key>
|
| 101 |
+
<string>${BUNDLE_ID}</string>
|
| 102 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 103 |
+
<string>6.0</string>
|
| 104 |
+
<key>CFBundleName</key>
|
| 105 |
+
<string>${APP_NAME}</string>
|
| 106 |
+
<key>CFBundlePackageType</key>
|
| 107 |
+
<string>APPL</string>
|
| 108 |
+
<key>CFBundleShortVersionString</key>
|
| 109 |
+
<string>1.0</string>
|
| 110 |
+
<key>CFBundleVersion</key>
|
| 111 |
+
<string>1</string>
|
| 112 |
+
<key>LSMinimumSystemVersion</key>
|
| 113 |
+
<string>12.0</string>
|
| 114 |
+
<key>NSHumanReadableCopyright</key>
|
| 115 |
+
<string>Copyright Β© 2025 GGML. All rights reserved.</string>
|
| 116 |
+
<key>NSPrincipalClass</key>
|
| 117 |
+
<string>NSApplication</string>
|
| 118 |
+
</dict>
|
| 119 |
+
</plist>
|
| 120 |
+
EOF
|
| 121 |
+
|
| 122 |
+
# Create SwiftUI app files
|
| 123 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
|
| 124 |
+
|
| 125 |
+
# Create App.swift
|
| 126 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
|
| 127 |
+
import SwiftUI
|
| 128 |
+
import whisper
|
| 129 |
+
|
| 130 |
+
@main
|
| 131 |
+
struct WhisperTestApp: App {
|
| 132 |
+
var body: some Scene {
|
| 133 |
+
WindowGroup {
|
| 134 |
+
ContentView()
|
| 135 |
+
}
|
| 136 |
+
}
|
| 137 |
+
}
|
| 138 |
+
EOF
|
| 139 |
+
|
| 140 |
+
# Create ContentView.swift with macOS specific elements
|
| 141 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
|
| 142 |
+
import SwiftUI
|
| 143 |
+
import whisper
|
| 144 |
+
|
| 145 |
+
struct ContentView: View {
|
| 146 |
+
// Test that we can initialize a whisper context params struct
|
| 147 |
+
let params = whisper_context_default_params()
|
| 148 |
+
|
| 149 |
+
var body: some View {
|
| 150 |
+
VStack(spacing: 20) {
|
| 151 |
+
Text("Whisper Framework Test on macOS")
|
| 152 |
+
.font(.largeTitle)
|
| 153 |
+
.padding()
|
| 154 |
+
|
| 155 |
+
Text("whisper_context_default_params() created successfully")
|
| 156 |
+
.font(.headline)
|
| 157 |
+
.multilineTextAlignment(.center)
|
| 158 |
+
.padding()
|
| 159 |
+
|
| 160 |
+
// Display some param values to confirm the framework is working
|
| 161 |
+
Text("dtw_n_top: \(params.dtw_n_top)")
|
| 162 |
+
.font(.body)
|
| 163 |
+
|
| 164 |
+
Spacer()
|
| 165 |
+
}
|
| 166 |
+
.padding()
|
| 167 |
+
.frame(width: 600, height: 400)
|
| 168 |
+
}
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
struct ContentView_Previews: PreviewProvider {
|
| 172 |
+
static var previews: some View {
|
| 173 |
+
ContentView()
|
| 174 |
+
}
|
| 175 |
+
}
|
| 176 |
+
EOF
|
| 177 |
+
|
| 178 |
+
# Create project.pbxproj, fixing the framework search paths issues
|
| 179 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
|
| 180 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 181 |
+
// !$*UTF8*$!
|
| 182 |
+
{
|
| 183 |
+
archiveVersion = 1;
|
| 184 |
+
classes = {
|
| 185 |
+
};
|
| 186 |
+
objectVersion = 54;
|
| 187 |
+
objects = {
|
| 188 |
+
|
| 189 |
+
/* Begin PBXBuildFile section */
|
| 190 |
+
11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
|
| 191 |
+
33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
|
| 192 |
+
55555555555555555555555 /* whisper.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 193 |
+
77777777777777777777777 /* whisper.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 194 |
+
/* End PBXBuildFile section */
|
| 195 |
+
|
| 196 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 197 |
+
88888888888888888888888 /* Embed Frameworks */ = {
|
| 198 |
+
isa = PBXCopyFilesBuildPhase;
|
| 199 |
+
buildActionMask = 2147483647;
|
| 200 |
+
dstPath = "";
|
| 201 |
+
dstSubfolderSpec = 10;
|
| 202 |
+
files = (
|
| 203 |
+
77777777777777777777777 /* whisper.xcframework in Embed Frameworks */,
|
| 204 |
+
);
|
| 205 |
+
name = "Embed Frameworks";
|
| 206 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 207 |
+
};
|
| 208 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 209 |
+
|
| 210 |
+
/* Begin PBXFileReference section */
|
| 211 |
+
EOF
|
| 212 |
+
|
| 213 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 214 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 215 |
+
99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 216 |
+
22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
| 217 |
+
44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
| 218 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
| 219 |
+
66666666666666666666666 /* whisper.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = whisper.xcframework; sourceTree = "<group>"; };
|
| 220 |
+
/* End PBXFileReference section */
|
| 221 |
+
EOF
|
| 222 |
+
|
| 223 |
+
# Add the rest of the project file with fixed framework search paths
|
| 224 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 225 |
+
/* Begin PBXFrameworksBuildPhase section */
|
| 226 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
|
| 227 |
+
isa = PBXFrameworksBuildPhase;
|
| 228 |
+
buildActionMask = 2147483647;
|
| 229 |
+
files = (
|
| 230 |
+
55555555555555555555555 /* whisper.xcframework in Frameworks */,
|
| 231 |
+
);
|
| 232 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 233 |
+
};
|
| 234 |
+
/* End PBXFrameworksBuildPhase section */
|
| 235 |
+
|
| 236 |
+
/* Begin PBXGroup section */
|
| 237 |
+
EOF
|
| 238 |
+
|
| 239 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 240 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 241 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
|
| 242 |
+
isa = PBXGroup;
|
| 243 |
+
children = (
|
| 244 |
+
99999999999999999999999 /* ${APP_NAME}.app */,
|
| 245 |
+
);
|
| 246 |
+
name = Products;
|
| 247 |
+
sourceTree = "<group>";
|
| 248 |
+
};
|
| 249 |
+
EOF
|
| 250 |
+
|
| 251 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 252 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
|
| 253 |
+
isa = PBXGroup;
|
| 254 |
+
children = (
|
| 255 |
+
66666666666666666666666 /* whisper.xcframework */,
|
| 256 |
+
);
|
| 257 |
+
name = Frameworks;
|
| 258 |
+
sourceTree = "<group>";
|
| 259 |
+
};
|
| 260 |
+
EEEEEEEEEEEEEEEEEEEEEEEE = {
|
| 261 |
+
isa = PBXGroup;
|
| 262 |
+
children = (
|
| 263 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* MacOSWhisperTest */,
|
| 264 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
|
| 265 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
|
| 266 |
+
);
|
| 267 |
+
sourceTree = "<group>";
|
| 268 |
+
};
|
| 269 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* MacOSWhisperTest */ = {
|
| 270 |
+
isa = PBXGroup;
|
| 271 |
+
children = (
|
| 272 |
+
1111111111111111111111AA /* Sources */,
|
| 273 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
|
| 274 |
+
);
|
| 275 |
+
path = "MacOSWhisperTest";
|
| 276 |
+
sourceTree = "<group>";
|
| 277 |
+
};
|
| 278 |
+
1111111111111111111111AA /* Sources */ = {
|
| 279 |
+
isa = PBXGroup;
|
| 280 |
+
children = (
|
| 281 |
+
22222222222222222222222 /* App.swift */,
|
| 282 |
+
44444444444444444444444 /* ContentView.swift */,
|
| 283 |
+
);
|
| 284 |
+
path = Sources;
|
| 285 |
+
sourceTree = "<group>";
|
| 286 |
+
};
|
| 287 |
+
/* End PBXGroup section */
|
| 288 |
+
EOF
|
| 289 |
+
|
| 290 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 291 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 292 |
+
/* Begin PBXNativeTarget section */
|
| 293 |
+
3333333333333333333333AA /* ${APP_NAME} */ = {
|
| 294 |
+
isa = PBXNativeTarget;
|
| 295 |
+
buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
|
| 296 |
+
buildPhases = (
|
| 297 |
+
5555555555555555555555AA /* Sources */,
|
| 298 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
|
| 299 |
+
6666666666666666666666AA /* Resources */,
|
| 300 |
+
88888888888888888888888 /* Embed Frameworks */,
|
| 301 |
+
);
|
| 302 |
+
buildRules = (
|
| 303 |
+
);
|
| 304 |
+
dependencies = (
|
| 305 |
+
);
|
| 306 |
+
name = "${APP_NAME}";
|
| 307 |
+
productName = "${APP_NAME}";
|
| 308 |
+
productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
|
| 309 |
+
productType = "com.apple.product-type.application";
|
| 310 |
+
};
|
| 311 |
+
/* End PBXNativeTarget section */
|
| 312 |
+
|
| 313 |
+
/* Begin PBXProject section */
|
| 314 |
+
7777777777777777777777AA /* Project object */ = {
|
| 315 |
+
isa = PBXProject;
|
| 316 |
+
attributes = {
|
| 317 |
+
LastSwiftUpdateCheck = 1240;
|
| 318 |
+
LastUpgradeCheck = 1240;
|
| 319 |
+
TargetAttributes = {
|
| 320 |
+
3333333333333333333333AA = {
|
| 321 |
+
CreatedOnToolsVersion = 12.4;
|
| 322 |
+
};
|
| 323 |
+
};
|
| 324 |
+
};
|
| 325 |
+
buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
|
| 326 |
+
compatibilityVersion = "Xcode 12.0";
|
| 327 |
+
developmentRegion = en;
|
| 328 |
+
hasScannedForEncodings = 0;
|
| 329 |
+
knownRegions = (
|
| 330 |
+
en,
|
| 331 |
+
Base,
|
| 332 |
+
);
|
| 333 |
+
mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
|
| 334 |
+
productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
|
| 335 |
+
projectDirPath = "";
|
| 336 |
+
projectRoot = "";
|
| 337 |
+
targets = (
|
| 338 |
+
3333333333333333333333AA /* ${APP_NAME} */,
|
| 339 |
+
);
|
| 340 |
+
};
|
| 341 |
+
/* End PBXProject section */
|
| 342 |
+
EOF
|
| 343 |
+
|
| 344 |
+
# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS and macOS settings
|
| 345 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 346 |
+
/* Begin PBXResourcesBuildPhase section */
|
| 347 |
+
6666666666666666666666AA /* Resources */ = {
|
| 348 |
+
isa = PBXResourcesBuildPhase;
|
| 349 |
+
buildActionMask = 2147483647;
|
| 350 |
+
files = (
|
| 351 |
+
);
|
| 352 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 353 |
+
};
|
| 354 |
+
/* End PBXResourcesBuildPhase section */
|
| 355 |
+
|
| 356 |
+
/* Begin PBXSourcesBuildPhase section */
|
| 357 |
+
5555555555555555555555AA /* Sources */ = {
|
| 358 |
+
isa = PBXSourcesBuildPhase;
|
| 359 |
+
buildActionMask = 2147483647;
|
| 360 |
+
files = (
|
| 361 |
+
33333333333333333333333 /* ContentView.swift in Sources */,
|
| 362 |
+
11111111111111111111111 /* App.swift in Sources */,
|
| 363 |
+
);
|
| 364 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 365 |
+
};
|
| 366 |
+
/* End PBXSourcesBuildPhase section */
|
| 367 |
+
|
| 368 |
+
/* Begin XCBuildConfiguration section */
|
| 369 |
+
9999999999999999999999AA /* Debug */ = {
|
| 370 |
+
isa = XCBuildConfiguration;
|
| 371 |
+
buildSettings = {
|
| 372 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 373 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 374 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 375 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 376 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 377 |
+
CLANG_ENABLE_MODULES = YES;
|
| 378 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 379 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 380 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 381 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 382 |
+
CLANG_WARN_COMMA = YES;
|
| 383 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 384 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 385 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 386 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 387 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 388 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 389 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 390 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 391 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 392 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 393 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 394 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 395 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 396 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 397 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 398 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 399 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 400 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 401 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 402 |
+
COPY_PHASE_STRIP = NO;
|
| 403 |
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
| 404 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 405 |
+
ENABLE_TESTABILITY = YES;
|
| 406 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 407 |
+
GCC_DYNAMIC_NO_PIC = NO;
|
| 408 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 409 |
+
GCC_OPTIMIZATION_LEVEL = 0;
|
| 410 |
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
| 411 |
+
"DEBUG=1",
|
| 412 |
+
"$(inherited)",
|
| 413 |
+
);
|
| 414 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 415 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 416 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 417 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 418 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 419 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 420 |
+
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
| 421 |
+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 422 |
+
MTL_FAST_MATH = YES;
|
| 423 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 424 |
+
SDKROOT = macosx;
|
| 425 |
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 426 |
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
| 427 |
+
};
|
| 428 |
+
name = Debug;
|
| 429 |
+
};
|
| 430 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
|
| 431 |
+
isa = XCBuildConfiguration;
|
| 432 |
+
buildSettings = {
|
| 433 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 434 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 435 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 436 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 437 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 438 |
+
CLANG_ENABLE_MODULES = YES;
|
| 439 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 440 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 441 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 442 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 443 |
+
CLANG_WARN_COMMA = YES;
|
| 444 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 445 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 446 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 447 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 448 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 449 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 450 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 451 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 452 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 453 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 454 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 455 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 456 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 457 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 458 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 459 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 460 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 461 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 462 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 463 |
+
COPY_PHASE_STRIP = NO;
|
| 464 |
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
| 465 |
+
ENABLE_NS_ASSERTIONS = NO;
|
| 466 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 467 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 468 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 469 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 470 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 471 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 472 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 473 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 474 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 475 |
+
MACOSX_DEPLOYMENT_TARGET = 12.0;
|
| 476 |
+
MTL_ENABLE_DEBUG_INFO = NO;
|
| 477 |
+
MTL_FAST_MATH = YES;
|
| 478 |
+
SDKROOT = macosx;
|
| 479 |
+
SWIFT_COMPILATION_MODE = wholemodule;
|
| 480 |
+
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
| 481 |
+
};
|
| 482 |
+
name = Release;
|
| 483 |
+
};
|
| 484 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
|
| 485 |
+
isa = XCBuildConfiguration;
|
| 486 |
+
buildSettings = {
|
| 487 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 488 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 489 |
+
CODE_SIGN_STYLE = Manual;
|
| 490 |
+
COMBINE_HIDPI_IMAGES = YES;
|
| 491 |
+
DEVELOPMENT_TEAM = "";
|
| 492 |
+
ENABLE_HARDENED_RUNTIME = YES;
|
| 493 |
+
ENABLE_PREVIEWS = YES;
|
| 494 |
+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
| 495 |
+
INFOPLIST_FILE = "MacOSWhisperTest/Info.plist";
|
| 496 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 497 |
+
"$(inherited)",
|
| 498 |
+
"@executable_path/../Frameworks",
|
| 499 |
+
);
|
| 500 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.MacOSWhisperTest";
|
| 501 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 502 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 503 |
+
SWIFT_VERSION = 5.0;
|
| 504 |
+
};
|
| 505 |
+
name = Debug;
|
| 506 |
+
};
|
| 507 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
|
| 508 |
+
isa = XCBuildConfiguration;
|
| 509 |
+
buildSettings = {
|
| 510 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 511 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 512 |
+
CODE_SIGN_STYLE = Manual;
|
| 513 |
+
COMBINE_HIDPI_IMAGES = YES;
|
| 514 |
+
DEVELOPMENT_TEAM = "";
|
| 515 |
+
ENABLE_HARDENED_RUNTIME = YES;
|
| 516 |
+
ENABLE_PREVIEWS = YES;
|
| 517 |
+
FRAMEWORK_SEARCH_PATHS = (
|
| 518 |
+
"$(inherited)",
|
| 519 |
+
"$(PROJECT_DIR)",
|
| 520 |
+
);
|
| 521 |
+
INFOPLIST_FILE = "MacOSWhisperTest/Info.plist";
|
| 522 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 523 |
+
"$(inherited)",
|
| 524 |
+
"@executable_path/../Frameworks",
|
| 525 |
+
);
|
| 526 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.MacOSWhisperTest";
|
| 527 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 528 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 529 |
+
SWIFT_VERSION = 5.0;
|
| 530 |
+
};
|
| 531 |
+
name = Release;
|
| 532 |
+
};
|
| 533 |
+
/* End XCBuildConfiguration section */
|
| 534 |
+
EOF
|
| 535 |
+
|
| 536 |
+
# Finish the project.pbxproj file
|
| 537 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 538 |
+
/* Begin XCConfigurationList section */
|
| 539 |
+
8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
|
| 540 |
+
isa = XCConfigurationList;
|
| 541 |
+
buildConfigurations = (
|
| 542 |
+
9999999999999999999999AA /* Debug */,
|
| 543 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
|
| 544 |
+
);
|
| 545 |
+
defaultConfigurationIsVisible = 0;
|
| 546 |
+
defaultConfigurationName = Release;
|
| 547 |
+
};
|
| 548 |
+
4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
|
| 549 |
+
isa = XCConfigurationList;
|
| 550 |
+
buildConfigurations = (
|
| 551 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
|
| 552 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
|
| 553 |
+
);
|
| 554 |
+
defaultConfigurationIsVisible = 0;
|
| 555 |
+
defaultConfigurationName = Release;
|
| 556 |
+
};
|
| 557 |
+
/* End XCConfigurationList section */
|
| 558 |
+
};
|
| 559 |
+
rootObject = 7777777777777777777777AA /* Project object */;
|
| 560 |
+
}
|
| 561 |
+
EOF
|
| 562 |
+
|
| 563 |
+
# 2. Copy XCFramework to test project
|
| 564 |
+
echo "Copying XCFramework to test project..."
|
| 565 |
+
cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
|
| 566 |
+
|
| 567 |
+
# 3. Build and archive the app
|
| 568 |
+
echo "Building and archiving test app..."
|
| 569 |
+
cd "${TEMP_DIR}/${APP_NAME}"
|
| 570 |
+
|
| 571 |
+
# Create a simple xcscheme file to avoid xcodebuild scheme issues
|
| 572 |
+
mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
|
| 573 |
+
cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
|
| 574 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 575 |
+
<Scheme
|
| 576 |
+
LastUpgradeVersion = "1240"
|
| 577 |
+
version = "1.3">
|
| 578 |
+
<BuildAction
|
| 579 |
+
parallelizeBuildables = "YES"
|
| 580 |
+
buildImplicitDependencies = "YES">
|
| 581 |
+
<BuildActionEntries>
|
| 582 |
+
<BuildActionEntry
|
| 583 |
+
buildForTesting = "YES"
|
| 584 |
+
buildForRunning = "YES"
|
| 585 |
+
buildForProfiling = "YES"
|
| 586 |
+
buildForArchiving = "YES"
|
| 587 |
+
buildForAnalyzing = "YES">
|
| 588 |
+
<BuildableReference
|
| 589 |
+
BuildableIdentifier = "primary"
|
| 590 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 591 |
+
BuildableName = "${APP_NAME}.app"
|
| 592 |
+
BlueprintName = "${APP_NAME}"
|
| 593 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 594 |
+
</BuildableReference>
|
| 595 |
+
</BuildActionEntry>
|
| 596 |
+
</BuildActionEntries>
|
| 597 |
+
</BuildAction>
|
| 598 |
+
<TestAction
|
| 599 |
+
buildConfiguration = "Debug"
|
| 600 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 601 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 602 |
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
| 603 |
+
<Testables>
|
| 604 |
+
</Testables>
|
| 605 |
+
</TestAction>
|
| 606 |
+
<LaunchAction
|
| 607 |
+
buildConfiguration = "Debug"
|
| 608 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 609 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 610 |
+
launchStyle = "0"
|
| 611 |
+
useCustomWorkingDirectory = "NO"
|
| 612 |
+
ignoresPersistentStateOnLaunch = "NO"
|
| 613 |
+
debugDocumentVersioning = "YES"
|
| 614 |
+
debugServiceExtension = "internal"
|
| 615 |
+
allowLocationSimulation = "YES">
|
| 616 |
+
<BuildableProductRunnable
|
| 617 |
+
runnableDebuggingMode = "0">
|
| 618 |
+
<BuildableReference
|
| 619 |
+
BuildableIdentifier = "primary"
|
| 620 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 621 |
+
BuildableName = "${APP_NAME}.app"
|
| 622 |
+
BlueprintName = "${APP_NAME}"
|
| 623 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 624 |
+
</BuildableReference>
|
| 625 |
+
</BuildableProductRunnable>
|
| 626 |
+
</LaunchAction>
|
| 627 |
+
<ProfileAction
|
| 628 |
+
buildConfiguration = "Release"
|
| 629 |
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
| 630 |
+
savedToolIdentifier = ""
|
| 631 |
+
useCustomWorkingDirectory = "NO"
|
| 632 |
+
debugDocumentVersioning = "YES">
|
| 633 |
+
<BuildableProductRunnable
|
| 634 |
+
runnableDebuggingMode = "0">
|
| 635 |
+
<BuildableReference
|
| 636 |
+
BuildableIdentifier = "primary"
|
| 637 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 638 |
+
BuildableName = "${APP_NAME}.app"
|
| 639 |
+
BlueprintName = "${APP_NAME}"
|
| 640 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 641 |
+
</BuildableReference>
|
| 642 |
+
</BuildableProductRunnable>
|
| 643 |
+
</ProfileAction>
|
| 644 |
+
<AnalyzeAction
|
| 645 |
+
buildConfiguration = "Debug">
|
| 646 |
+
</AnalyzeAction>
|
| 647 |
+
<ArchiveAction
|
| 648 |
+
buildConfiguration = "Release"
|
| 649 |
+
revealArchiveInOrganizer = "YES">
|
| 650 |
+
</ArchiveAction>
|
| 651 |
+
</Scheme>
|
| 652 |
+
EOF
|
| 653 |
+
|
| 654 |
+
# Now use xcodebuild with an explicitly defined product name for macOS
|
| 655 |
+
xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk macosx -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
|
| 656 |
+
|
| 657 |
+
# 4. Create a package for distribution
|
| 658 |
+
echo "Creating distributable package from archive..."
|
| 659 |
+
cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${APP_PATH}"
|
| 660 |
+
|
| 661 |
+
# Check and log app structure
|
| 662 |
+
echo "App structure:"
|
| 663 |
+
ls -la "${APP_PATH}"
|
| 664 |
+
echo "Frameworks:"
|
| 665 |
+
ls -la "${APP_PATH}/Contents/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 666 |
+
|
| 667 |
+
# Create a zip file for potential distribution
|
| 668 |
+
cd "${BUILD_DIR}"
|
| 669 |
+
zip -r "${ZIP_PATH}" "${APP_NAME}.app"
|
| 670 |
+
|
| 671 |
+
# Check embedded provisioning profile
|
| 672 |
+
echo "Checking provisioning profile (if any)..."
|
| 673 |
+
PROVISIONING_PROFILE=$(find "${APP_PATH}/Contents" -name "embedded.provisionprofile" 2>/dev/null)
|
| 674 |
+
if [ -n "$PROVISIONING_PROFILE" ]; then
|
| 675 |
+
echo "Found embedded provisioning profile:"
|
| 676 |
+
security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
|
| 677 |
+
else
|
| 678 |
+
echo "No embedded provisioning profile found (expected for ad-hoc builds)"
|
| 679 |
+
fi
|
| 680 |
+
|
| 681 |
+
# 5. Validate the app
|
| 682 |
+
echo "Validating macOS app..."
|
| 683 |
+
VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
|
| 684 |
+
|
| 685 |
+
# Check if authentication credentials are provided
|
| 686 |
+
AUTH_ARGS=""
|
| 687 |
+
if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
|
| 688 |
+
echo "Using Apple ID authentication for validation..."
|
| 689 |
+
AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
|
| 690 |
+
else
|
| 691 |
+
echo "No authentication credentials provided. Will perform basic validation."
|
| 692 |
+
echo "To use your personal developer account, you can run the script with:"
|
| 693 |
+
echo " APPLE_ID='[email protected]' APPLE_PASSWORD='your-app-specific-password' ./validate-macos.sh"
|
| 694 |
+
echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
|
| 695 |
+
fi
|
| 696 |
+
|
| 697 |
+
# For macOS we need to use notarytool or alternative checks because altool doesn't support macOS apps in the same way
|
| 698 |
+
echo "Note: For macOS, formal notarization process would require Apple Developer credentials."
|
| 699 |
+
echo "Performing alternative validation checks..."
|
| 700 |
+
|
| 701 |
+
# Final validation result
|
| 702 |
+
FINAL_VALIDATION_RESULT=0
|
| 703 |
+
|
| 704 |
+
# Check if app was created successfully
|
| 705 |
+
if [ -d "${APP_PATH}" ] && [ -s "${APP_PATH}/Contents/MacOS/${APP_NAME}" ]; then
|
| 706 |
+
echo "β
App package created successfully"
|
| 707 |
+
else
|
| 708 |
+
echo "β App package not created or binary missing"
|
| 709 |
+
FINAL_VALIDATION_RESULT=1
|
| 710 |
+
fi
|
| 711 |
+
|
| 712 |
+
# Check if app binary exists and is executable
|
| 713 |
+
if [ -f "${APP_PATH}/Contents/MacOS/${APP_NAME}" ] && [ -x "${APP_PATH}/Contents/MacOS/${APP_NAME}" ]; then
|
| 714 |
+
echo "β
App binary exists and is executable"
|
| 715 |
+
else
|
| 716 |
+
echo "β App binary missing or not executable"
|
| 717 |
+
FINAL_VALIDATION_RESULT=1
|
| 718 |
+
fi
|
| 719 |
+
|
| 720 |
+
# Check if framework was properly embedded
|
| 721 |
+
if [ -d "${APP_PATH}/Contents/Frameworks/whisper.framework" ]; then
|
| 722 |
+
echo "β
whisper.framework properly embedded"
|
| 723 |
+
else
|
| 724 |
+
echo "β whisper.framework not properly embedded"
|
| 725 |
+
FINAL_VALIDATION_RESULT=1
|
| 726 |
+
fi
|
| 727 |
+
|
| 728 |
+
# Check if framework binary exists
|
| 729 |
+
if [ -f "${APP_PATH}/Contents/Frameworks/whisper.framework/Versions/A/whisper" ]; then
|
| 730 |
+
echo "β
Framework binary exists"
|
| 731 |
+
|
| 732 |
+
# Further validate framework by checking architecture
|
| 733 |
+
ARCHS=$(lipo -info "${APP_PATH}/Contents/Frameworks/whisper.framework/Versions/A/whisper" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
|
| 734 |
+
if [ -n "$ARCHS" ]; then
|
| 735 |
+
echo "β
Framework architecture(s): $ARCHS"
|
| 736 |
+
else
|
| 737 |
+
echo "β οΈ Could not determine framework architecture"
|
| 738 |
+
fi
|
| 739 |
+
else
|
| 740 |
+
echo "β Framework binary missing"
|
| 741 |
+
FINAL_VALIDATION_RESULT=1
|
| 742 |
+
fi
|
| 743 |
+
|
| 744 |
+
# Check code signing
|
| 745 |
+
echo ""
|
| 746 |
+
echo "==== CODE SIGNING INFO ===="
|
| 747 |
+
codesign -vv -d "${APP_PATH}" 2>&1 || echo "Code signing verification not available (expected for ad-hoc builds)"
|
| 748 |
+
|
| 749 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 750 |
+
if [ -n "$AUTH_ARGS" ]; then
|
| 751 |
+
echo ""
|
| 752 |
+
echo "To notarize this app with Apple (requires Apple Developer account):"
|
| 753 |
+
echo "xcrun notarytool submit \"${ZIP_PATH}\" --apple-id \"your-apple-id\" --password \"your-app-specific-password\" --team-id \"your-team-id\" --wait"
|
| 754 |
+
echo ""
|
| 755 |
+
fi
|
| 756 |
+
echo "β
Validation PASSED: macOS app built successfully with embedded framework"
|
| 757 |
+
else
|
| 758 |
+
echo "β Validation FAILED: Issues found with the app or framework"
|
| 759 |
+
fi
|
| 760 |
+
|
| 761 |
+
# Don't clean up on error to allow inspection
|
| 762 |
+
if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
|
| 763 |
+
echo ""
|
| 764 |
+
echo "Temporary files kept for inspection at: ${TEMP_DIR}"
|
| 765 |
+
echo "===== macOS Validation Process Failed ====="
|
| 766 |
+
exit 1
|
| 767 |
+
fi
|
| 768 |
+
|
| 769 |
+
# Clean up temporary files but keep build artifacts
|
| 770 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 771 |
+
echo "Cleaning up temporary files..."
|
| 772 |
+
#rm -rf "${TEMP_DIR}"
|
| 773 |
+
fi
|
| 774 |
+
|
| 775 |
+
echo "===== macOS Validation Process Completed ====="
|
| 776 |
+
echo "App package available at: ${APP_PATH}"
|
| 777 |
+
echo "Zipped app available at: ${ZIP_PATH}"
|
| 778 |
+
exit $FINAL_VALIDATION_RESULT
|
scripts/apple/validate-tvos.sh
ADDED
|
@@ -0,0 +1,810 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# validate-tvos.sh - Validate tvOS Application with embedded whisper.xcframework using SwiftUI
|
| 3 |
+
|
| 4 |
+
# Authentication options (optional) (can be set via environment variables)
|
| 5 |
+
# To use: export [email protected]
|
| 6 |
+
# export APPLE_PASSWORD=your-app-specific-password
|
| 7 |
+
# ./validate-tvos.sh
|
| 8 |
+
APPLE_ID=${APPLE_ID:-""}
|
| 9 |
+
APPLE_PASSWORD=${APPLE_PASSWORD:-""}
|
| 10 |
+
|
| 11 |
+
# Ensure the script exits on error
|
| 12 |
+
set -e
|
| 13 |
+
|
| 14 |
+
# Function to print usage instructions
|
| 15 |
+
print_usage() {
|
| 16 |
+
echo "Usage: ./validate-tvos.sh [OPTIONS]"
|
| 17 |
+
echo ""
|
| 18 |
+
echo "Options:"
|
| 19 |
+
echo " --help Show this help message"
|
| 20 |
+
echo " --apple-id EMAIL Apple ID email for validation"
|
| 21 |
+
echo " --apple-password PWD App-specific password for Apple ID"
|
| 22 |
+
echo ""
|
| 23 |
+
echo "Environment variables:"
|
| 24 |
+
echo " APPLE_ID Apple ID email for validation"
|
| 25 |
+
echo " APPLE_PASSWORD App-specific password for Apple ID"
|
| 26 |
+
echo ""
|
| 27 |
+
echo "Notes:"
|
| 28 |
+
echo " - Command line options take precedence over environment variables"
|
| 29 |
+
echo " - Authentication is optional. If not provided, alternative validation will be performed"
|
| 30 |
+
echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
# Parse command line arguments
|
| 34 |
+
while [[ $# -gt 0 ]]; do
|
| 35 |
+
case $1 in
|
| 36 |
+
--help)
|
| 37 |
+
print_usage
|
| 38 |
+
exit 0
|
| 39 |
+
;;
|
| 40 |
+
--apple-id)
|
| 41 |
+
APPLE_ID="$2"
|
| 42 |
+
shift 2
|
| 43 |
+
;;
|
| 44 |
+
--apple-password)
|
| 45 |
+
APPLE_PASSWORD="$2"
|
| 46 |
+
shift 2
|
| 47 |
+
;;
|
| 48 |
+
*)
|
| 49 |
+
echo "Unknown option: $1"
|
| 50 |
+
print_usage
|
| 51 |
+
exit 1
|
| 52 |
+
;;
|
| 53 |
+
esac
|
| 54 |
+
done
|
| 55 |
+
|
| 56 |
+
# Function to clean up in case of error
|
| 57 |
+
cleanup() {
|
| 58 |
+
# Don't clean up temp files on error to help with debugging
|
| 59 |
+
echo "===== tvOS Validation Process Failed ====="
|
| 60 |
+
exit 1
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
# Set up trap to call cleanup function on error
|
| 64 |
+
trap cleanup ERR
|
| 65 |
+
|
| 66 |
+
set -e # Exit on any error
|
| 67 |
+
|
| 68 |
+
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
| 69 |
+
BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
|
| 70 |
+
|
| 71 |
+
# Configuration
|
| 72 |
+
APP_NAME="TVOSWhisperTest"
|
| 73 |
+
BUNDLE_ID="org.ggml.TVOSWhisperTest"
|
| 74 |
+
XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/whisper.xcframework"
|
| 75 |
+
TEMP_DIR="${BUILD_DIR}/temp"
|
| 76 |
+
ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
|
| 77 |
+
IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
|
| 78 |
+
VALIDATION_DIR="${BUILD_DIR}/validation"
|
| 79 |
+
|
| 80 |
+
# Create necessary directories
|
| 81 |
+
mkdir -p "${BUILD_DIR}"
|
| 82 |
+
mkdir -p "${TEMP_DIR}"
|
| 83 |
+
mkdir -p "${VALIDATION_DIR}"
|
| 84 |
+
|
| 85 |
+
echo "===== tvOS Validation Process Started ====="
|
| 86 |
+
|
| 87 |
+
# 1. Create a simple test app project
|
| 88 |
+
echo "Creating test tvOS app project..."
|
| 89 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
|
| 90 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
|
| 91 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 92 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 93 |
+
<plist version="1.0">
|
| 94 |
+
<dict>
|
| 95 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 96 |
+
<string>en</string>
|
| 97 |
+
<key>CFBundleExecutable</key>
|
| 98 |
+
<string>${APP_NAME}</string>
|
| 99 |
+
<key>CFBundleIdentifier</key>
|
| 100 |
+
<string>${BUNDLE_ID}</string>
|
| 101 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 102 |
+
<string>6.0</string>
|
| 103 |
+
<key>CFBundleName</key>
|
| 104 |
+
<string>${APP_NAME}</string>
|
| 105 |
+
<key>CFBundlePackageType</key>
|
| 106 |
+
<string>APPL</string>
|
| 107 |
+
<key>CFBundleShortVersionString</key>
|
| 108 |
+
<string>1.0</string>
|
| 109 |
+
<key>CFBundleVersion</key>
|
| 110 |
+
<string>1</string>
|
| 111 |
+
<key>UIRequiredDeviceCapabilities</key>
|
| 112 |
+
<array>
|
| 113 |
+
<string>arm64</string>
|
| 114 |
+
</array>
|
| 115 |
+
</dict>
|
| 116 |
+
</plist>
|
| 117 |
+
EOF
|
| 118 |
+
|
| 119 |
+
# Create SwiftUI app files
|
| 120 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
|
| 121 |
+
|
| 122 |
+
# Create App.swift
|
| 123 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
|
| 124 |
+
import SwiftUI
|
| 125 |
+
import whisper
|
| 126 |
+
|
| 127 |
+
@main
|
| 128 |
+
struct WhisperTestApp: App {
|
| 129 |
+
var body: some Scene {
|
| 130 |
+
WindowGroup {
|
| 131 |
+
ContentView()
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
EOF
|
| 136 |
+
|
| 137 |
+
# Create ContentView.swift with tvOS specific elements
|
| 138 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
|
| 139 |
+
import SwiftUI
|
| 140 |
+
import whisper
|
| 141 |
+
|
| 142 |
+
struct ContentView: View {
|
| 143 |
+
// Test that we can initialize a whisper context params struct
|
| 144 |
+
let params = whisper_context_default_params()
|
| 145 |
+
|
| 146 |
+
var body: some View {
|
| 147 |
+
VStack(spacing: 40) {
|
| 148 |
+
Text("Whisper Framework Test on tvOS")
|
| 149 |
+
.font(.largeTitle)
|
| 150 |
+
.padding()
|
| 151 |
+
|
| 152 |
+
Text("whisper_context_default_params() created successfully")
|
| 153 |
+
.font(.headline)
|
| 154 |
+
.multilineTextAlignment(.center)
|
| 155 |
+
.padding()
|
| 156 |
+
|
| 157 |
+
// Display some param values to confirm the framework is working
|
| 158 |
+
Text("dtw_n_top: \(params.dtw_n_top)")
|
| 159 |
+
.font(.body)
|
| 160 |
+
|
| 161 |
+
Spacer()
|
| 162 |
+
}
|
| 163 |
+
.padding(50)
|
| 164 |
+
// Larger size suitable for TV display
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
struct ContentView_Previews: PreviewProvider {
|
| 169 |
+
static var previews: some View {
|
| 170 |
+
ContentView()
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
EOF
|
| 174 |
+
|
| 175 |
+
# Create project.pbxproj, fixing the framework search paths issues
|
| 176 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
|
| 177 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 178 |
+
// !$*UTF8*$!
|
| 179 |
+
{
|
| 180 |
+
archiveVersion = 1;
|
| 181 |
+
classes = {
|
| 182 |
+
};
|
| 183 |
+
objectVersion = 54;
|
| 184 |
+
objects = {
|
| 185 |
+
|
| 186 |
+
/* Begin PBXBuildFile section */
|
| 187 |
+
11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
|
| 188 |
+
33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
|
| 189 |
+
55555555555555555555555 /* whisper.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 190 |
+
77777777777777777777777 /* whisper.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 191 |
+
/* End PBXBuildFile section */
|
| 192 |
+
|
| 193 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 194 |
+
88888888888888888888888 /* Embed Frameworks */ = {
|
| 195 |
+
isa = PBXCopyFilesBuildPhase;
|
| 196 |
+
buildActionMask = 2147483647;
|
| 197 |
+
dstPath = "";
|
| 198 |
+
dstSubfolderSpec = 10;
|
| 199 |
+
files = (
|
| 200 |
+
77777777777777777777777 /* whisper.xcframework in Embed Frameworks */,
|
| 201 |
+
);
|
| 202 |
+
name = "Embed Frameworks";
|
| 203 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 204 |
+
};
|
| 205 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 206 |
+
|
| 207 |
+
/* Begin PBXFileReference section */
|
| 208 |
+
EOF
|
| 209 |
+
|
| 210 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 211 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 212 |
+
99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 213 |
+
22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
| 214 |
+
44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
| 215 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
| 216 |
+
66666666666666666666666 /* whisper.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = whisper.xcframework; sourceTree = "<group>"; };
|
| 217 |
+
/* End PBXFileReference section */
|
| 218 |
+
EOF
|
| 219 |
+
|
| 220 |
+
# Add the rest of the project file with fixed framework search paths
|
| 221 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 222 |
+
/* Begin PBXFrameworksBuildPhase section */
|
| 223 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
|
| 224 |
+
isa = PBXFrameworksBuildPhase;
|
| 225 |
+
buildActionMask = 2147483647;
|
| 226 |
+
files = (
|
| 227 |
+
55555555555555555555555 /* whisper.xcframework in Frameworks */,
|
| 228 |
+
);
|
| 229 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 230 |
+
};
|
| 231 |
+
/* End PBXFrameworksBuildPhase section */
|
| 232 |
+
|
| 233 |
+
/* Begin PBXGroup section */
|
| 234 |
+
EOF
|
| 235 |
+
|
| 236 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 237 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 238 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
|
| 239 |
+
isa = PBXGroup;
|
| 240 |
+
children = (
|
| 241 |
+
99999999999999999999999 /* ${APP_NAME}.app */,
|
| 242 |
+
);
|
| 243 |
+
name = Products;
|
| 244 |
+
sourceTree = "<group>";
|
| 245 |
+
};
|
| 246 |
+
EOF
|
| 247 |
+
|
| 248 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 249 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
|
| 250 |
+
isa = PBXGroup;
|
| 251 |
+
children = (
|
| 252 |
+
66666666666666666666666 /* whisper.xcframework */,
|
| 253 |
+
);
|
| 254 |
+
name = Frameworks;
|
| 255 |
+
sourceTree = "<group>";
|
| 256 |
+
};
|
| 257 |
+
EEEEEEEEEEEEEEEEEEEEEEEE = {
|
| 258 |
+
isa = PBXGroup;
|
| 259 |
+
children = (
|
| 260 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSWhisperTest */,
|
| 261 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
|
| 262 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
|
| 263 |
+
);
|
| 264 |
+
sourceTree = "<group>";
|
| 265 |
+
};
|
| 266 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSWhisperTest */ = {
|
| 267 |
+
isa = PBXGroup;
|
| 268 |
+
children = (
|
| 269 |
+
1111111111111111111111AA /* Sources */,
|
| 270 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
|
| 271 |
+
);
|
| 272 |
+
path = "TVOSWhisperTest";
|
| 273 |
+
sourceTree = "<group>";
|
| 274 |
+
};
|
| 275 |
+
1111111111111111111111AA /* Sources */ = {
|
| 276 |
+
isa = PBXGroup;
|
| 277 |
+
children = (
|
| 278 |
+
22222222222222222222222 /* App.swift */,
|
| 279 |
+
44444444444444444444444 /* ContentView.swift */,
|
| 280 |
+
);
|
| 281 |
+
path = Sources;
|
| 282 |
+
sourceTree = "<group>";
|
| 283 |
+
};
|
| 284 |
+
/* End PBXGroup section */
|
| 285 |
+
EOF
|
| 286 |
+
|
| 287 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 288 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 289 |
+
/* Begin PBXNativeTarget section */
|
| 290 |
+
3333333333333333333333AA /* ${APP_NAME} */ = {
|
| 291 |
+
isa = PBXNativeTarget;
|
| 292 |
+
buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
|
| 293 |
+
buildPhases = (
|
| 294 |
+
5555555555555555555555AA /* Sources */,
|
| 295 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
|
| 296 |
+
6666666666666666666666AA /* Resources */,
|
| 297 |
+
88888888888888888888888 /* Embed Frameworks */,
|
| 298 |
+
);
|
| 299 |
+
buildRules = (
|
| 300 |
+
);
|
| 301 |
+
dependencies = (
|
| 302 |
+
);
|
| 303 |
+
name = "${APP_NAME}";
|
| 304 |
+
productName = "${APP_NAME}";
|
| 305 |
+
productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
|
| 306 |
+
productType = "com.apple.product-type.application";
|
| 307 |
+
};
|
| 308 |
+
/* End PBXNativeTarget section */
|
| 309 |
+
|
| 310 |
+
/* Begin PBXProject section */
|
| 311 |
+
7777777777777777777777AA /* Project object */ = {
|
| 312 |
+
isa = PBXProject;
|
| 313 |
+
attributes = {
|
| 314 |
+
LastSwiftUpdateCheck = 1240;
|
| 315 |
+
LastUpgradeCheck = 1240;
|
| 316 |
+
TargetAttributes = {
|
| 317 |
+
3333333333333333333333AA = {
|
| 318 |
+
CreatedOnToolsVersion = 12.4;
|
| 319 |
+
};
|
| 320 |
+
};
|
| 321 |
+
};
|
| 322 |
+
buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
|
| 323 |
+
compatibilityVersion = "Xcode 12.0";
|
| 324 |
+
developmentRegion = en;
|
| 325 |
+
hasScannedForEncodings = 0;
|
| 326 |
+
knownRegions = (
|
| 327 |
+
en,
|
| 328 |
+
Base,
|
| 329 |
+
);
|
| 330 |
+
mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
|
| 331 |
+
productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
|
| 332 |
+
projectDirPath = "";
|
| 333 |
+
projectRoot = "";
|
| 334 |
+
targets = (
|
| 335 |
+
3333333333333333333333AA /* ${APP_NAME} */,
|
| 336 |
+
);
|
| 337 |
+
};
|
| 338 |
+
/* End PBXProject section */
|
| 339 |
+
EOF
|
| 340 |
+
|
| 341 |
+
# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS and tvOS settings
|
| 342 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 343 |
+
/* Begin PBXResourcesBuildPhase section */
|
| 344 |
+
6666666666666666666666AA /* Resources */ = {
|
| 345 |
+
isa = PBXResourcesBuildPhase;
|
| 346 |
+
buildActionMask = 2147483647;
|
| 347 |
+
files = (
|
| 348 |
+
);
|
| 349 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 350 |
+
};
|
| 351 |
+
/* End PBXResourcesBuildPhase section */
|
| 352 |
+
|
| 353 |
+
/* Begin PBXSourcesBuildPhase section */
|
| 354 |
+
5555555555555555555555AA /* Sources */ = {
|
| 355 |
+
isa = PBXSourcesBuildPhase;
|
| 356 |
+
buildActionMask = 2147483647;
|
| 357 |
+
files = (
|
| 358 |
+
33333333333333333333333 /* ContentView.swift in Sources */,
|
| 359 |
+
11111111111111111111111 /* App.swift in Sources */,
|
| 360 |
+
);
|
| 361 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 362 |
+
};
|
| 363 |
+
/* End PBXSourcesBuildPhase section */
|
| 364 |
+
|
| 365 |
+
/* Begin XCBuildConfiguration section */
|
| 366 |
+
9999999999999999999999AA /* Debug */ = {
|
| 367 |
+
isa = XCBuildConfiguration;
|
| 368 |
+
buildSettings = {
|
| 369 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 370 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 371 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 372 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 373 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 374 |
+
CLANG_ENABLE_MODULES = YES;
|
| 375 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 376 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 377 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 378 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 379 |
+
CLANG_WARN_COMMA = YES;
|
| 380 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 381 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 382 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 383 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 384 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 385 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 386 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 387 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 388 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 389 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 390 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 391 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 392 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 393 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 394 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 395 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 396 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 397 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 398 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 399 |
+
COPY_PHASE_STRIP = NO;
|
| 400 |
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
| 401 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 402 |
+
ENABLE_TESTABILITY = YES;
|
| 403 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 404 |
+
GCC_DYNAMIC_NO_PIC = NO;
|
| 405 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 406 |
+
GCC_OPTIMIZATION_LEVEL = 0;
|
| 407 |
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
| 408 |
+
"DEBUG=1",
|
| 409 |
+
"$(inherited)",
|
| 410 |
+
);
|
| 411 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 412 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 413 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 414 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 415 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 416 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 417 |
+
TVOS_DEPLOYMENT_TARGET = 15.0;
|
| 418 |
+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 419 |
+
MTL_FAST_MATH = YES;
|
| 420 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 421 |
+
SDKROOT = appletvos;
|
| 422 |
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 423 |
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
| 424 |
+
};
|
| 425 |
+
name = Debug;
|
| 426 |
+
};
|
| 427 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
|
| 428 |
+
isa = XCBuildConfiguration;
|
| 429 |
+
buildSettings = {
|
| 430 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 431 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 432 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 433 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 434 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 435 |
+
CLANG_ENABLE_MODULES = YES;
|
| 436 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 437 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 438 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 439 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 440 |
+
CLANG_WARN_COMMA = YES;
|
| 441 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 442 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 443 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 444 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 445 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 446 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 447 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 448 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 449 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 450 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 451 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 452 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 453 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 454 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 455 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 456 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 457 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 458 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 459 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 460 |
+
COPY_PHASE_STRIP = NO;
|
| 461 |
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
| 462 |
+
ENABLE_NS_ASSERTIONS = NO;
|
| 463 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 464 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 465 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 466 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 467 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 468 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 469 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 470 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 471 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 472 |
+
TVOS_DEPLOYMENT_TARGET = 15.0;
|
| 473 |
+
MTL_ENABLE_DEBUG_INFO = NO;
|
| 474 |
+
MTL_FAST_MATH = YES;
|
| 475 |
+
SDKROOT = appletvos;
|
| 476 |
+
SWIFT_COMPILATION_MODE = wholemodule;
|
| 477 |
+
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
| 478 |
+
VALIDATE_PRODUCT = YES;
|
| 479 |
+
};
|
| 480 |
+
name = Release;
|
| 481 |
+
};
|
| 482 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
|
| 483 |
+
isa = XCBuildConfiguration;
|
| 484 |
+
buildSettings = {
|
| 485 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 486 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 487 |
+
CODE_SIGN_STYLE = Manual;
|
| 488 |
+
DEVELOPMENT_TEAM = "";
|
| 489 |
+
ENABLE_PREVIEWS = YES;
|
| 490 |
+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
| 491 |
+
INFOPLIST_FILE = "TVOSWhisperTest/Info.plist";
|
| 492 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 493 |
+
"$(inherited)",
|
| 494 |
+
"@executable_path/Frameworks",
|
| 495 |
+
);
|
| 496 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSWhisperTest";
|
| 497 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 498 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 499 |
+
SWIFT_VERSION = 5.0;
|
| 500 |
+
TARGETED_DEVICE_FAMILY = 3;
|
| 501 |
+
};
|
| 502 |
+
name = Debug;
|
| 503 |
+
};
|
| 504 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
|
| 505 |
+
isa = XCBuildConfiguration;
|
| 506 |
+
buildSettings = {
|
| 507 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 508 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 509 |
+
CODE_SIGN_STYLE = Manual;
|
| 510 |
+
DEVELOPMENT_TEAM = "";
|
| 511 |
+
ENABLE_PREVIEWS = YES;
|
| 512 |
+
FRAMEWORK_SEARCH_PATHS = (
|
| 513 |
+
"$(inherited)",
|
| 514 |
+
"$(PROJECT_DIR)",
|
| 515 |
+
);
|
| 516 |
+
INFOPLIST_FILE = "TVOSWhisperTest/Info.plist";
|
| 517 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 518 |
+
"$(inherited)",
|
| 519 |
+
"@executable_path/Frameworks",
|
| 520 |
+
);
|
| 521 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSWhisperTest";
|
| 522 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 523 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 524 |
+
SWIFT_VERSION = 5.0;
|
| 525 |
+
TARGETED_DEVICE_FAMILY = 3;
|
| 526 |
+
};
|
| 527 |
+
name = Release;
|
| 528 |
+
};
|
| 529 |
+
/* End XCBuildConfiguration section */
|
| 530 |
+
EOF
|
| 531 |
+
|
| 532 |
+
# Finish the project.pbxproj file
|
| 533 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 534 |
+
/* Begin XCConfigurationList section */
|
| 535 |
+
8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
|
| 536 |
+
isa = XCConfigurationList;
|
| 537 |
+
buildConfigurations = (
|
| 538 |
+
9999999999999999999999AA /* Debug */,
|
| 539 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
|
| 540 |
+
);
|
| 541 |
+
defaultConfigurationIsVisible = 0;
|
| 542 |
+
defaultConfigurationName = Release;
|
| 543 |
+
};
|
| 544 |
+
4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
|
| 545 |
+
isa = XCConfigurationList;
|
| 546 |
+
buildConfigurations = (
|
| 547 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
|
| 548 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
|
| 549 |
+
);
|
| 550 |
+
defaultConfigurationIsVisible = 0;
|
| 551 |
+
defaultConfigurationName = Release;
|
| 552 |
+
};
|
| 553 |
+
/* End XCConfigurationList section */
|
| 554 |
+
};
|
| 555 |
+
rootObject = 7777777777777777777777AA /* Project object */;
|
| 556 |
+
}
|
| 557 |
+
EOF
|
| 558 |
+
|
| 559 |
+
# 2. Copy XCFramework to test project
|
| 560 |
+
echo "Copying XCFramework to test project..."
|
| 561 |
+
cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
|
| 562 |
+
|
| 563 |
+
# 3. Build and archive the app
|
| 564 |
+
echo "Building and archiving test app..."
|
| 565 |
+
cd "${TEMP_DIR}/${APP_NAME}"
|
| 566 |
+
|
| 567 |
+
# Create a simple xcscheme file to avoid xcodebuild scheme issues
|
| 568 |
+
mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
|
| 569 |
+
cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
|
| 570 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 571 |
+
<Scheme
|
| 572 |
+
LastUpgradeVersion = "1240"
|
| 573 |
+
version = "1.3">
|
| 574 |
+
<BuildAction
|
| 575 |
+
parallelizeBuildables = "YES"
|
| 576 |
+
buildImplicitDependencies = "YES">
|
| 577 |
+
<BuildActionEntries>
|
| 578 |
+
<BuildActionEntry
|
| 579 |
+
buildForTesting = "YES"
|
| 580 |
+
buildForRunning = "YES"
|
| 581 |
+
buildForProfiling = "YES"
|
| 582 |
+
buildForArchiving = "YES"
|
| 583 |
+
buildForAnalyzing = "YES">
|
| 584 |
+
<BuildableReference
|
| 585 |
+
BuildableIdentifier = "primary"
|
| 586 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 587 |
+
BuildableName = "${APP_NAME}.app"
|
| 588 |
+
BlueprintName = "${APP_NAME}"
|
| 589 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 590 |
+
</BuildableReference>
|
| 591 |
+
</BuildActionEntry>
|
| 592 |
+
</BuildActionEntries>
|
| 593 |
+
</BuildAction>
|
| 594 |
+
<TestAction
|
| 595 |
+
buildConfiguration = "Debug"
|
| 596 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 597 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 598 |
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
| 599 |
+
<Testables>
|
| 600 |
+
</Testables>
|
| 601 |
+
</TestAction>
|
| 602 |
+
<LaunchAction
|
| 603 |
+
buildConfiguration = "Debug"
|
| 604 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 605 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 606 |
+
launchStyle = "0"
|
| 607 |
+
useCustomWorkingDirectory = "NO"
|
| 608 |
+
ignoresPersistentStateOnLaunch = "NO"
|
| 609 |
+
debugDocumentVersioning = "YES"
|
| 610 |
+
debugServiceExtension = "internal"
|
| 611 |
+
allowLocationSimulation = "YES">
|
| 612 |
+
<BuildableProductRunnable
|
| 613 |
+
runnableDebuggingMode = "0">
|
| 614 |
+
<BuildableReference
|
| 615 |
+
BuildableIdentifier = "primary"
|
| 616 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 617 |
+
BuildableName = "${APP_NAME}.app"
|
| 618 |
+
BlueprintName = "${APP_NAME}"
|
| 619 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 620 |
+
</BuildableReference>
|
| 621 |
+
</BuildableProductRunnable>
|
| 622 |
+
</LaunchAction>
|
| 623 |
+
<ProfileAction
|
| 624 |
+
buildConfiguration = "Release"
|
| 625 |
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
| 626 |
+
savedToolIdentifier = ""
|
| 627 |
+
useCustomWorkingDirectory = "NO"
|
| 628 |
+
debugDocumentVersioning = "YES">
|
| 629 |
+
<BuildableProductRunnable
|
| 630 |
+
runnableDebuggingMode = "0">
|
| 631 |
+
<BuildableReference
|
| 632 |
+
BuildableIdentifier = "primary"
|
| 633 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 634 |
+
BuildableName = "${APP_NAME}.app"
|
| 635 |
+
BlueprintName = "${APP_NAME}"
|
| 636 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 637 |
+
</BuildableReference>
|
| 638 |
+
</BuildableProductRunnable>
|
| 639 |
+
</ProfileAction>
|
| 640 |
+
<AnalyzeAction
|
| 641 |
+
buildConfiguration = "Debug">
|
| 642 |
+
</AnalyzeAction>
|
| 643 |
+
<ArchiveAction
|
| 644 |
+
buildConfiguration = "Release"
|
| 645 |
+
revealArchiveInOrganizer = "YES">
|
| 646 |
+
</ArchiveAction>
|
| 647 |
+
</Scheme>
|
| 648 |
+
EOF
|
| 649 |
+
|
| 650 |
+
# Now use xcodebuild with an explicitly defined product name for tvOS
|
| 651 |
+
xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk appletvos -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
|
| 652 |
+
|
| 653 |
+
# 4. Create IPA from archive
|
| 654 |
+
echo "Creating IPA from archive..."
|
| 655 |
+
mkdir -p "${TEMP_DIR}/Payload"
|
| 656 |
+
cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
|
| 657 |
+
|
| 658 |
+
# Check and log app structure before zipping
|
| 659 |
+
echo "App structure:"
|
| 660 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
|
| 661 |
+
echo "Frameworks:"
|
| 662 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 663 |
+
|
| 664 |
+
cd "${TEMP_DIR}"
|
| 665 |
+
zip -r "${IPA_PATH}" Payload
|
| 666 |
+
|
| 667 |
+
# Check embedded provisioning profile
|
| 668 |
+
echo "Checking provisioning profile (if any)..."
|
| 669 |
+
PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
|
| 670 |
+
if [ -n "$PROVISIONING_PROFILE" ]; then
|
| 671 |
+
echo "Found embedded provisioning profile:"
|
| 672 |
+
security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
|
| 673 |
+
else
|
| 674 |
+
echo "No embedded provisioning profile found (expected for ad-hoc builds)"
|
| 675 |
+
fi
|
| 676 |
+
|
| 677 |
+
# 5. Validate the IPA
|
| 678 |
+
echo "Validating IPA..."
|
| 679 |
+
VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
|
| 680 |
+
|
| 681 |
+
# Check if authentication credentials are provided
|
| 682 |
+
AUTH_ARGS=""
|
| 683 |
+
if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
|
| 684 |
+
echo "Using Apple ID authentication for validation..."
|
| 685 |
+
AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
|
| 686 |
+
else
|
| 687 |
+
echo "No authentication credentials provided. Will perform basic validation."
|
| 688 |
+
echo "To use your personal developer account, you can run the script with:"
|
| 689 |
+
echo " APPLE_ID='[email protected]' APPLE_PASSWORD='your-app-specific-password' ./validate-tvos.sh"
|
| 690 |
+
echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
|
| 691 |
+
fi
|
| 692 |
+
|
| 693 |
+
# Run validation with detailed output
|
| 694 |
+
echo "Running validation with altool..."
|
| 695 |
+
if [ -n "$AUTH_ARGS" ]; then
|
| 696 |
+
# Use eval to properly handle the quoted arguments
|
| 697 |
+
eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type tvos --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 698 |
+
else
|
| 699 |
+
xcrun altool --validate-app -f "${IPA_PATH}" --type tvos --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 700 |
+
fi
|
| 701 |
+
VALIDATION_RESULT=$?
|
| 702 |
+
|
| 703 |
+
# Final validation result
|
| 704 |
+
FINAL_VALIDATION_RESULT=0
|
| 705 |
+
|
| 706 |
+
# Check if validation failed because the app isn't in App Store Connect
|
| 707 |
+
if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
|
| 708 |
+
echo "β οΈ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
|
| 709 |
+
echo "This is expected for apps that haven't been registered in App Store Connect yet."
|
| 710 |
+
echo "This doesn't indicate a problem with the build or framework."
|
| 711 |
+
|
| 712 |
+
# Perform alternative validation
|
| 713 |
+
echo "Performing alternative validation checks..."
|
| 714 |
+
|
| 715 |
+
# Check if IPA was created successfully
|
| 716 |
+
if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
|
| 717 |
+
echo "β
IPA file created successfully"
|
| 718 |
+
else
|
| 719 |
+
echo "β IPA file not created or empty"
|
| 720 |
+
FINAL_VALIDATION_RESULT=1
|
| 721 |
+
fi
|
| 722 |
+
|
| 723 |
+
# Check if app binary exists and is executable
|
| 724 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
|
| 725 |
+
echo "β
App binary exists and is executable"
|
| 726 |
+
else
|
| 727 |
+
echo "β App binary missing or not executable"
|
| 728 |
+
FINAL_VALIDATION_RESULT=1
|
| 729 |
+
fi
|
| 730 |
+
|
| 731 |
+
# Check if framework was properly embedded
|
| 732 |
+
if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework" ]; then
|
| 733 |
+
echo "β
whisper.framework properly embedded"
|
| 734 |
+
else
|
| 735 |
+
echo "β whisper.framework not properly embedded"
|
| 736 |
+
FINAL_VALIDATION_RESULT=1
|
| 737 |
+
fi
|
| 738 |
+
|
| 739 |
+
# Check if framework binary exists
|
| 740 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework/whisper" ]; then
|
| 741 |
+
echo "β
Framework binary exists"
|
| 742 |
+
|
| 743 |
+
# Further validate framework by checking architecture
|
| 744 |
+
ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework/whisper" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
|
| 745 |
+
if [ -n "$ARCHS" ]; then
|
| 746 |
+
echo "β
Framework architecture(s): $ARCHS"
|
| 747 |
+
else
|
| 748 |
+
echo "β οΈ Could not determine framework architecture"
|
| 749 |
+
fi
|
| 750 |
+
else
|
| 751 |
+
echo "β Framework binary missing"
|
| 752 |
+
FINAL_VALIDATION_RESULT=1
|
| 753 |
+
fi
|
| 754 |
+
|
| 755 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 756 |
+
echo "β
Alternative validation PASSED: App built successfully with embedded framework"
|
| 757 |
+
else
|
| 758 |
+
echo "β Alternative validation FAILED: Issues found with the app or framework"
|
| 759 |
+
fi
|
| 760 |
+
elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
|
| 761 |
+
echo "β
tvOS Validation PASSED: IPA successfully validated"
|
| 762 |
+
echo "Results saved to ${VALIDATION_OUTPUT}"
|
| 763 |
+
else
|
| 764 |
+
echo "β tvOS Validation FAILED: IPA validation found issues"
|
| 765 |
+
echo "See validation output at ${VALIDATION_OUTPUT}"
|
| 766 |
+
echo ""
|
| 767 |
+
echo "==== VALIDATION ERRORS ===="
|
| 768 |
+
|
| 769 |
+
# Try to extract specific errors from the output
|
| 770 |
+
if grep -q "Error" "${VALIDATION_OUTPUT}"; then
|
| 771 |
+
grep -A 5 "Error" "${VALIDATION_OUTPUT}"
|
| 772 |
+
else
|
| 773 |
+
# If no specific error found, show the whole log
|
| 774 |
+
cat "${VALIDATION_OUTPUT}"
|
| 775 |
+
fi
|
| 776 |
+
|
| 777 |
+
# Additional debugging: check IPA contents
|
| 778 |
+
echo ""
|
| 779 |
+
echo "==== IPA CONTENTS ===="
|
| 780 |
+
mkdir -p "${TEMP_DIR}/ipa_contents"
|
| 781 |
+
unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
|
| 782 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
|
| 783 |
+
|
| 784 |
+
# Check for code signing issues
|
| 785 |
+
echo ""
|
| 786 |
+
echo "==== CODE SIGNING INFO ===="
|
| 787 |
+
codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
|
| 788 |
+
|
| 789 |
+
# Check embedded frameworks
|
| 790 |
+
echo ""
|
| 791 |
+
echo "==== FRAMEWORK INFO ===="
|
| 792 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 793 |
+
fi
|
| 794 |
+
|
| 795 |
+
# Don't clean up on error to allow inspection
|
| 796 |
+
if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
|
| 797 |
+
echo ""
|
| 798 |
+
echo "Temporary files kept for inspection at: ${TEMP_DIR}"
|
| 799 |
+
echo "===== tvOS Validation Process Failed ====="
|
| 800 |
+
exit 1
|
| 801 |
+
fi
|
| 802 |
+
|
| 803 |
+
# Clean up temporary files but keep build artifacts
|
| 804 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 805 |
+
echo "Cleaning up temporary files..."
|
| 806 |
+
#rm -rf "${TEMP_DIR}"
|
| 807 |
+
fi
|
| 808 |
+
|
| 809 |
+
echo "===== tvOS Validation Process Completed ====="
|
| 810 |
+
exit $FINAL_VALIDATION_RESULT
|
scripts/apple/validate-visionos.sh
ADDED
|
@@ -0,0 +1,808 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# validate-visionos.sh - Validate visionOS Application with embedded whisper.xcframework using SwiftUI
|
| 3 |
+
|
| 4 |
+
# Authentication options (optional) (can be set via environment variables)
|
| 5 |
+
# To use: export [email protected]
|
| 6 |
+
# export APPLE_PASSWORD=your-app-specific-password
|
| 7 |
+
# ./validate-visionos.sh
|
| 8 |
+
APPLE_ID=${APPLE_ID:-""}
|
| 9 |
+
APPLE_PASSWORD=${APPLE_PASSWORD:-""}
|
| 10 |
+
|
| 11 |
+
# Ensure the script exits on error
|
| 12 |
+
set -e
|
| 13 |
+
|
| 14 |
+
# Function to print usage instructions
|
| 15 |
+
print_usage() {
|
| 16 |
+
echo "Usage: ./validate-visionos.sh [OPTIONS]"
|
| 17 |
+
echo ""
|
| 18 |
+
echo "Options:"
|
| 19 |
+
echo " --help Show this help message"
|
| 20 |
+
echo " --apple-id EMAIL Apple ID email for validation"
|
| 21 |
+
echo " --apple-password PWD App-specific password for Apple ID"
|
| 22 |
+
echo ""
|
| 23 |
+
echo "Environment variables:"
|
| 24 |
+
echo " APPLE_ID Apple ID email for validation"
|
| 25 |
+
echo " APPLE_PASSWORD App-specific password for Apple ID"
|
| 26 |
+
echo ""
|
| 27 |
+
echo "Notes:"
|
| 28 |
+
echo " - Command line options take precedence over environment variables"
|
| 29 |
+
echo " - Authentication is optional. If not provided, alternative validation will be performed"
|
| 30 |
+
echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
# Parse command line arguments
|
| 34 |
+
while [[ $# -gt 0 ]]; do
|
| 35 |
+
case $1 in
|
| 36 |
+
--help)
|
| 37 |
+
print_usage
|
| 38 |
+
exit 0
|
| 39 |
+
;;
|
| 40 |
+
--apple-id)
|
| 41 |
+
APPLE_ID="$2"
|
| 42 |
+
shift 2
|
| 43 |
+
;;
|
| 44 |
+
--apple-password)
|
| 45 |
+
APPLE_PASSWORD="$2"
|
| 46 |
+
shift 2
|
| 47 |
+
;;
|
| 48 |
+
*)
|
| 49 |
+
echo "Unknown option: $1"
|
| 50 |
+
print_usage
|
| 51 |
+
exit 1
|
| 52 |
+
;;
|
| 53 |
+
esac
|
| 54 |
+
done
|
| 55 |
+
|
| 56 |
+
# Function to clean up in case of error
|
| 57 |
+
cleanup() {
|
| 58 |
+
# Don't clean up temp files on error to help with debugging
|
| 59 |
+
echo "===== visionOS Validation Process Failed ====="
|
| 60 |
+
exit 1
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
# Set up trap to call cleanup function on error
|
| 64 |
+
trap cleanup ERR
|
| 65 |
+
|
| 66 |
+
set -e # Exit on any error
|
| 67 |
+
|
| 68 |
+
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
| 69 |
+
BUILD_DIR="${ROOT_DIR}/validation-builds/visionos"
|
| 70 |
+
|
| 71 |
+
# Configuration
|
| 72 |
+
APP_NAME="VisionOSWhisperTest"
|
| 73 |
+
BUNDLE_ID="org.ggml.VisionOSWhisperTest"
|
| 74 |
+
XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/whisper.xcframework"
|
| 75 |
+
TEMP_DIR="${BUILD_DIR}/temp"
|
| 76 |
+
ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
|
| 77 |
+
IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
|
| 78 |
+
VALIDATION_DIR="${BUILD_DIR}/validation"
|
| 79 |
+
|
| 80 |
+
# Create necessary directories
|
| 81 |
+
mkdir -p "${BUILD_DIR}"
|
| 82 |
+
mkdir -p "${TEMP_DIR}"
|
| 83 |
+
mkdir -p "${VALIDATION_DIR}"
|
| 84 |
+
|
| 85 |
+
echo "===== visionOS Validation Process Started ====="
|
| 86 |
+
|
| 87 |
+
# 1. Create a simple test app project
|
| 88 |
+
echo "Creating test visionOS app project..."
|
| 89 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
|
| 90 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
|
| 91 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 92 |
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
| 93 |
+
<plist version="1.0">
|
| 94 |
+
<dict>
|
| 95 |
+
<key>CFBundleDevelopmentRegion</key>
|
| 96 |
+
<string>en</string>
|
| 97 |
+
<key>CFBundleExecutable</key>
|
| 98 |
+
<string>${APP_NAME}</string>
|
| 99 |
+
<key>CFBundleIdentifier</key>
|
| 100 |
+
<string>${BUNDLE_ID}</string>
|
| 101 |
+
<key>CFBundleInfoDictionaryVersion</key>
|
| 102 |
+
<string>6.0</string>
|
| 103 |
+
<key>CFBundleName</key>
|
| 104 |
+
<string>${APP_NAME}</string>
|
| 105 |
+
<key>CFBundlePackageType</key>
|
| 106 |
+
<string>APPL</string>
|
| 107 |
+
<key>CFBundleShortVersionString</key>
|
| 108 |
+
<string>1.0</string>
|
| 109 |
+
<key>CFBundleVersion</key>
|
| 110 |
+
<string>1</string>
|
| 111 |
+
</dict>
|
| 112 |
+
</plist>
|
| 113 |
+
EOF
|
| 114 |
+
|
| 115 |
+
# Create SwiftUI app files
|
| 116 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
|
| 117 |
+
|
| 118 |
+
# Create App.swift
|
| 119 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
|
| 120 |
+
import SwiftUI
|
| 121 |
+
import whisper
|
| 122 |
+
|
| 123 |
+
@main
|
| 124 |
+
struct WhisperTestApp: App {
|
| 125 |
+
var body: some Scene {
|
| 126 |
+
WindowGroup {
|
| 127 |
+
ContentView()
|
| 128 |
+
}
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
EOF
|
| 132 |
+
|
| 133 |
+
# Create ContentView.swift with visionOS specific elements
|
| 134 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
|
| 135 |
+
import SwiftUI
|
| 136 |
+
import whisper
|
| 137 |
+
|
| 138 |
+
struct ContentView: View {
|
| 139 |
+
// Test that we can initialize a whisper context params struct
|
| 140 |
+
let params = whisper_context_default_params()
|
| 141 |
+
|
| 142 |
+
var body: some View {
|
| 143 |
+
VStack(spacing: 20) {
|
| 144 |
+
Text("Whisper Framework Test on visionOS")
|
| 145 |
+
.font(.largeTitle)
|
| 146 |
+
.padding()
|
| 147 |
+
|
| 148 |
+
Text("whisper_context_default_params() created successfully")
|
| 149 |
+
.font(.headline)
|
| 150 |
+
.multilineTextAlignment(.center)
|
| 151 |
+
.padding()
|
| 152 |
+
|
| 153 |
+
// Display some param values to confirm the framework is working
|
| 154 |
+
Text("dtw_n_top: \(params.dtw_n_top)")
|
| 155 |
+
.font(.body)
|
| 156 |
+
|
| 157 |
+
Spacer()
|
| 158 |
+
}
|
| 159 |
+
.padding()
|
| 160 |
+
.frame(width: 500, height: 400)
|
| 161 |
+
}
|
| 162 |
+
}
|
| 163 |
+
|
| 164 |
+
struct ContentView_Previews: PreviewProvider {
|
| 165 |
+
static var previews: some View {
|
| 166 |
+
ContentView()
|
| 167 |
+
}
|
| 168 |
+
}
|
| 169 |
+
EOF
|
| 170 |
+
|
| 171 |
+
# Create project.pbxproj, fixing the framework search paths issues
|
| 172 |
+
mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
|
| 173 |
+
cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 174 |
+
// !$*UTF8*$!
|
| 175 |
+
{
|
| 176 |
+
archiveVersion = 1;
|
| 177 |
+
classes = {
|
| 178 |
+
};
|
| 179 |
+
objectVersion = 54;
|
| 180 |
+
objects = {
|
| 181 |
+
|
| 182 |
+
/* Begin PBXBuildFile section */
|
| 183 |
+
11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
|
| 184 |
+
33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
|
| 185 |
+
55555555555555555555555 /* whisper.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 186 |
+
77777777777777777777777 /* whisper.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
|
| 187 |
+
/* End PBXBuildFile section */
|
| 188 |
+
|
| 189 |
+
/* Begin PBXCopyFilesBuildPhase section */
|
| 190 |
+
88888888888888888888888 /* Embed Frameworks */ = {
|
| 191 |
+
isa = PBXCopyFilesBuildPhase;
|
| 192 |
+
buildActionMask = 2147483647;
|
| 193 |
+
dstPath = "";
|
| 194 |
+
dstSubfolderSpec = 10;
|
| 195 |
+
files = (
|
| 196 |
+
77777777777777777777777 /* whisper.xcframework in Embed Frameworks */,
|
| 197 |
+
);
|
| 198 |
+
name = "Embed Frameworks";
|
| 199 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 200 |
+
};
|
| 201 |
+
/* End PBXCopyFilesBuildPhase section */
|
| 202 |
+
|
| 203 |
+
/* Begin PBXFileReference section */
|
| 204 |
+
EOF
|
| 205 |
+
|
| 206 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 207 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 208 |
+
99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
| 209 |
+
22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
|
| 210 |
+
44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
| 211 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
| 212 |
+
66666666666666666666666 /* whisper.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = whisper.xcframework; sourceTree = "<group>"; };
|
| 213 |
+
/* End PBXFileReference section */
|
| 214 |
+
EOF
|
| 215 |
+
|
| 216 |
+
# Add the rest of the project file with fixed framework search paths
|
| 217 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 218 |
+
/* Begin PBXFrameworksBuildPhase section */
|
| 219 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
|
| 220 |
+
isa = PBXFrameworksBuildPhase;
|
| 221 |
+
buildActionMask = 2147483647;
|
| 222 |
+
files = (
|
| 223 |
+
55555555555555555555555 /* whisper.xcframework in Frameworks */,
|
| 224 |
+
);
|
| 225 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 226 |
+
};
|
| 227 |
+
/* End PBXFrameworksBuildPhase section */
|
| 228 |
+
|
| 229 |
+
/* Begin PBXGroup section */
|
| 230 |
+
EOF
|
| 231 |
+
|
| 232 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 233 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 234 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
|
| 235 |
+
isa = PBXGroup;
|
| 236 |
+
children = (
|
| 237 |
+
99999999999999999999999 /* ${APP_NAME}.app */,
|
| 238 |
+
);
|
| 239 |
+
name = Products;
|
| 240 |
+
sourceTree = "<group>";
|
| 241 |
+
};
|
| 242 |
+
EOF
|
| 243 |
+
|
| 244 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 245 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
|
| 246 |
+
isa = PBXGroup;
|
| 247 |
+
children = (
|
| 248 |
+
66666666666666666666666 /* whisper.xcframework */,
|
| 249 |
+
);
|
| 250 |
+
name = Frameworks;
|
| 251 |
+
sourceTree = "<group>";
|
| 252 |
+
};
|
| 253 |
+
EEEEEEEEEEEEEEEEEEEEEEEE = {
|
| 254 |
+
isa = PBXGroup;
|
| 255 |
+
children = (
|
| 256 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* VisionOSWhisperTest */,
|
| 257 |
+
CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
|
| 258 |
+
DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
|
| 259 |
+
);
|
| 260 |
+
sourceTree = "<group>";
|
| 261 |
+
};
|
| 262 |
+
FFFFFFFFFFFFFFFFFFFFFFFF /* VisionOSWhisperTest */ = {
|
| 263 |
+
isa = PBXGroup;
|
| 264 |
+
children = (
|
| 265 |
+
1111111111111111111111AA /* Sources */,
|
| 266 |
+
AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
|
| 267 |
+
);
|
| 268 |
+
path = "VisionOSWhisperTest";
|
| 269 |
+
sourceTree = "<group>";
|
| 270 |
+
};
|
| 271 |
+
1111111111111111111111AA /* Sources */ = {
|
| 272 |
+
isa = PBXGroup;
|
| 273 |
+
children = (
|
| 274 |
+
22222222222222222222222 /* App.swift */,
|
| 275 |
+
44444444444444444444444 /* ContentView.swift */,
|
| 276 |
+
);
|
| 277 |
+
path = Sources;
|
| 278 |
+
sourceTree = "<group>";
|
| 279 |
+
};
|
| 280 |
+
/* End PBXGroup section */
|
| 281 |
+
EOF
|
| 282 |
+
|
| 283 |
+
# Continue with the project.pbxproj file, using the APP_NAME variable appropriately
|
| 284 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 285 |
+
/* Begin PBXNativeTarget section */
|
| 286 |
+
3333333333333333333333AA /* ${APP_NAME} */ = {
|
| 287 |
+
isa = PBXNativeTarget;
|
| 288 |
+
buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
|
| 289 |
+
buildPhases = (
|
| 290 |
+
5555555555555555555555AA /* Sources */,
|
| 291 |
+
BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
|
| 292 |
+
6666666666666666666666AA /* Resources */,
|
| 293 |
+
88888888888888888888888 /* Embed Frameworks */,
|
| 294 |
+
);
|
| 295 |
+
buildRules = (
|
| 296 |
+
);
|
| 297 |
+
dependencies = (
|
| 298 |
+
);
|
| 299 |
+
name = "${APP_NAME}";
|
| 300 |
+
productName = "${APP_NAME}";
|
| 301 |
+
productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
|
| 302 |
+
productType = "com.apple.product-type.application";
|
| 303 |
+
};
|
| 304 |
+
/* End PBXNativeTarget section */
|
| 305 |
+
|
| 306 |
+
/* Begin PBXProject section */
|
| 307 |
+
7777777777777777777777AA /* Project object */ = {
|
| 308 |
+
isa = PBXProject;
|
| 309 |
+
attributes = {
|
| 310 |
+
LastSwiftUpdateCheck = 1510;
|
| 311 |
+
LastUpgradeCheck = 1510;
|
| 312 |
+
TargetAttributes = {
|
| 313 |
+
3333333333333333333333AA = {
|
| 314 |
+
CreatedOnToolsVersion = 15.1;
|
| 315 |
+
};
|
| 316 |
+
};
|
| 317 |
+
};
|
| 318 |
+
buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
|
| 319 |
+
compatibilityVersion = "Xcode 15.0";
|
| 320 |
+
developmentRegion = en;
|
| 321 |
+
hasScannedForEncodings = 0;
|
| 322 |
+
knownRegions = (
|
| 323 |
+
en,
|
| 324 |
+
Base,
|
| 325 |
+
);
|
| 326 |
+
mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
|
| 327 |
+
productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
|
| 328 |
+
projectDirPath = "";
|
| 329 |
+
projectRoot = "";
|
| 330 |
+
targets = (
|
| 331 |
+
3333333333333333333333AA /* ${APP_NAME} */,
|
| 332 |
+
);
|
| 333 |
+
};
|
| 334 |
+
/* End PBXProject section */
|
| 335 |
+
EOF
|
| 336 |
+
|
| 337 |
+
# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS
|
| 338 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
|
| 339 |
+
/* Begin PBXResourcesBuildPhase section */
|
| 340 |
+
6666666666666666666666AA /* Resources */ = {
|
| 341 |
+
isa = PBXResourcesBuildPhase;
|
| 342 |
+
buildActionMask = 2147483647;
|
| 343 |
+
files = (
|
| 344 |
+
);
|
| 345 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 346 |
+
};
|
| 347 |
+
/* End PBXResourcesBuildPhase section */
|
| 348 |
+
|
| 349 |
+
/* Begin PBXSourcesBuildPhase section */
|
| 350 |
+
5555555555555555555555AA /* Sources */ = {
|
| 351 |
+
isa = PBXSourcesBuildPhase;
|
| 352 |
+
buildActionMask = 2147483647;
|
| 353 |
+
files = (
|
| 354 |
+
33333333333333333333333 /* ContentView.swift in Sources */,
|
| 355 |
+
11111111111111111111111 /* App.swift in Sources */,
|
| 356 |
+
);
|
| 357 |
+
runOnlyForDeploymentPostprocessing = 0;
|
| 358 |
+
};
|
| 359 |
+
/* End PBXSourcesBuildPhase section */
|
| 360 |
+
|
| 361 |
+
/* Begin XCBuildConfiguration section */
|
| 362 |
+
9999999999999999999999AA /* Debug */ = {
|
| 363 |
+
isa = XCBuildConfiguration;
|
| 364 |
+
buildSettings = {
|
| 365 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 366 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 367 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 368 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 369 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 370 |
+
CLANG_ENABLE_MODULES = YES;
|
| 371 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 372 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 373 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 374 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 375 |
+
CLANG_WARN_COMMA = YES;
|
| 376 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 377 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 378 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 379 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 380 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 381 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 382 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 383 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 384 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 385 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 386 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 387 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 388 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 389 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 390 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 391 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 392 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 393 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 394 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 395 |
+
COPY_PHASE_STRIP = NO;
|
| 396 |
+
DEBUG_INFORMATION_FORMAT = dwarf;
|
| 397 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 398 |
+
ENABLE_TESTABILITY = YES;
|
| 399 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 400 |
+
GCC_DYNAMIC_NO_PIC = NO;
|
| 401 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 402 |
+
GCC_OPTIMIZATION_LEVEL = 0;
|
| 403 |
+
GCC_PREPROCESSOR_DEFINITIONS = (
|
| 404 |
+
"DEBUG=1",
|
| 405 |
+
"$(inherited)",
|
| 406 |
+
);
|
| 407 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 408 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 409 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 410 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 411 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 412 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 413 |
+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
| 414 |
+
MTL_FAST_MATH = YES;
|
| 415 |
+
ONLY_ACTIVE_ARCH = YES;
|
| 416 |
+
SDKROOT = xros;
|
| 417 |
+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
| 418 |
+
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
| 419 |
+
XROS_DEPLOYMENT_TARGET = 1.0;
|
| 420 |
+
};
|
| 421 |
+
name = Debug;
|
| 422 |
+
};
|
| 423 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
|
| 424 |
+
isa = XCBuildConfiguration;
|
| 425 |
+
buildSettings = {
|
| 426 |
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
| 427 |
+
CLANG_ANALYZER_NONNULL = YES;
|
| 428 |
+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
| 429 |
+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
| 430 |
+
CLANG_CXX_LIBRARY = "libc++";
|
| 431 |
+
CLANG_ENABLE_MODULES = YES;
|
| 432 |
+
CLANG_ENABLE_OBJC_ARC = YES;
|
| 433 |
+
CLANG_ENABLE_OBJC_WEAK = YES;
|
| 434 |
+
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
| 435 |
+
CLANG_WARN_BOOL_CONVERSION = YES;
|
| 436 |
+
CLANG_WARN_COMMA = YES;
|
| 437 |
+
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
| 438 |
+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
| 439 |
+
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
| 440 |
+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
| 441 |
+
CLANG_WARN_EMPTY_BODY = YES;
|
| 442 |
+
CLANG_WARN_ENUM_CONVERSION = YES;
|
| 443 |
+
CLANG_WARN_INFINITE_RECURSION = YES;
|
| 444 |
+
CLANG_WARN_INT_CONVERSION = YES;
|
| 445 |
+
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
| 446 |
+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
| 447 |
+
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
| 448 |
+
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
| 449 |
+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
| 450 |
+
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
| 451 |
+
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
| 452 |
+
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
| 453 |
+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
| 454 |
+
CLANG_WARN_UNREACHABLE_CODE = YES;
|
| 455 |
+
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
| 456 |
+
COPY_PHASE_STRIP = NO;
|
| 457 |
+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
| 458 |
+
ENABLE_NS_ASSERTIONS = NO;
|
| 459 |
+
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
| 460 |
+
GCC_C_LANGUAGE_STANDARD = gnu11;
|
| 461 |
+
GCC_NO_COMMON_BLOCKS = YES;
|
| 462 |
+
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
| 463 |
+
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
| 464 |
+
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
| 465 |
+
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
| 466 |
+
GCC_WARN_UNUSED_FUNCTION = YES;
|
| 467 |
+
GCC_WARN_UNUSED_VARIABLE = YES;
|
| 468 |
+
MTL_ENABLE_DEBUG_INFO = NO;
|
| 469 |
+
MTL_FAST_MATH = YES;
|
| 470 |
+
SDKROOT = xros;
|
| 471 |
+
SWIFT_COMPILATION_MODE = wholemodule;
|
| 472 |
+
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
| 473 |
+
VALIDATE_PRODUCT = YES;
|
| 474 |
+
XROS_DEPLOYMENT_TARGET = 1.0;
|
| 475 |
+
};
|
| 476 |
+
name = Release;
|
| 477 |
+
};
|
| 478 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
|
| 479 |
+
isa = XCBuildConfiguration;
|
| 480 |
+
buildSettings = {
|
| 481 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 482 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 483 |
+
CODE_SIGN_STYLE = Manual;
|
| 484 |
+
DEVELOPMENT_TEAM = "";
|
| 485 |
+
ENABLE_PREVIEWS = YES;
|
| 486 |
+
FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
|
| 487 |
+
INFOPLIST_FILE = "VisionOSWhisperTest/Info.plist";
|
| 488 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 489 |
+
"$(inherited)",
|
| 490 |
+
"@executable_path/Frameworks",
|
| 491 |
+
);
|
| 492 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.VisionOSWhisperTest";
|
| 493 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 494 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 495 |
+
SUPPORTED_PLATFORMS = "xros xrsimulator";
|
| 496 |
+
SWIFT_VERSION = 5.0;
|
| 497 |
+
TARGETED_DEVICE_FAMILY = "1,2,7";
|
| 498 |
+
};
|
| 499 |
+
name = Debug;
|
| 500 |
+
};
|
| 501 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
|
| 502 |
+
isa = XCBuildConfiguration;
|
| 503 |
+
buildSettings = {
|
| 504 |
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
| 505 |
+
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
| 506 |
+
CODE_SIGN_STYLE = Manual;
|
| 507 |
+
DEVELOPMENT_TEAM = "";
|
| 508 |
+
ENABLE_PREVIEWS = YES;
|
| 509 |
+
FRAMEWORK_SEARCH_PATHS = (
|
| 510 |
+
"$(inherited)",
|
| 511 |
+
"$(PROJECT_DIR)",
|
| 512 |
+
);
|
| 513 |
+
INFOPLIST_FILE = "VisionOSWhisperTest/Info.plist";
|
| 514 |
+
LD_RUNPATH_SEARCH_PATHS = (
|
| 515 |
+
"$(inherited)",
|
| 516 |
+
"@executable_path/Frameworks",
|
| 517 |
+
);
|
| 518 |
+
PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.VisionOSWhisperTest";
|
| 519 |
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
| 520 |
+
PROVISIONING_PROFILE_SPECIFIER = "";
|
| 521 |
+
SUPPORTED_PLATFORMS = "xros xrsimulator";
|
| 522 |
+
SWIFT_VERSION = 5.0;
|
| 523 |
+
TARGETED_DEVICE_FAMILY = "1,2,7";
|
| 524 |
+
};
|
| 525 |
+
name = Release;
|
| 526 |
+
};
|
| 527 |
+
/* End XCBuildConfiguration section */
|
| 528 |
+
EOF
|
| 529 |
+
|
| 530 |
+
# Finish the project.pbxproj file
|
| 531 |
+
cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
|
| 532 |
+
/* Begin XCConfigurationList section */
|
| 533 |
+
8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
|
| 534 |
+
isa = XCConfigurationList;
|
| 535 |
+
buildConfigurations = (
|
| 536 |
+
9999999999999999999999AA /* Debug */,
|
| 537 |
+
AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
|
| 538 |
+
);
|
| 539 |
+
defaultConfigurationIsVisible = 0;
|
| 540 |
+
defaultConfigurationName = Release;
|
| 541 |
+
};
|
| 542 |
+
4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
|
| 543 |
+
isa = XCConfigurationList;
|
| 544 |
+
buildConfigurations = (
|
| 545 |
+
BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
|
| 546 |
+
CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
|
| 547 |
+
);
|
| 548 |
+
defaultConfigurationIsVisible = 0;
|
| 549 |
+
defaultConfigurationName = Release;
|
| 550 |
+
};
|
| 551 |
+
/* End XCConfigurationList section */
|
| 552 |
+
};
|
| 553 |
+
rootObject = 7777777777777777777777AA /* Project object */;
|
| 554 |
+
}
|
| 555 |
+
EOF
|
| 556 |
+
|
| 557 |
+
# 2. Copy XCFramework to test project
|
| 558 |
+
echo "Copying XCFramework to test project..."
|
| 559 |
+
cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
|
| 560 |
+
|
| 561 |
+
# 3. Build and archive the app
|
| 562 |
+
echo "Building and archiving test app..."
|
| 563 |
+
cd "${TEMP_DIR}/${APP_NAME}"
|
| 564 |
+
|
| 565 |
+
# Create a simple xcscheme file to avoid xcodebuild scheme issues
|
| 566 |
+
mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
|
| 567 |
+
cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
|
| 568 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
| 569 |
+
<Scheme
|
| 570 |
+
LastUpgradeVersion = "1510"
|
| 571 |
+
version = "1.3">
|
| 572 |
+
<BuildAction
|
| 573 |
+
parallelizeBuildables = "YES"
|
| 574 |
+
buildImplicitDependencies = "YES">
|
| 575 |
+
<BuildActionEntries>
|
| 576 |
+
<BuildActionEntry
|
| 577 |
+
buildForTesting = "YES"
|
| 578 |
+
buildForRunning = "YES"
|
| 579 |
+
buildForProfiling = "YES"
|
| 580 |
+
buildForArchiving = "YES"
|
| 581 |
+
buildForAnalyzing = "YES">
|
| 582 |
+
<BuildableReference
|
| 583 |
+
BuildableIdentifier = "primary"
|
| 584 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 585 |
+
BuildableName = "${APP_NAME}.app"
|
| 586 |
+
BlueprintName = "${APP_NAME}"
|
| 587 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 588 |
+
</BuildableReference>
|
| 589 |
+
</BuildActionEntry>
|
| 590 |
+
</BuildActionEntries>
|
| 591 |
+
</BuildAction>
|
| 592 |
+
<TestAction
|
| 593 |
+
buildConfiguration = "Debug"
|
| 594 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 595 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 596 |
+
shouldUseLaunchSchemeArgsEnv = "YES">
|
| 597 |
+
<Testables>
|
| 598 |
+
</Testables>
|
| 599 |
+
</TestAction>
|
| 600 |
+
<LaunchAction
|
| 601 |
+
buildConfiguration = "Debug"
|
| 602 |
+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
| 603 |
+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
| 604 |
+
launchStyle = "0"
|
| 605 |
+
useCustomWorkingDirectory = "NO"
|
| 606 |
+
ignoresPersistentStateOnLaunch = "NO"
|
| 607 |
+
debugDocumentVersioning = "YES"
|
| 608 |
+
debugServiceExtension = "internal"
|
| 609 |
+
allowLocationSimulation = "YES">
|
| 610 |
+
<BuildableProductRunnable
|
| 611 |
+
runnableDebuggingMode = "0">
|
| 612 |
+
<BuildableReference
|
| 613 |
+
BuildableIdentifier = "primary"
|
| 614 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 615 |
+
BuildableName = "${APP_NAME}.app"
|
| 616 |
+
BlueprintName = "${APP_NAME}"
|
| 617 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 618 |
+
</BuildableReference>
|
| 619 |
+
</BuildableProductRunnable>
|
| 620 |
+
</LaunchAction>
|
| 621 |
+
<ProfileAction
|
| 622 |
+
buildConfiguration = "Release"
|
| 623 |
+
shouldUseLaunchSchemeArgsEnv = "YES"
|
| 624 |
+
savedToolIdentifier = ""
|
| 625 |
+
useCustomWorkingDirectory = "NO"
|
| 626 |
+
debugDocumentVersioning = "YES">
|
| 627 |
+
<BuildableProductRunnable
|
| 628 |
+
runnableDebuggingMode = "0">
|
| 629 |
+
<BuildableReference
|
| 630 |
+
BuildableIdentifier = "primary"
|
| 631 |
+
BlueprintIdentifier = "3333333333333333333333AA"
|
| 632 |
+
BuildableName = "${APP_NAME}.app"
|
| 633 |
+
BlueprintName = "${APP_NAME}"
|
| 634 |
+
ReferencedContainer = "container:${APP_NAME}.xcodeproj">
|
| 635 |
+
</BuildableReference>
|
| 636 |
+
</BuildableProductRunnable>
|
| 637 |
+
</ProfileAction>
|
| 638 |
+
<AnalyzeAction
|
| 639 |
+
buildConfiguration = "Debug">
|
| 640 |
+
</AnalyzeAction>
|
| 641 |
+
<ArchiveAction
|
| 642 |
+
buildConfiguration = "Release"
|
| 643 |
+
revealArchiveInOrganizer = "YES">
|
| 644 |
+
</ArchiveAction>
|
| 645 |
+
</Scheme>
|
| 646 |
+
EOF
|
| 647 |
+
|
| 648 |
+
# Now use xcodebuild with an explicitly defined product name for visionOS
|
| 649 |
+
xcodebuild -project "${APP_NAME}.xcodeproj" -scheme "${APP_NAME}" -sdk xros -configuration Release archive -archivePath "${ARCHIVE_PATH}" CODE_SIGN_IDENTITY="-" CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO PRODUCT_NAME="${APP_NAME}" SWIFT_OPTIMIZATION_LEVEL="-Onone" -quiet
|
| 650 |
+
|
| 651 |
+
# 4. Create IPA from archive
|
| 652 |
+
echo "Creating IPA from archive..."
|
| 653 |
+
mkdir -p "${TEMP_DIR}/Payload"
|
| 654 |
+
cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
|
| 655 |
+
|
| 656 |
+
# Check and log app structure before zipping
|
| 657 |
+
echo "App structure:"
|
| 658 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
|
| 659 |
+
echo "Frameworks:"
|
| 660 |
+
ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 661 |
+
|
| 662 |
+
cd "${TEMP_DIR}"
|
| 663 |
+
zip -r "${IPA_PATH}" Payload
|
| 664 |
+
|
| 665 |
+
# Check embedded provisioning profile
|
| 666 |
+
echo "Checking provisioning profile (if any)..."
|
| 667 |
+
PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
|
| 668 |
+
if [ -n "$PROVISIONING_PROFILE" ]; then
|
| 669 |
+
echo "Found embedded provisioning profile:"
|
| 670 |
+
security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
|
| 671 |
+
else
|
| 672 |
+
echo "No embedded provisioning profile found (expected for ad-hoc builds)"
|
| 673 |
+
fi
|
| 674 |
+
|
| 675 |
+
# 5. Validate the IPA
|
| 676 |
+
echo "Validating IPA..."
|
| 677 |
+
VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
|
| 678 |
+
|
| 679 |
+
# Check if authentication credentials are provided
|
| 680 |
+
AUTH_ARGS=""
|
| 681 |
+
if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
|
| 682 |
+
echo "Using Apple ID authentication for validation..."
|
| 683 |
+
AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
|
| 684 |
+
else
|
| 685 |
+
echo "No authentication credentials provided. Will perform basic validation."
|
| 686 |
+
echo "To use your personal developer account, you can run the script with:"
|
| 687 |
+
echo " APPLE_ID='[email protected]' APPLE_PASSWORD='your-app-specific-password' ./validate-visionos.sh"
|
| 688 |
+
echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
|
| 689 |
+
fi
|
| 690 |
+
|
| 691 |
+
# Run validation with detailed output
|
| 692 |
+
echo "Running validation with altool..."
|
| 693 |
+
if [ -n "$AUTH_ARGS" ]; then
|
| 694 |
+
# Use eval to properly handle the quoted arguments
|
| 695 |
+
eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type visionos --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 696 |
+
else
|
| 697 |
+
xcrun altool --validate-app -f "${IPA_PATH}" --type visionos --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
|
| 698 |
+
fi
|
| 699 |
+
VALIDATION_RESULT=$?
|
| 700 |
+
|
| 701 |
+
# Final validation result
|
| 702 |
+
FINAL_VALIDATION_RESULT=0
|
| 703 |
+
|
| 704 |
+
# Check if validation failed because the app isn't in App Store Connect
|
| 705 |
+
if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
|
| 706 |
+
echo "β οΈ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
|
| 707 |
+
echo "This is expected for apps that haven't been registered in App Store Connect yet."
|
| 708 |
+
echo "This doesn't indicate a problem with the build or framework."
|
| 709 |
+
|
| 710 |
+
# Perform alternative validation
|
| 711 |
+
echo "Performing alternative validation checks..."
|
| 712 |
+
|
| 713 |
+
# Check if IPA was created successfully
|
| 714 |
+
if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
|
| 715 |
+
echo "β
IPA file created successfully"
|
| 716 |
+
else
|
| 717 |
+
echo "β IPA file not created or empty"
|
| 718 |
+
FINAL_VALIDATION_RESULT=1
|
| 719 |
+
fi
|
| 720 |
+
|
| 721 |
+
# Check if app binary exists and is executable
|
| 722 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
|
| 723 |
+
echo "β
App binary exists and is executable"
|
| 724 |
+
else
|
| 725 |
+
echo "β App binary missing or not executable"
|
| 726 |
+
FINAL_VALIDATION_RESULT=1
|
| 727 |
+
fi
|
| 728 |
+
|
| 729 |
+
# Check if framework was properly embedded
|
| 730 |
+
if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework" ]; then
|
| 731 |
+
echo "β
whisper.framework properly embedded"
|
| 732 |
+
else
|
| 733 |
+
echo "β whisper.framework not properly embedded"
|
| 734 |
+
FINAL_VALIDATION_RESULT=1
|
| 735 |
+
fi
|
| 736 |
+
|
| 737 |
+
# Check if framework binary exists
|
| 738 |
+
if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework/whisper" ]; then
|
| 739 |
+
echo "β
Framework binary exists"
|
| 740 |
+
|
| 741 |
+
# Further validate framework by checking architecture
|
| 742 |
+
ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/whisper.framework/whisper" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')
|
| 743 |
+
if [ -n "$ARCHS" ]; then
|
| 744 |
+
echo "β
Framework architecture(s): $ARCHS"
|
| 745 |
+
else
|
| 746 |
+
echo "β οΈ Could not determine framework architecture"
|
| 747 |
+
fi
|
| 748 |
+
else
|
| 749 |
+
echo "β Framework binary missing"
|
| 750 |
+
FINAL_VALIDATION_RESULT=1
|
| 751 |
+
fi
|
| 752 |
+
|
| 753 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 754 |
+
echo "β
Alternative validation PASSED: App built successfully with embedded framework"
|
| 755 |
+
else
|
| 756 |
+
echo "β Alternative validation FAILED: Issues found with the app or framework"
|
| 757 |
+
fi
|
| 758 |
+
elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
|
| 759 |
+
echo "β
visionOS Validation PASSED: IPA successfully validated"
|
| 760 |
+
echo "Results saved to ${VALIDATION_OUTPUT}"
|
| 761 |
+
else
|
| 762 |
+
echo "β visionOS Validation FAILED: IPA validation found issues"
|
| 763 |
+
echo "See validation output at ${VALIDATION_OUTPUT}"
|
| 764 |
+
echo ""
|
| 765 |
+
echo "==== VALIDATION ERRORS ===="
|
| 766 |
+
|
| 767 |
+
# Try to extract specific errors from the output
|
| 768 |
+
if grep -q "Error" "${VALIDATION_OUTPUT}"; then
|
| 769 |
+
grep -A 5 "Error" "${VALIDATION_OUTPUT}"
|
| 770 |
+
else
|
| 771 |
+
# If no specific error found, show the whole log
|
| 772 |
+
cat "${VALIDATION_OUTPUT}"
|
| 773 |
+
fi
|
| 774 |
+
|
| 775 |
+
# Additional debugging: check IPA contents
|
| 776 |
+
echo ""
|
| 777 |
+
echo "==== IPA CONTENTS ===="
|
| 778 |
+
mkdir -p "${TEMP_DIR}/ipa_contents"
|
| 779 |
+
unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
|
| 780 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
|
| 781 |
+
|
| 782 |
+
# Check for code signing issues
|
| 783 |
+
echo ""
|
| 784 |
+
echo "==== CODE SIGNING INFO ===="
|
| 785 |
+
codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
|
| 786 |
+
|
| 787 |
+
# Check embedded frameworks
|
| 788 |
+
echo ""
|
| 789 |
+
echo "==== FRAMEWORK INFO ===="
|
| 790 |
+
ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
|
| 791 |
+
fi
|
| 792 |
+
|
| 793 |
+
# Don't clean up on error to allow inspection
|
| 794 |
+
if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
|
| 795 |
+
echo ""
|
| 796 |
+
echo "Temporary files kept for inspection at: ${TEMP_DIR}"
|
| 797 |
+
echo "===== visionOS Validation Process Failed ====="
|
| 798 |
+
exit 1
|
| 799 |
+
fi
|
| 800 |
+
|
| 801 |
+
# Clean up temporary files but keep build artifacts
|
| 802 |
+
if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
|
| 803 |
+
echo "Cleaning up temporary files..."
|
| 804 |
+
#rm -rf "${TEMP_DIR}"
|
| 805 |
+
fi
|
| 806 |
+
|
| 807 |
+
echo "===== visionOS Validation Process Completed ====="
|
| 808 |
+
exit $FINAL_VALIDATION_RESULT
|
spm-headers/ggml-alloc.h
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
../ggml/include/ggml-alloc.h
|
|
|
|
|
|
spm-headers/ggml-backend.h
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
../ggml/include/ggml-backend.h
|
|
|
|
|
|
spm-headers/ggml-cpp.h
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
../ggml/include/ggml-cpp.h
|
|
|
|
|
|
spm-headers/ggml-cpu.h
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
../ggml/include/ggml-cpu.h
|
|
|
|
|
|
spm-headers/ggml-metal.h
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
../ggml/include/ggml-metal.h
|
|
|
|
|
|
spm-headers/ggml.h
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
../ggml/include/ggml.h
|
|
|
|
|
|
spm-headers/whisper.h
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
../include/whisper.h
|
|
|
|
|
|