Felipe97/llama-cpp-compiled
01.2k
1#!/usr/bin/env bash2# validate-tvos.sh - Validate tvOS Application with embedded llama.xcframework using SwiftUI3 4# Authentication options (optional) (can be set via environment variables)5# To use: export APPLE_ID=your.email@example.com6# export APPLE_PASSWORD=your-app-specific-password7# ./validate-tvos.sh8APPLE_ID=${APPLE_ID:-""}9APPLE_PASSWORD=${APPLE_PASSWORD:-""}10 11# Ensure the script exits on error12set -e13 14# Function to print usage instructions15print_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 arguments34while [[ $# -gt 0 ]]; do35 case $1 in36 --help)37 print_usage38 exit 039 ;;40 --apple-id)41 APPLE_ID="$2"42 shift 243 ;;44 --apple-password)45 APPLE_PASSWORD="$2"46 shift 247 ;;48 *)49 echo "Unknown option: $1"50 print_usage51 exit 152 ;;53 esac54done55 56# Function to clean up in case of error57cleanup() {58 # Don't clean up temp files on error to help with debugging59 echo "===== tvOS Validation Process Failed ====="60 exit 161}62 63# Set up trap to call cleanup function on error64trap cleanup ERR65 66set -e # Exit on any error67 68ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"69BUILD_DIR="${ROOT_DIR}/validation-builds/ios"70 71# Configuration72APP_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 directories81mkdir -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 project88echo "Creating test tvOS app project..."89mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"90cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF91<?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>117EOF118 119# Create SwiftUI app files120mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"121 122# Create App.swift123cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF124import SwiftUI125import llama126 127@main128struct LlamaTestApp: App {129 var body: some Scene {130 WindowGroup {131 ContentView()132 }133 }134}135EOF136 137# Create ContentView.swift with tvOS specific elements138cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF139import SwiftUI140import llama141 142struct ContentView: View {143 // Test that we can initialize a llama context params struct144 let params = llama_context_default_params()145 146 var body: some View {147 VStack(spacing: 40) {148 Text("Llama Framework Test on tvOS")149 .font(.largeTitle)150 .padding()151 152 Text("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 working158 Text("n_ctx: \(params.n_ctx)")159 .font(.title2)160 161 Text("n_batch: \(params.n_batch)")162 .font(.title2)163 164 Spacer()165 }166 .padding(50)167 // Larger size suitable for TV display168 }169}170 171struct ContentView_Previews: PreviewProvider {172 static var previews: some View {173 ContentView()174 }175}176EOF177 178# Create project.pbxproj, fixing the framework search paths issues179mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"180cat > "${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 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };193 77777777777777777777777 /* llama.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 /* llama.xcframework in Embed Frameworks */,204 );205 name = "Embed Frameworks";206 runOnlyForDeploymentPostprocessing = 0;207 };208/* End PBXCopyFilesBuildPhase section */209 210/* Begin PBXFileReference section */211EOF212 213# Continue with the project.pbxproj file, using the APP_NAME variable appropriately214cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF215 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 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };220/* End PBXFileReference section */221EOF222 223# Add the rest of the project file with fixed framework search paths224cat >> "${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 /* llama.xcframework in Frameworks */,231 );232 runOnlyForDeploymentPostprocessing = 0;233 };234/* End PBXFrameworksBuildPhase section */235 236/* Begin PBXGroup section */237EOF238 239# Continue with the project.pbxproj file, using the APP_NAME variable appropriately240cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF241 CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {242 isa = PBXGroup;243 children = (244 99999999999999999999999 /* ${APP_NAME}.app */,245 );246 name = Products;247 sourceTree = "<group>";248 };249EOF250 251cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'252 DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {253 isa = PBXGroup;254 children = (255 66666666666666666666666 /* llama.xcframework */,256 );257 name = Frameworks;258 sourceTree = "<group>";259 };260 EEEEEEEEEEEEEEEEEEEEEEEE = {261 isa = PBXGroup;262 children = (263 FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSLlamaTest */,264 CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,265 DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,266 );267 sourceTree = "<group>";268 };269 FFFFFFFFFFFFFFFFFFFFFFFF /* TVOSLlamaTest */ = {270 isa = PBXGroup;271 children = (272 1111111111111111111111AA /* Sources */,273 AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,274 );275 path = "TVOSLlamaTest";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 */288EOF289 290# Continue with the project.pbxproj file, using the APP_NAME variable appropriately291cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF292/* 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 */342EOF343 344# Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS and tvOS settings345cat >> "${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 TVOS_DEPLOYMENT_TARGET = 15.0;421 MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;422 MTL_FAST_MATH = YES;423 ONLY_ACTIVE_ARCH = YES;424 SDKROOT = appletvos;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 TVOS_DEPLOYMENT_TARGET = 15.0;476 MTL_ENABLE_DEBUG_INFO = NO;477 MTL_FAST_MATH = YES;478 SDKROOT = appletvos;479 SWIFT_COMPILATION_MODE = wholemodule;480 SWIFT_OPTIMIZATION_LEVEL = "-O";481 VALIDATE_PRODUCT = YES;482 };483 name = Release;484 };485 BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {486 isa = XCBuildConfiguration;487 buildSettings = {488 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;489 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;490 CODE_SIGN_STYLE = Manual;491 DEVELOPMENT_TEAM = "";492 ENABLE_PREVIEWS = YES;493 FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";494 INFOPLIST_FILE = "TVOSLlamaTest/Info.plist";495 LD_RUNPATH_SEARCH_PATHS = (496 "$(inherited)",497 "@executable_path/Frameworks",498 );499 PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSLlamaTest";500 PRODUCT_NAME = "$(TARGET_NAME)";501 PROVISIONING_PROFILE_SPECIFIER = "";502 SWIFT_VERSION = 5.0;503 TARGETED_DEVICE_FAMILY = 3;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 DEVELOPMENT_TEAM = "";514 ENABLE_PREVIEWS = YES;515 FRAMEWORK_SEARCH_PATHS = (516 "$(inherited)",517 "$(PROJECT_DIR)",518 );519 INFOPLIST_FILE = "TVOSLlamaTest/Info.plist";520 LD_RUNPATH_SEARCH_PATHS = (521 "$(inherited)",522 "@executable_path/Frameworks",523 );524 PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.TVOSLlamaTest";525 PRODUCT_NAME = "$(TARGET_NAME)";526 PROVISIONING_PROFILE_SPECIFIER = "";527 SWIFT_VERSION = 5.0;528 TARGETED_DEVICE_FAMILY = 3;529 };530 name = Release;531 };532/* End XCBuildConfiguration section */533EOF534 535# Finish the project.pbxproj file536cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF537/* Begin XCConfigurationList section */538 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {539 isa = XCConfigurationList;540 buildConfigurations = (541 9999999999999999999999AA /* Debug */,542 AAAAAAAAAAAAAAAAAAAAABBB /* Release */,543 );544 defaultConfigurationIsVisible = 0;545 defaultConfigurationName = Release;546 };547 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {548 isa = XCConfigurationList;549 buildConfigurations = (550 BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,551 CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,552 );553 defaultConfigurationIsVisible = 0;554 defaultConfigurationName = Release;555 };556/* End XCConfigurationList section */557 };558 rootObject = 7777777777777777777777AA /* Project object */;559}560EOF561 562# 2. Copy XCFramework to test project563echo "Copying XCFramework to test project..."564cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"565 566# 3. Build and archive the app567echo "Building and archiving test app..."568cd "${TEMP_DIR}/${APP_NAME}"569 570# Create a simple xcscheme file to avoid xcodebuild scheme issues571mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"572cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF573<?xml version="1.0" encoding="UTF-8"?>574<Scheme575 LastUpgradeVersion = "1240"576 version = "1.3">577 <BuildAction578 parallelizeBuildables = "YES"579 buildImplicitDependencies = "YES">580 <BuildActionEntries>581 <BuildActionEntry582 buildForTesting = "YES"583 buildForRunning = "YES"584 buildForProfiling = "YES"585 buildForArchiving = "YES"586 buildForAnalyzing = "YES">587 <BuildableReference588 BuildableIdentifier = "primary"589 BlueprintIdentifier = "3333333333333333333333AA"590 BuildableName = "${APP_NAME}.app"591 BlueprintName = "${APP_NAME}"592 ReferencedContainer = "container:${APP_NAME}.xcodeproj">593 </BuildableReference>594 </BuildActionEntry>595 </BuildActionEntries>596 </BuildAction>597 <TestAction598 buildConfiguration = "Debug"599 selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"600 selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"601 shouldUseLaunchSchemeArgsEnv = "YES">602 <Testables>603 </Testables>604 </TestAction>605 <LaunchAction606 buildConfiguration = "Debug"607 selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"608 selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"609 launchStyle = "0"610 useCustomWorkingDirectory = "NO"611 ignoresPersistentStateOnLaunch = "NO"612 debugDocumentVersioning = "YES"613 debugServiceExtension = "internal"614 allowLocationSimulation = "YES">615 <BuildableProductRunnable616 runnableDebuggingMode = "0">617 <BuildableReference618 BuildableIdentifier = "primary"619 BlueprintIdentifier = "3333333333333333333333AA"620 BuildableName = "${APP_NAME}.app"621 BlueprintName = "${APP_NAME}"622 ReferencedContainer = "container:${APP_NAME}.xcodeproj">623 </BuildableReference>624 </BuildableProductRunnable>625 </LaunchAction>626 <ProfileAction627 buildConfiguration = "Release"628 shouldUseLaunchSchemeArgsEnv = "YES"629 savedToolIdentifier = ""630 useCustomWorkingDirectory = "NO"631 debugDocumentVersioning = "YES">632 <BuildableProductRunnable633 runnableDebuggingMode = "0">634 <BuildableReference635 BuildableIdentifier = "primary"636 BlueprintIdentifier = "3333333333333333333333AA"637 BuildableName = "${APP_NAME}.app"638 BlueprintName = "${APP_NAME}"639 ReferencedContainer = "container:${APP_NAME}.xcodeproj">640 </BuildableReference>641 </BuildableProductRunnable>642 </ProfileAction>643 <AnalyzeAction644 buildConfiguration = "Debug">645 </AnalyzeAction>646 <ArchiveAction647 buildConfiguration = "Release"648 revealArchiveInOrganizer = "YES">649 </ArchiveAction>650</Scheme>651EOF652 653# Now use xcodebuild with an explicitly defined product name for tvOS654xcodebuild -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" -quiet655 656# 4. Create IPA from archive657echo "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 zipping662echo "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}" Payload669 670# Check embedded provisioning profile671echo "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" ]; then674 echo "Found embedded provisioning profile:"675 security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"676else677 echo "No embedded provisioning profile found (expected for ad-hoc builds)"678fi679 680# 5. Validate the IPA681echo "Validating IPA..."682VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"683 684# Check if authentication credentials are provided685AUTH_ARGS=""686if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then687 echo "Using Apple ID authentication for validation..."688 AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""689else690 echo "No authentication credentials provided. Will perform basic validation."691 echo "To use your personal developer account, you can run the script with:"692 echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-tvos.sh"693 echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"694fi695 696# Run validation with detailed output697echo "Running validation with altool..."698if [ -n "$AUTH_ARGS" ]; then699 # Use eval to properly handle the quoted arguments700 eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type tvos --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"701else702 xcrun altool --validate-app -f "${IPA_PATH}" --type tvos --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"703fi704VALIDATION_RESULT=$?705 706# Final validation result707FINAL_VALIDATION_RESULT=0708 709# Check if validation failed because the app isn't in App Store Connect710if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then711 echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"712 echo "This is expected for apps that haven't been registered in App Store Connect yet."713 echo "This doesn't indicate a problem with the build or framework."714 715 # Perform alternative validation716 echo "Performing alternative validation checks..."717 718 # Check if IPA was created successfully719 if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then720 echo "✅ IPA file created successfully"721 else722 echo "❌ IPA file not created or empty"723 FINAL_VALIDATION_RESULT=1724 fi725 726 # Check if app binary exists and is executable727 if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then728 echo "✅ App binary exists and is executable"729 else730 echo "❌ App binary missing or not executable"731 FINAL_VALIDATION_RESULT=1732 fi733 734 # Check if framework was properly embedded735 if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework" ]; then736 echo "✅ llama.framework properly embedded"737 else738 echo "❌ llama.framework not properly embedded"739 FINAL_VALIDATION_RESULT=1740 fi741 742 # Check if framework binary exists743 if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" ]; then744 echo "✅ Framework binary exists"745 746 # Further validate framework by checking architecture747 ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" 2>/dev/null | grep -o "arm64\\|x86_64" | tr '\n' ' ')748 if [ -n "$ARCHS" ]; then749 echo "✅ Framework architecture(s): $ARCHS"750 else751 echo "⚠️ Could not determine framework architecture"752 fi753 else754 echo "❌ Framework binary missing"755 FINAL_VALIDATION_RESULT=1756 fi757 758 if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then759 echo "✅ Alternative validation PASSED: App built successfully with embedded framework"760 else761 echo "❌ Alternative validation FAILED: Issues found with the app or framework"762 fi763elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then764 echo "✅ tvOS Validation PASSED: IPA successfully validated"765 echo "Results saved to ${VALIDATION_OUTPUT}"766else767 echo "❌ tvOS Validation FAILED: IPA validation found issues"768 echo "See validation output at ${VALIDATION_OUTPUT}"769 echo ""770 echo "==== VALIDATION ERRORS ===="771 772 # Try to extract specific errors from the output773 if grep -q "Error" "${VALIDATION_OUTPUT}"; then774 grep -A 5 "Error" "${VALIDATION_OUTPUT}"775 else776 # If no specific error found, show the whole log777 cat "${VALIDATION_OUTPUT}"778 fi779 780 # Additional debugging: check IPA contents781 echo ""782 echo "==== IPA CONTENTS ===="783 mkdir -p "${TEMP_DIR}/ipa_contents"784 unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"785 ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"786 787 # Check for code signing issues788 echo ""789 echo "==== CODE SIGNING INFO ===="790 codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"791 792 # Check embedded frameworks793 echo ""794 echo "==== FRAMEWORK INFO ===="795 ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"796fi797 798# Don't clean up on error to allow inspection799if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then800 echo ""801 echo "Temporary files kept for inspection at: ${TEMP_DIR}"802 echo "===== tvOS Validation Process Failed ====="803 exit 1804fi805 806# Clean up temporary files but keep build artifacts807if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then808 echo "Cleaning up temporary files..."809 #rm -rf "${TEMP_DIR}"810fi811 812echo "===== tvOS Validation Process Completed ====="813exit $FINAL_VALIDATION_RESULT814 