char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
e9b6350e6
char/aliceai-t5-moe
1#!/usr/bin/env bash 2# validate-tvos.sh - Validate tvOS Application with embedded llama.xcframework using SwiftUI 3 4# Authentication options (optional) (can be set via environment variables) 5# To use: export APPLE_ID=your.email@example.com 6# export APPLE_PASSWORD=your-app-specific-password 7# ./validate-tvos.sh 8APPLE_ID =${ APPLE_ID :- "" } 9APPLE_PASSWORD =${ APPLE_PASSWORD :- "" } 10 11# Ensure the script exits on error 12set -e 13 14# Function to print usage instructions 15print_usage () { 16echo "Usage: ./validate-tvos.sh [OPTIONS]" 17echo "" 18echo "Options:" 19echo " --help Show this help message" 20echo " --apple-id EMAIL Apple ID email for validation" 21echo " --apple-password PWD App-specific password for Apple ID" 22echo "" 23echo "Environment variables:" 24echo " APPLE_ID Apple ID email for validation" 25echo " APPLE_PASSWORD App-specific password for Apple ID" 26echo "" 27echo "Notes:" 28echo " - Command line options take precedence over environment variables" 29echo " - Authentication is optional. If not provided, alternative validation will be performed" 30echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage" 31} 32 33# Parse command line arguments 34while [[$ # -gt 0 ]];do 35case $ 1 in 36 --help) 37print_usage 38exit 0 39 ;; 40 --apple-id) 41APPLE_ID =" $ 2 " 42shift 2 43 ;; 44 --apple-password) 45APPLE_PASSWORD =" $ 2 " 46shift 2 47 ;; 48 *) 49echo "Unknown option: $ 1 " 50print_usage 51exit 1 52 ;; 53esac 54done 55 56# Function to clean up in case of error 57cleanup () { 58# Don't clean up temp files on error to help with debugging 59echo "===== tvOS Validation Process Failed =====" 60exit 1 61} 62 63# Set up trap to call cleanup function on error 64trap cleanup ERR 65 66set -e # Exit on any error 67 68ROOT_DIR =" $( cd " $( dirname " ${ BASH_SOURCE [0]} " ) /../.." && pwd ) " 69BUILD_DIR =" ${ ROOT_DIR } /validation-builds/ios" 70 71# Configuration 72APP_NAME ="TVOSLlamaTest" 73BUNDLE_ID ="org.ggml.TVOSLlamaTest" 74XCFRAMEWORK_PATH =" ${ ROOT_DIR } /build-apple/llama.xcframework" 75TEMP_DIR =" ${ BUILD_DIR } /temp" 76ARCHIVE_PATH =" ${ BUILD_DIR } / ${ APP_NAME } .xcarchive" 77IPA_PATH =" ${ BUILD_DIR } / ${ APP_NAME } .ipa" 78VALIDATION_DIR =" ${ BUILD_DIR } /validation" 79 80# Create necessary directories 81mkdir -p " ${ BUILD_DIR } " 82mkdir -p " ${ TEMP_DIR } " 83mkdir -p " ${ VALIDATION_DIR } " 84 85echo "===== tvOS Validation Process Started =====" 86 87# 1. Create a simple test app project 88echo "Creating test tvOS app project..." 89mkdir -p " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } " 90cat > " ${ 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> 117EOF 118 119# Create SwiftUI app files 120mkdir -p " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } /Sources" 121 122# Create App.swift 123cat > " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } /Sources/App.swift" <<EOF 124import SwiftUI 125import llama 126 127@main 128struct LlamaTestApp: App { 129var body: some Scene { 130WindowGroup { 131ContentView() 132} 133} 134} 135EOF 136 137# Create ContentView.swift with tvOS specific elements 138cat > " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } /Sources/ContentView.swift" <<EOF 139import SwiftUI 140import llama 141 142struct ContentView: View { 143// Test that we can initialize a llama context params struct 144let params = llama_context_default_params() 145 146var body: some View { 147VStack(spacing: 40) { 148Text("Llama Framework Test on tvOS") 149.font(.largeTitle) 150.padding() 151 152Text("llama_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 158Text("n_ctx: \(params.n_ctx)") 159.font(.title2) 160 161Text("n_batch: \(params.n_batch)") 162.font(.title2) 163 164Spacer() 165} 166.padding(50) 167// Larger size suitable for TV display 168} 169} 170 171struct ContentView_Previews: PreviewProvider { 172static var previews: some View { 173ContentView() 174} 175} 176EOF 177 178# Create project.pbxproj, fixing the framework search paths issues 179mkdir -p " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj" 180cat > " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj/project.pbxproj" <<'EOF' 181// !$*UTF8*$! 182{ 183archiveVersion = 1; 184classes = { 185}; 186objectVersion = 54; 187objects = { 188 189/* Begin PBXBuildFile section */ 19011111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; }; 19133333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; }; 19255555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; }; 19377777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; }; 194/* End PBXBuildFile section */ 195 196/* Begin PBXCopyFilesBuildPhase section */ 19788888888888888888888888 /* Embed Frameworks */ = { 198isa = PBXCopyFilesBuildPhase; 199buildActionMask = 2147483647; 200dstPath = ""; 201dstSubfolderSpec = 10; 202files = ( 20377777777777777777777777 /* llama.xcframework in Embed Frameworks */, 204); 205name = "Embed Frameworks"; 206runOnlyForDeploymentPostprocessing = 0; 207}; 208/* End PBXCopyFilesBuildPhase section */ 209 210/* Begin PBXFileReference section */ 211EOF 212 213# Continue with the project.pbxproj file, using the APP_NAME variable appropriately 214cat >> " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj/project.pbxproj" <<EOF 21599999999999999999999999 /* ${ APP_NAME } .app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = " ${ APP_NAME } .app"; sourceTree = BUILT_PRODUCTS_DIR; }; 21622222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; }; 21744444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; }; 218AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 21966666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; }; 220/* End PBXFileReference section */ 221EOF 222 223# Add the rest of the project file with fixed framework search paths 224cat >> " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj/project.pbxproj" <<'EOF' 225/* Begin PBXFrameworksBuildPhase section */ 226BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = { 227isa = PBXFrameworksBuildPhase; 228buildActionMask = 2147483647; 229files = ( 23055555555555555555555555 /* llama.xcframework in Frameworks */, 231); 232runOnlyForDeploymentPostprocessing = 0; 233}; 234/* End PBXFrameworksBuildPhase section */ 235 236/* Begin PBXGroup section */ 237EOF 238 239# Continue with the project.pbxproj file, using the APP_NAME variable appropriately 240cat >> " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj/project.pbxproj" <<EOF 241CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = { 242isa = PBXGroup; 243children = ( 24499999999999999999999999 /* ${ APP_NAME } .app */, 245); 246name = Products; 247sourceTree = "<group>"; 248}; 249EOF 250 251cat >> " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj/project.pbxproj" <<'EOF' 252DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = { 253isa = PBXGroup; 254children = ( 25566666666666666666666666 /* llama.xcframework */, 256); 257name = Frameworks; 258sourceTree = "<group>"; 259}; 260EEEEEEEEEEEEEEEEEEEEEEEE = { 261isa = PBXGroup; 262children = ( 263FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSLlamaTest */, 264CCCCCCCCCCCCCCCCCCCCCCCC /* Products */, 265DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */, 266); 267sourceTree = "<group>"; 268}; 269FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSLlamaTest */ = { 270isa = PBXGroup; 271children = ( 2721111111111111111111111AA /* Sources */, 273AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */, 274); 275path = "TVOSLlamaTest"; 276sourceTree = "<group>"; 277}; 2781111111111111111111111AA /* Sources */ = { 279isa = PBXGroup; 280children = ( 28122222222222222222222222 /* App.swift */, 28244444444444444444444444 /* ContentView.swift */, 283); 284path = Sources; 285sourceTree = "<group>"; 286}; 287/* End PBXGroup section */ 288EOF 289 290# Continue with the project.pbxproj file, using the APP_NAME variable appropriately 291cat >> " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj/project.pbxproj" <<EOF 292/* Begin PBXNativeTarget section */ 2933333333333333333333333AA /* ${ APP_NAME } */ = { 294isa = PBXNativeTarget; 295buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget " ${ APP_NAME } " */; 296buildPhases = ( 2975555555555555555555555AA /* Sources */, 298BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */, 2996666666666666666666666AA /* Resources */, 30088888888888888888888888 /* Embed Frameworks */, 301); 302buildRules = ( 303); 304dependencies = ( 305); 306name = " ${ APP_NAME } "; 307productName = " ${ APP_NAME } "; 308productReference = 99999999999999999999999 /* ${ APP_NAME } .app */; 309productType = "com.apple.product-type.application"; 310}; 311/* End PBXNativeTarget section */ 312 313/* Begin PBXProject section */ 3147777777777777777777777AA /* Project object */ = { 315isa = PBXProject; 316attributes = { 317LastSwiftUpdateCheck = 1240; 318LastUpgradeCheck = 1240; 319TargetAttributes = { 3203333333333333333333333AA = { 321CreatedOnToolsVersion = 12.4; 322}; 323}; 324}; 325buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject " ${ APP_NAME } " */; 326compatibilityVersion = "Xcode 12.0"; 327developmentRegion = en; 328hasScannedForEncodings = 0; 329knownRegions = ( 330en, 331Base, 332); 333mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE; 334productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */; 335projectDirPath = ""; 336projectRoot = ""; 337targets = ( 3383333333333333333333333AA /* ${ APP_NAME } */, 339); 340}; 341/* End PBXProject section */ 342EOF 343 344# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS and tvOS settings 345cat >> " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj/project.pbxproj" <<'EOF' 346/* Begin PBXResourcesBuildPhase section */ 3476666666666666666666666AA /* Resources */ = { 348isa = PBXResourcesBuildPhase; 349buildActionMask = 2147483647; 350files = ( 351); 352runOnlyForDeploymentPostprocessing = 0; 353}; 354/* End PBXResourcesBuildPhase section */ 355 356/* Begin PBXSourcesBuildPhase section */ 3575555555555555555555555AA /* Sources */ = { 358isa = PBXSourcesBuildPhase; 359buildActionMask = 2147483647; 360files = ( 36133333333333333333333333 /* ContentView.swift in Sources */, 36211111111111111111111111 /* App.swift in Sources */, 363); 364runOnlyForDeploymentPostprocessing = 0; 365}; 366/* End PBXSourcesBuildPhase section */ 367 368/* Begin XCBuildConfiguration section */ 3699999999999999999999999AA /* Debug */ = { 370isa = XCBuildConfiguration; 371buildSettings = { 372ALWAYS_SEARCH_USER_PATHS = NO; 373CLANG_ANALYZER_NONNULL = YES; 374CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 375CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 376CLANG_CXX_LIBRARY = "libc++"; 377CLANG_ENABLE_MODULES = YES; 378CLANG_ENABLE_OBJC_ARC = YES; 379CLANG_ENABLE_OBJC_WEAK = YES; 380CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 381CLANG_WARN_BOOL_CONVERSION = YES; 382CLANG_WARN_COMMA = YES; 383CLANG_WARN_CONSTANT_CONVERSION = YES; 384CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 385CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 386CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 387CLANG_WARN_EMPTY_BODY = YES; 388CLANG_WARN_ENUM_CONVERSION = YES; 389CLANG_WARN_INFINITE_RECURSION = YES; 390CLANG_WARN_INT_CONVERSION = YES; 391CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 392CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 393CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 394CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 395CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 396CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 397CLANG_WARN_STRICT_PROTOTYPES = YES; 398CLANG_WARN_SUSPICIOUS_MOVE = YES; 399CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 400CLANG_WARN_UNREACHABLE_CODE = YES; 401CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 402COPY_PHASE_STRIP = NO; 403DEBUG_INFORMATION_FORMAT = dwarf; 404ENABLE_STRICT_OBJC_MSGSEND = YES; 405ENABLE_TESTABILITY = YES; 406GCC_C_LANGUAGE_STANDARD = gnu11; 407GCC_DYNAMIC_NO_PIC = NO; 408GCC_NO_COMMON_BLOCKS = YES; 409GCC_OPTIMIZATION_LEVEL = 0; 410GCC_PREPROCESSOR_DEFINITIONS = ( 411"DEBUG=1", 412"$(inherited)", 413); 414GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 415GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 416GCC_WARN_UNDECLARED_SELECTOR = YES; 417GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 418GCC_WARN_UNUSED_FUNCTION = YES; 419GCC_WARN_UNUSED_VARIABLE = YES; 420TVOS_DEPLOYMENT_TARGET = 15.0; 421MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 422MTL_FAST_MATH = YES; 423ONLY_ACTIVE_ARCH = YES; 424SDKROOT = appletvos; 425SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 426SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 427}; 428name = Debug; 429}; 430AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = { 431isa = XCBuildConfiguration; 432buildSettings = { 433ALWAYS_SEARCH_USER_PATHS = NO; 434CLANG_ANALYZER_NONNULL = YES; 435CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 436CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 437CLANG_CXX_LIBRARY = "libc++"; 438CLANG_ENABLE_MODULES = YES; 439CLANG_ENABLE_OBJC_ARC = YES; 440CLANG_ENABLE_OBJC_WEAK = YES; 441CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 442CLANG_WARN_BOOL_CONVERSION = YES; 443CLANG_WARN_COMMA = YES; 444CLANG_WARN_CONSTANT_CONVERSION = YES; 445CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 446CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 447CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 448CLANG_WARN_EMPTY_BODY = YES; 449CLANG_WARN_ENUM_CONVERSION = YES; 450CLANG_WARN_INFINITE_RECURSION = YES; 451CLANG_WARN_INT_CONVERSION = YES; 452CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 453CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 454CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 455CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 456CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 457CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 458CLANG_WARN_STRICT_PROTOTYPES = YES; 459CLANG_WARN_SUSPICIOUS_MOVE = YES; 460CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 461CLANG_WARN_UNREACHABLE_CODE = YES; 462CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 463COPY_PHASE_STRIP = NO; 464DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 465ENABLE_NS_ASSERTIONS = NO; 466ENABLE_STRICT_OBJC_MSGSEND = YES; 467GCC_C_LANGUAGE_STANDARD = gnu11; 468GCC_NO_COMMON_BLOCKS = YES; 469GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 470GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 471GCC_WARN_UNDECLARED_SELECTOR = YES; 472GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 473GCC_WARN_UNUSED_FUNCTION = YES; 474GCC_WARN_UNUSED_VARIABLE = YES; 475TVOS_DEPLOYMENT_TARGET = 15.0; 476MTL_ENABLE_DEBUG_INFO = NO; 477MTL_FAST_MATH = YES; 478SDKROOT = appletvos; 479SWIFT_COMPILATION_MODE = wholemodule; 480SWIFT_OPTIMIZATION_LEVEL = "-O"; 481VALIDATE_PRODUCT = YES; 482}; 483name = Release; 484}; 485BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = { 486isa = XCBuildConfiguration; 487buildSettings = { 488ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 489ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 490CODE_SIGN_STYLE = Manual; 491DEVELOPMENT_TEAM = ""; 492ENABLE_PREVIEWS = YES; 493FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)"; 494INFOPLIST_FILE = "TVOSLlamaTest/Info.plist"; 495LD_RUNPATH_SEARCH_PATHS = ( 496"$(inherited)", 497"@executable_path/Frameworks", 498); 499PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSLlamaTest"; 500PRODUCT_NAME = "$(TARGET_NAME)"; 501PROVISIONING_PROFILE_SPECIFIER = ""; 502SWIFT_VERSION = 5.0; 503TARGETED_DEVICE_FAMILY = 3; 504}; 505name = Debug; 506}; 507CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = { 508isa = XCBuildConfiguration; 509buildSettings = { 510ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 511ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 512CODE_SIGN_STYLE = Manual; 513DEVELOPMENT_TEAM = ""; 514ENABLE_PREVIEWS = YES; 515FRAMEWORK_SEARCH_PATHS = ( 516"$(inherited)", 517"$(PROJECT_DIR)", 518); 519INFOPLIST_FILE = "TVOSLlamaTest/Info.plist"; 520LD_RUNPATH_SEARCH_PATHS = ( 521"$(inherited)", 522"@executable_path/Frameworks", 523); 524PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSLlamaTest"; 525PRODUCT_NAME = "$(TARGET_NAME)"; 526PROVISIONING_PROFILE_SPECIFIER = ""; 527SWIFT_VERSION = 5.0; 528TARGETED_DEVICE_FAMILY = 3; 529}; 530name = Release; 531}; 532/* End XCBuildConfiguration section */ 533EOF 534 535# Finish the project.pbxproj file 536cat >> " ${ TEMP_DIR } / ${ APP_NAME } / ${ APP_NAME } .xcodeproj/project.pbxproj" <<EOF 537/* Begin XCConfigurationList section */ 5388888888888888888888888AA /* Build configuration list for PBXProject " ${ APP_NAME } " */ = { 539isa = XCConfigurationList; 540buildConfigurations = ( 5419999999999999999999999AA /* Debug */, 542AAAAAAAAAAAAAAAAAAAAABBB /* Release */, 543); 544defaultConfigurationIsVisible = 0; 545defaultConfigurationName = Release; 546}; 5474444444444444444444444AA /* Build configuration list for PBXNativeTarget " ${ APP_NAME } " */ = { 548isa = XCConfigurationList; 549buildConfigurations = ( 550BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */, 551CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */, 552); 553defaultConfigurationIsVisible = 0; 554defaultConfigurationName = Release; 555}; 556/* End XCConfigurationList section */ 557}; 558rootObject = 7777777777777777777777AA /* Project object */; 559} 560EOF 561 562# 2. Copy XCFramework to test project 563echo "Copying XCFramework to test project..." 564cp -R " ${ XCFRAMEWORK_PATH } " " ${ TEMP_DIR } / ${ APP_NAME } /" 565 566# 3. Build and archive the app 567echo "Building and archiving test app..." 568cd " ${ TEMP_DIR } / ${ APP_NAME } " 569 570# Create a simple xcscheme file to avoid xcodebuild scheme issues 571mkdir -p " ${ APP_NAME } .xcodeproj/xcshareddata/xcschemes" 572cat > " ${ APP_NAME } .xcodeproj/xcshareddata/xcschemes/ ${ APP_NAME } .xcscheme" <<EOF 573<?xml version="1.0" encoding="UTF-8"?> 574<Scheme 575LastUpgradeVersion = "1240" 576version = "1.3"> 577<BuildAction 578parallelizeBuildables = "YES" 579buildImplicitDependencies = "YES"> 580<BuildActionEntries> 581<BuildActionEntry 582buildForTesting = "YES" 583buildForRunning = "YES" 584buildForProfiling = "YES" 585buildForArchiving = "YES" 586buildForAnalyzing = "YES"> 587<BuildableReference 588BuildableIdentifier = "primary" 589BlueprintIdentifier = "3333333333333333333333AA" 590BuildableName = " ${ APP_NAME } .app" 591BlueprintName = " ${ APP_NAME } " 592ReferencedContainer = "container: ${ APP_NAME } .xcodeproj"> 593</BuildableReference> 594</BuildActionEntry> 595</BuildActionEntries> 596</BuildAction> 597<TestAction 598buildConfiguration = "Debug" 599selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" 600selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" 601shouldUseLaunchSchemeArgsEnv = "YES"> 602<Testables> 603</Testables> 604</TestAction> 605<LaunchAction 606buildConfiguration = "Debug" 607selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" 608selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" 609launchStyle = "0" 610useCustomWorkingDirectory = "NO" 611ignoresPersistentStateOnLaunch = "NO" 612debugDocumentVersioning = "YES" 613debugServiceExtension = "internal" 614allowLocationSimulation = "YES"> 615<BuildableProductRunnable 616runnableDebuggingMode = "0"> 617<BuildableReference 618BuildableIdentifier = "primary" 619BlueprintIdentifier = "3333333333333333333333AA" 620BuildableName = " ${ APP_NAME } .app" 621BlueprintName = " ${ APP_NAME } " 622ReferencedContainer = "container: ${ APP_NAME } .xcodeproj"> 623</BuildableReference> 624</BuildableProductRunnable> 625</LaunchAction> 626<ProfileAction 627buildConfiguration = "Release" 628shouldUseLaunchSchemeArgsEnv = "YES" 629savedToolIdentifier = "" 630useCustomWorkingDirectory = "NO" 631debugDocumentVersioning = "YES"> 632<BuildableProductRunnable 633runnableDebuggingMode = "0"> 634<BuildableReference 635BuildableIdentifier = "primary" 636BlueprintIdentifier = "3333333333333333333333AA" 637BuildableName = " ${ APP_NAME } .app" 638BlueprintName = " ${ APP_NAME } " 639ReferencedContainer = "container: ${ APP_NAME } .xcodeproj"> 640</BuildableReference> 641</BuildableProductRunnable> 642</ProfileAction> 643<AnalyzeAction 644buildConfiguration = "Debug"> 645</AnalyzeAction> 646<ArchiveAction 647buildConfiguration = "Release" 648revealArchiveInOrganizer = "YES"> 649</ArchiveAction> 650</Scheme> 651EOF 652 653# Now use xcodebuild with an explicitly defined product name for tvOS 654xcodebuild -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 655 656# 4. Create IPA from archive 657echo "Creating IPA from archive..." 658mkdir -p " ${ TEMP_DIR } /Payload" 659cp -R " ${ ARCHIVE_PATH } /Products/Applications/ ${ APP_NAME } .app" " ${ TEMP_DIR } /Payload/" 660 661# Check and log app structure before zipping 662echo "App structure:" 663ls -la " ${ TEMP_DIR } /Payload/ ${ APP_NAME } .app/" 664echo "Frameworks:" 665ls -la " ${ TEMP_DIR } /Payload/ ${ APP_NAME } .app/Frameworks/" 2 > /dev/null ||echo "No Frameworks directory found" 666 667cd " ${ TEMP_DIR } " 668zip -r " ${ IPA_PATH } " Payload 669 670# Check embedded provisioning profile 671echo "Checking provisioning profile (if any)..." 672PROVISIONING_PROFILE =$( find " ${ ARCHIVE_PATH } /Products/Applications/ ${ APP_NAME } .app" -name "embedded.mobileprovision" 2 > /dev/null) 673if [ -n" $ PROVISIONING_PROFILE " ];then 674echo "Found embedded provisioning profile:" 675security cms-D -i " $ PROVISIONING_PROFILE " ||echo "Unable to decode provisioning profile" 676else 677echo "No embedded provisioning profile found (expected for ad-hoc builds)" 678fi 679 680# 5. Validate the IPA 681echo "Validating IPA..." 682VALIDATION_OUTPUT =" ${ VALIDATION_DIR } /validation_output.txt" 683 684# Check if authentication credentials are provided 685AUTH_ARGS ="" 686if [ -n" $ APPLE_ID " ]&& [ -n" $ APPLE_PASSWORD " ];then 687echo "Using Apple ID authentication for validation..." 688AUTH_ARGS ="--username \" $ APPLE_ID \" --password \" $ APPLE_PASSWORD \"" 689else 690echo "No authentication credentials provided. Will perform basic validation." 691echo "To use your personal developer account, you can run the script with:" 692echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-tvos.sh" 693echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage" 694fi 695 696# Run validation with detailed output 697echo "Running validation with altool..." 698if [ -n" $ AUTH_ARGS " ];then 699# Use eval to properly handle the quoted arguments 700eval "xcrun altool --validate-app -f \" ${ IPA_PATH } \" --type tvos --output-format xml $ AUTH_ARGS " 2 >&1| tee " ${ VALIDATION_OUTPUT } " 701else 702xcrun altool--validate-app -f " ${ IPA_PATH } " --type tvos--output-format xml2 >&1| tee " ${ VALIDATION_OUTPUT } " 703fi 704VALIDATION_RESULT =$ ? 705 706# Final validation result 707FINAL_VALIDATION_RESULT =0 708 709# Check if validation failed because the app isn't in App Store Connect 710if grep -q "No suitable application records were found" " ${ VALIDATION_OUTPUT } " ;then 711echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect" 712echo "This is expected for apps that haven't been registered in App Store Connect yet." 713echo "This doesn't indicate a problem with the build or framework." 714 715# Perform alternative validation 716echo "Performing alternative validation checks..." 717 718# Check if IPA was created successfully 719if [ -f" ${ IPA_PATH } " ]&& [ -s" ${ IPA_PATH } " ];then 720echo "✅ IPA file created successfully" 721else 722echo "❌ IPA file not created or empty" 723FINAL_VALIDATION_RESULT =1 724fi 725 726# Check if app binary exists and is executable 727if [ -f" ${ TEMP_DIR } /Payload/ ${ APP_NAME } .app/ ${ APP_NAME } " ]&& [ -x" ${ TEMP_DIR } /Payload/ ${ APP_NAME } .app/ ${ APP_NAME } " ];then 728echo "✅ App binary exists and is executable" 729else 730echo "❌ App binary missing or not executable" 731FINAL_VALIDATION_RESULT =1 732fi 733 734# Check if framework was properly embedded 735if [ -d" ${ TEMP_DIR } /Payload/ ${ APP_NAME } .app/Frameworks/llama.framework" ];then 736echo "✅ llama.framework properly embedded" 737else 738echo "❌ llama.framework not properly embedded" 739FINAL_VALIDATION_RESULT =1 740fi 741 742# Check if framework binary exists 743if [ -f" ${ TEMP_DIR } /Payload/ ${ APP_NAME } .app/Frameworks/llama.framework/llama" ];then 744echo "✅ Framework binary exists" 745 746# Further validate framework by checking architecture 747ARCHS =$( lipo -info " ${ TEMP_DIR } /Payload/ ${ APP_NAME } .app/Frameworks/llama.framework/llama" 2 > /dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ' ) 748if [ -n" $ ARCHS " ];then 749echo "✅ Framework architecture(s): $ ARCHS " 750else 751echo "⚠️ Could not determine framework architecture" 752fi 753else 754echo "❌ Framework binary missing" 755FINAL_VALIDATION_RESULT =1 756fi 757 758if [$ FINAL_VALIDATION_RESULT -eq 0 ];then 759echo "✅ Alternative validation PASSED: App built successfully with embedded framework" 760else 761echo "❌ Alternative validation FAILED: Issues found with the app or framework" 762fi 763elif grep -q "You must specify authentication credentials" " ${ VALIDATION_OUTPUT } " && [ -z" $ AUTH_ARGS " ];then 764echo "✅ tvOS Validation PASSED: IPA successfully validated" 765echo "Results saved to ${ VALIDATION_OUTPUT } " 766else 767echo "❌ tvOS Validation FAILED: IPA validation found issues" 768echo "See validation output at ${ VALIDATION_OUTPUT } " 769echo "" 770echo "==== VALIDATION ERRORS ====" 771 772# Try to extract specific errors from the output 773if grep -q "Error" " ${ VALIDATION_OUTPUT } " ;then 774grep -A 5"Error" " ${ VALIDATION_OUTPUT } " 775else 776# If no specific error found, show the whole log 777cat " ${ VALIDATION_OUTPUT } " 778fi 779 780# Additional debugging: check IPA contents 781echo "" 782echo "==== IPA CONTENTS ====" 783mkdir -p " ${ TEMP_DIR } /ipa_contents" 784unzip -q " ${ IPA_PATH } " -d " ${ TEMP_DIR } /ipa_contents" 785ls -la " ${ TEMP_DIR } /ipa_contents/Payload/ ${ APP_NAME } .app/" 786 787# Check for code signing issues 788echo "" 789echo "==== CODE SIGNING INFO ====" 790codesign -vv -d " ${ TEMP_DIR } /ipa_contents/Payload/ ${ APP_NAME } .app" 2 >&1 ||echo "Code signing verification failed" 791 792# Check embedded frameworks 793echo "" 794echo "==== FRAMEWORK INFO ====" 795ls -la " ${ TEMP_DIR } /ipa_contents/Payload/ ${ APP_NAME } .app/Frameworks/" 2 > /dev/null ||echo "No Frameworks directory found" 796fi 797 798# Don't clean up on error to allow inspection 799if [$ FINAL_VALIDATION_RESULT -ne 0 ];then 800echo "" 801echo "Temporary files kept for inspection at: ${ TEMP_DIR } " 802echo "===== tvOS Validation Process Failed =====" 803exit 1 804fi 805 806# Clean up temporary files but keep build artifacts 807if [$ FINAL_VALIDATION_RESULT -eq 0 ];then 808echo "Cleaning up temporary files..." 809#rm -rf "${TEMP_DIR}" 810fi 811 812echo "===== tvOS Validation Process Completed =====" 813exit $ FINAL_VALIDATION_RESULT