validate-visionos.sh 31 KB

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