| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820 |
- #!/usr/bin/env bash
- # validate-ios.sh - Validate iOS Application with embedded llama.xcframework using SwiftUI
- # Authentication options (optional) (can be set via environment variables)
- # To use: export APPLE_ID=your.email@example.com
- # export APPLE_PASSWORD=your-app-specific-password
- # ./validate-ios.sh
- APPLE_ID=${APPLE_ID:-""}
- APPLE_PASSWORD=${APPLE_PASSWORD:-""}
- # Ensure the script exits on error
- set -e
- # Function to print usage instructions
- print_usage() {
- echo "Usage: ./validate-ios.sh [OPTIONS]"
- echo ""
- echo "Options:"
- echo " --help Show this help message"
- echo " --apple-id EMAIL Apple ID email for validation"
- echo " --apple-password PWD App-specific password for Apple ID"
- echo ""
- echo "Environment variables:"
- echo " APPLE_ID Apple ID email for validation"
- echo " APPLE_PASSWORD App-specific password for Apple ID"
- echo ""
- echo "Notes:"
- echo " - Command line options take precedence over environment variables"
- echo " - Authentication is optional. If not provided, alternative validation will be performed"
- echo " - For APPLE_PASSWORD, use an app-specific password generated at https://appleid.apple.com/account/manage"
- }
- # Parse command line arguments
- while [[ $# -gt 0 ]]; do
- case $1 in
- --help)
- print_usage
- exit 0
- ;;
- --apple-id)
- APPLE_ID="$2"
- shift 2
- ;;
- --apple-password)
- APPLE_PASSWORD="$2"
- shift 2
- ;;
- *)
- echo "Unknown option: $1"
- print_usage
- exit 1
- ;;
- esac
- done
- # Function to clean up in case of error
- cleanup() {
- # Don't clean up temp files on error to help with debugging
- echo "===== iOS Validation Process Failed ====="
- exit 1
- }
- # Set up trap to call cleanup function on error
- trap cleanup ERR
- set -e # Exit on any error
- ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
- BUILD_DIR="${ROOT_DIR}/validation-builds/ios"
- # Configuration
- APP_NAME="iOSLlamaTest"
- BUNDLE_ID="org.ggml.iOSLlamaTest"
- XCFRAMEWORK_PATH="${ROOT_DIR}/build-apple/llama.xcframework"
- TEMP_DIR="${BUILD_DIR}/temp"
- ARCHIVE_PATH="${BUILD_DIR}/${APP_NAME}.xcarchive"
- IPA_PATH="${BUILD_DIR}/${APP_NAME}.ipa"
- VALIDATION_DIR="${BUILD_DIR}/validation"
- # Create necessary directories
- mkdir -p "${BUILD_DIR}"
- mkdir -p "${TEMP_DIR}"
- mkdir -p "${VALIDATION_DIR}"
- echo "===== iOS Validation Process Started ====="
- # 1. Create a simple test app project
- echo "Creating test iOS app project..."
- mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}"
- cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Info.plist" << EOF
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
- <plist version="1.0">
- <dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>en</string>
- <key>CFBundleExecutable</key>
- <string>${APP_NAME}</string>
- <key>CFBundleIdentifier</key>
- <string>${BUNDLE_ID}</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>${APP_NAME}</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleShortVersionString</key>
- <string>1.0</string>
- <key>CFBundleVersion</key>
- <string>1</string>
- <key>LSRequiresIPhoneOS</key>
- <true/>
- <key>UILaunchScreen</key>
- <dict/>
- <key>UIRequiredDeviceCapabilities</key>
- <array>
- <string>armv7</string>
- </array>
- <key>UISupportedInterfaceOrientations</key>
- <array>
- <string>UIInterfaceOrientationPortrait</string>
- </array>
- </dict>
- </plist>
- EOF
- # Create SwiftUI app files
- mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources"
- # Create App.swift
- cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/App.swift" << EOF
- import SwiftUI
- import llama
- @main
- struct LlamaTestApp: App {
- var body: some Scene {
- WindowGroup {
- ContentView()
- }
- }
- }
- EOF
- # Create ContentView.swift
- cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}/Sources/ContentView.swift" << EOF
- import SwiftUI
- import llama
- struct ContentView: View {
- // Test that we can initialize a llama context params struct
- let params = llama_context_default_params()
- var body: some View {
- VStack(spacing: 20) {
- Text("Llama Framework Test")
- .font(.largeTitle)
- .padding()
- Text("llama_context_default_params() created successfully")
- .font(.headline)
- .multilineTextAlignment(.center)
- .padding()
- // Display some param values to confirm the framework is working
- Text("n_ctx: \(params.n_ctx)")
- .font(.body)
- Text("n_batch: \(params.n_batch)")
- .font(.body)
- Spacer()
- }
- .padding()
- }
- }
- struct ContentView_Previews: PreviewProvider {
- static var previews: some View {
- ContentView()
- }
- }
- EOF
- # Create project.pbxproj, fixing the framework search paths issues
- mkdir -p "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj"
- cat > "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
- // !$*UTF8*$!
- {
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 54;
- objects = {
- /* Begin PBXBuildFile section */
- 11111111111111111111111 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22222222222222222222222; };
- 33333333333333333333333 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44444444444444444444444; };
- 55555555555555555555555 /* llama.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
- 77777777777777777777777 /* llama.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 66666666666666666666666; };
- /* End PBXBuildFile section */
- /* Begin PBXCopyFilesBuildPhase section */
- 88888888888888888888888 /* Embed Frameworks */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- 77777777777777777777777 /* llama.xcframework in Embed Frameworks */,
- );
- name = "Embed Frameworks";
- runOnlyForDeploymentPostprocessing = 0;
- };
- /* End PBXCopyFilesBuildPhase section */
- /* Begin PBXFileReference section */
- EOF
- # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
- cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
- 99999999999999999999999 /* ${APP_NAME}.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "${APP_NAME}.app"; sourceTree = BUILT_PRODUCTS_DIR; };
- 22222222222222222222222 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
- 44444444444444444444444 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
- AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
- 66666666666666666666666 /* llama.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = llama.xcframework; sourceTree = "<group>"; };
- /* End PBXFileReference section */
- EOF
- # Add the rest of the project file with fixed framework search paths
- cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
- /* Begin PBXFrameworksBuildPhase section */
- BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 55555555555555555555555 /* llama.xcframework in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- /* End PBXFrameworksBuildPhase section */
- /* Begin PBXGroup section */
- EOF
- # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
- cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
- CCCCCCCCCCCCCCCCCCCCCCCC /* Products */ = {
- isa = PBXGroup;
- children = (
- 99999999999999999999999 /* ${APP_NAME}.app */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- EOF
- cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
- DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- 66666666666666666666666 /* llama.xcframework */,
- );
- name = Frameworks;
- sourceTree = "<group>";
- };
- EEEEEEEEEEEEEEEEEEEEEEEE = {
- isa = PBXGroup;
- children = (
- FFFFFFFFFFFFFFFFFFFFFFFF /* iOSLlamaTest */,
- CCCCCCCCCCCCCCCCCCCCCCCC /* Products */,
- DDDDDDDDDDDDDDDDDDDDDDDD /* Frameworks */,
- );
- sourceTree = "<group>";
- };
- FFFFFFFFFFFFFFFFFFFFFFFF /* iOSLlamaTest */ = {
- isa = PBXGroup;
- children = (
- 1111111111111111111111AA /* Sources */,
- AAAAAAAAAAAAAAAAAAAAAAA /* Info.plist */,
- );
- path = "iOSLlamaTest";
- sourceTree = "<group>";
- };
- 1111111111111111111111AA /* Sources */ = {
- isa = PBXGroup;
- children = (
- 22222222222222222222222 /* App.swift */,
- 44444444444444444444444 /* ContentView.swift */,
- );
- path = Sources;
- sourceTree = "<group>";
- };
- /* End PBXGroup section */
- EOF
- # Continue with the project.pbxproj file, using the APP_NAME variable appropriately
- cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
- /* Begin PBXNativeTarget section */
- 3333333333333333333333AA /* ${APP_NAME} */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */;
- buildPhases = (
- 5555555555555555555555AA /* Sources */,
- BBBBBBBBBBBBBBBBBBBBBBBB /* Frameworks */,
- 6666666666666666666666AA /* Resources */,
- 88888888888888888888888 /* Embed Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "${APP_NAME}";
- productName = "${APP_NAME}";
- productReference = 99999999999999999999999 /* ${APP_NAME}.app */;
- productType = "com.apple.product-type.application";
- };
- /* End PBXNativeTarget section */
- /* Begin PBXProject section */
- 7777777777777777777777AA /* Project object */ = {
- isa = PBXProject;
- attributes = {
- LastSwiftUpdateCheck = 1240;
- LastUpgradeCheck = 1240;
- TargetAttributes = {
- 3333333333333333333333AA = {
- CreatedOnToolsVersion = 12.4;
- };
- };
- };
- buildConfigurationList = 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */;
- compatibilityVersion = "Xcode 12.0";
- developmentRegion = en;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = EEEEEEEEEEEEEEEEEEEEEEEE;
- productRefGroup = CCCCCCCCCCCCCCCCCCCCCCCC /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 3333333333333333333333AA /* ${APP_NAME} */,
- );
- };
- /* End PBXProject section */
- EOF
- # Add the rest of the file with correct FRAMEWORK_SEARCH_PATHS
- cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << 'EOF'
- /* Begin PBXResourcesBuildPhase section */
- 6666666666666666666666AA /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- /* End PBXResourcesBuildPhase section */
- /* Begin PBXSourcesBuildPhase section */
- 5555555555555555555555AA /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 33333333333333333333333 /* ContentView.swift in Sources */,
- 11111111111111111111111 /* App.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- /* End PBXSourcesBuildPhase section */
- /* Begin XCBuildConfiguration section */
- 9999999999999999999999AA /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- GCC_C_LANGUAGE_STANDARD = gnu11;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 16.4;
- MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
- MTL_FAST_MATH = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- };
- name = Debug;
- };
- AAAAAAAAAAAAAAAAAAAAABBB /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_ENABLE_OBJC_WEAK = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu11;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 16.4;
- MTL_ENABLE_DEBUG_INFO = NO;
- MTL_FAST_MATH = YES;
- SDKROOT = iphoneos;
- SWIFT_COMPILATION_MODE = wholemodule;
- SWIFT_OPTIMIZATION_LEVEL = "-O";
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
- CODE_SIGN_STYLE = Manual;
- DEVELOPMENT_TEAM = "";
- ENABLE_PREVIEWS = YES;
- FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)";
- INFOPLIST_FILE = "iOSLlamaTest/Info.plist";
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.iOSLlamaTest";
- PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = "";
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Debug;
- };
- CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
- CODE_SIGN_STYLE = Manual;
- DEVELOPMENT_TEAM = "";
- ENABLE_PREVIEWS = YES;
- FRAMEWORK_SEARCH_PATHS = (
- "$(inherited)",
- "$(PROJECT_DIR)",
- );
- INFOPLIST_FILE = "iOSLlamaTest/Info.plist";
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- PRODUCT_BUNDLE_IDENTIFIER = "org.ggml.iOSLlamaTest";
- PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = "";
- SWIFT_VERSION = 5.0;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Release;
- };
- /* End XCBuildConfiguration section */
- EOF
- # Finish the project.pbxproj file
- cat >> "${TEMP_DIR}/${APP_NAME}/${APP_NAME}.xcodeproj/project.pbxproj" << EOF
- /* Begin XCConfigurationList section */
- 8888888888888888888888AA /* Build configuration list for PBXProject "${APP_NAME}" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 9999999999999999999999AA /* Debug */,
- AAAAAAAAAAAAAAAAAAAAABBB /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 4444444444444444444444AA /* Build configuration list for PBXNativeTarget "${APP_NAME}" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- BBBBBBBBBBBBBBBBBBBBBBCCC /* Debug */,
- CCCCCCCCCCCCCCCCCCCCCCDDD /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- /* End XCConfigurationList section */
- };
- rootObject = 7777777777777777777777AA /* Project object */;
- }
- EOF
- # 2. Copy XCFramework to test project
- echo "Copying XCFramework to test project..."
- cp -R "${XCFRAMEWORK_PATH}" "${TEMP_DIR}/${APP_NAME}/"
- # 3. Build and archive the app
- echo "Building and archiving test app..."
- cd "${TEMP_DIR}/${APP_NAME}"
- # Create a simple xcscheme file to avoid xcodebuild scheme issues
- mkdir -p "${APP_NAME}.xcodeproj/xcshareddata/xcschemes"
- cat > "${APP_NAME}.xcodeproj/xcshareddata/xcschemes/${APP_NAME}.xcscheme" << EOF
- <?xml version="1.0" encoding="UTF-8"?>
- <Scheme
- LastUpgradeVersion = "1240"
- version = "1.3">
- <BuildAction
- parallelizeBuildables = "YES"
- buildImplicitDependencies = "YES">
- <BuildActionEntries>
- <BuildActionEntry
- buildForTesting = "YES"
- buildForRunning = "YES"
- buildForProfiling = "YES"
- buildForArchiving = "YES"
- buildForAnalyzing = "YES">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "3333333333333333333333AA"
- BuildableName = "${APP_NAME}.app"
- BlueprintName = "${APP_NAME}"
- ReferencedContainer = "container:${APP_NAME}.xcodeproj">
- </BuildableReference>
- </BuildActionEntry>
- </BuildActionEntries>
- </BuildAction>
- <TestAction
- buildConfiguration = "Debug"
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES">
- <Testables>
- </Testables>
- </TestAction>
- <LaunchAction
- buildConfiguration = "Debug"
- selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
- selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- launchStyle = "0"
- useCustomWorkingDirectory = "NO"
- ignoresPersistentStateOnLaunch = "NO"
- debugDocumentVersioning = "YES"
- debugServiceExtension = "internal"
- allowLocationSimulation = "YES">
- <BuildableProductRunnable
- runnableDebuggingMode = "0">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "3333333333333333333333AA"
- BuildableName = "${APP_NAME}.app"
- BlueprintName = "${APP_NAME}"
- ReferencedContainer = "container:${APP_NAME}.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- </LaunchAction>
- <ProfileAction
- buildConfiguration = "Release"
- shouldUseLaunchSchemeArgsEnv = "YES"
- savedToolIdentifier = ""
- useCustomWorkingDirectory = "NO"
- debugDocumentVersioning = "YES">
- <BuildableProductRunnable
- runnableDebuggingMode = "0">
- <BuildableReference
- BuildableIdentifier = "primary"
- BlueprintIdentifier = "3333333333333333333333AA"
- BuildableName = "${APP_NAME}.app"
- BlueprintName = "${APP_NAME}"
- ReferencedContainer = "container:${APP_NAME}.xcodeproj">
- </BuildableReference>
- </BuildableProductRunnable>
- </ProfileAction>
- <AnalyzeAction
- buildConfiguration = "Debug">
- </AnalyzeAction>
- <ArchiveAction
- buildConfiguration = "Release"
- revealArchiveInOrganizer = "YES">
- </ArchiveAction>
- </Scheme>
- EOF
- # Now use xcodebuild with an explicitly defined product name
- 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
- # 4. Create IPA from archive
- echo "Creating IPA from archive..."
- mkdir -p "${TEMP_DIR}/Payload"
- cp -R "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" "${TEMP_DIR}/Payload/"
- # Check and log app structure before zipping
- echo "App structure:"
- ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/"
- echo "Frameworks:"
- ls -la "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
- cd "${TEMP_DIR}"
- zip -r "${IPA_PATH}" Payload
- # Check embedded provisioning profile
- echo "Checking provisioning profile (if any)..."
- PROVISIONING_PROFILE=$(find "${ARCHIVE_PATH}/Products/Applications/${APP_NAME}.app" -name "embedded.mobileprovision" 2>/dev/null)
- if [ -n "$PROVISIONING_PROFILE" ]; then
- echo "Found embedded provisioning profile:"
- security cms -D -i "$PROVISIONING_PROFILE" || echo "Unable to decode provisioning profile"
- else
- echo "No embedded provisioning profile found (expected for ad-hoc builds)"
- fi
- # 5. Validate the IPA
- echo "Validating IPA..."
- VALIDATION_OUTPUT="${VALIDATION_DIR}/validation_output.txt"
- # Check if authentication credentials are provided
- AUTH_ARGS=""
- if [ -n "$APPLE_ID" ] && [ -n "$APPLE_PASSWORD" ]; then
- echo "Using Apple ID authentication for validation..."
- AUTH_ARGS="--username \"$APPLE_ID\" --password \"$APPLE_PASSWORD\""
- else
- echo "No authentication credentials provided. Will perform basic validation."
- echo "To use your personal developer account, you can run the script with:"
- echo " APPLE_ID='your.email@example.com' APPLE_PASSWORD='your-app-specific-password' ./validate-ios.sh"
- echo "Note: You need to create an app-specific password at https://appleid.apple.com/account/manage"
- fi
- # Run validation with detailed output
- echo "Running validation with altool..."
- if [ -n "$AUTH_ARGS" ]; then
- # Use eval to properly handle the quoted arguments
- eval "xcrun altool --validate-app -f \"${IPA_PATH}\" --type ios --output-format xml $AUTH_ARGS" 2>&1 | tee "${VALIDATION_OUTPUT}"
- else
- xcrun altool --validate-app -f "${IPA_PATH}" --type ios --output-format xml 2>&1 | tee "${VALIDATION_OUTPUT}"
- fi
- VALIDATION_RESULT=$?
- # Final validation result
- FINAL_VALIDATION_RESULT=0
- # Check if validation failed because the app isn't in App Store Connect
- if grep -q "No suitable application records were found" "${VALIDATION_OUTPUT}"; then
- echo "⚠️ App Store Connect Warning: The app bundle identifier is not found in App Store Connect"
- echo "This is expected for apps that haven't been registered in App Store Connect yet."
- echo "This doesn't indicate a problem with the build or framework."
- # Perform alternative validation
- echo "Performing alternative validation checks..."
- # Check if IPA was created successfully
- if [ -f "${IPA_PATH}" ] && [ -s "${IPA_PATH}" ]; then
- echo "✅ IPA file created successfully"
- else
- echo "❌ IPA file not created or empty"
- FINAL_VALIDATION_RESULT=1
- fi
- # Check if app binary exists and is executable
- if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ] && [ -x "${TEMP_DIR}/Payload/${APP_NAME}.app/${APP_NAME}" ]; then
- echo "✅ App binary exists and is executable"
- else
- echo "❌ App binary missing or not executable"
- FINAL_VALIDATION_RESULT=1
- fi
- # Check if framework was properly embedded
- if [ -d "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework" ]; then
- echo "✅ llama.framework properly embedded"
- else
- echo "❌ llama.framework not properly embedded"
- FINAL_VALIDATION_RESULT=1
- fi
- # Check if framework binary exists
- if [ -f "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" ]; then
- echo "✅ Framework binary exists"
- # Further validate framework by checking architecture
- ARCHS=$(lipo -info "${TEMP_DIR}/Payload/${APP_NAME}.app/Frameworks/llama.framework/llama" 2>/dev/null | grep -o "arm64\\|armv7\\|x86_64" | tr '\n' ' ')
- if [ -n "$ARCHS" ]; then
- echo "✅ Framework architecture(s): $ARCHS"
- else
- echo "⚠️ Could not determine framework architecture"
- fi
- else
- echo "❌ Framework binary missing"
- FINAL_VALIDATION_RESULT=1
- fi
- if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
- echo "✅ Alternative validation PASSED: App built successfully with embedded framework"
- else
- echo "❌ Alternative validation FAILED: Issues found with the app or framework"
- fi
- elif grep -q "You must specify authentication credentials" "${VALIDATION_OUTPUT}" && [ -z "$AUTH_ARGS" ]; then
- echo "✅ iOS Validation PASSED: IPA successfully validated"
- echo "Results saved to ${VALIDATION_OUTPUT}"
- else
- echo "❌ iOS Validation FAILED: IPA validation found issues"
- echo "See validation output at ${VALIDATION_OUTPUT}"
- echo ""
- echo "==== VALIDATION ERRORS ===="
- # Try to extract specific errors from the output
- if grep -q "Error" "${VALIDATION_OUTPUT}"; then
- grep -A 5 "Error" "${VALIDATION_OUTPUT}"
- else
- # If no specific error found, show the whole log
- cat "${VALIDATION_OUTPUT}"
- fi
- # Additional debugging: check IPA contents
- echo ""
- echo "==== IPA CONTENTS ===="
- mkdir -p "${TEMP_DIR}/ipa_contents"
- unzip -q "${IPA_PATH}" -d "${TEMP_DIR}/ipa_contents"
- ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/"
- # Check for code signing issues
- echo ""
- echo "==== CODE SIGNING INFO ===="
- codesign -vv -d "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app" 2>&1 || echo "Code signing verification failed"
- # Check embedded frameworks
- echo ""
- echo "==== FRAMEWORK INFO ===="
- ls -la "${TEMP_DIR}/ipa_contents/Payload/${APP_NAME}.app/Frameworks/" 2>/dev/null || echo "No Frameworks directory found"
- fi
- # Don't clean up on error to allow inspection
- if [ $FINAL_VALIDATION_RESULT -ne 0 ]; then
- echo ""
- echo "Temporary files kept for inspection at: ${TEMP_DIR}"
- echo "===== iOS Validation Process Failed ====="
- exit 1
- fi
- # Clean up temporary files but keep build artifacts
- if [ $FINAL_VALIDATION_RESULT -eq 0 ]; then
- echo "Cleaning up temporary files..."
- #rm -rf "${TEMP_DIR}"
- fi
- echo "===== iOS Validation Process Completed ====="
- exit $FINAL_VALIDATION_RESULT
|