build-xcframework.sh 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. #!/bin/bash
  2. #
  3. # Options
  4. IOS_MIN_OS_VERSION=16.4
  5. MACOS_MIN_OS_VERSION=13.3
  6. VISIONOS_MIN_OS_VERSION=1.0
  7. TVOS_MIN_OS_VERSION=16.4
  8. BUILD_SHARED_LIBS=OFF
  9. LLAMA_BUILD_EXAMPLES=OFF
  10. LLAMA_BUILD_TESTS=OFF
  11. LLAMA_BUILD_SERVER=OFF
  12. GGML_METAL=ON
  13. GGML_METAL_EMBED_LIBRARY=ON
  14. GGML_BLAS_DEFAULT=ON
  15. GGML_METAL_USE_BF16=ON
  16. GGML_OPENMP=OFF
  17. COMMON_C_FLAGS="-Wno-macro-redefined -Wno-shorten-64-to-32 -Wno-unused-command-line-argument -g"
  18. COMMON_CXX_FLAGS="-Wno-macro-redefined -Wno-shorten-64-to-32 -Wno-unused-command-line-argument -g"
  19. # Common options for all builds
  20. COMMON_CMAKE_ARGS=(
  21. -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED=NO
  22. -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY=""
  23. -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED=NO
  24. -DCMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT="dwarf-with-dsym"
  25. -DCMAKE_XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS=YES
  26. -DCMAKE_XCODE_ATTRIBUTE_COPY_PHASE_STRIP=NO
  27. -DCMAKE_XCODE_ATTRIBUTE_STRIP_INSTALLED_PRODUCT=NO
  28. -DCMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM=ggml
  29. -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
  30. -DLLAMA_BUILD_EXAMPLES=${LLAMA_BUILD_EXAMPLES}
  31. -DLLAMA_BUILD_TESTS=${LLAMA_BUILD_TESTS}
  32. -DLLAMA_BUILD_SERVER=${LLAMA_BUILD_SERVER}
  33. -DGGML_METAL_EMBED_LIBRARY=${GGML_METAL_EMBED_LIBRARY}
  34. -DGGML_BLAS_DEFAULT=${GGML_BLAS_DEFAULT}
  35. -DGGML_METAL=${GGML_METAL}
  36. -DGGML_METAL_USE_BF16=${GGML_METAL_USE_BF16}
  37. -DGGML_NATIVE=OFF
  38. -DGGML_OPENMP=${GGML_OPENMP}
  39. )
  40. check_required_tool() {
  41. local tool=$1
  42. local install_message=$2
  43. if ! command -v $tool &> /dev/null; then
  44. echo "Error: $tool is required but not found."
  45. echo "$install_message"
  46. exit 1
  47. fi
  48. }
  49. echo "Checking for required tools..."
  50. check_required_tool "cmake" "Please install CMake 3.28.0 or later (brew install cmake)"
  51. check_required_tool "xcodebuild" "Please install Xcode and Xcode Command Line Tools (xcode-select --install)"
  52. check_required_tool "libtool" "Please install libtool which should be available with Xcode Command Line Tools (CLT). Make sure Xcode CLT is installed (xcode-select --install)"
  53. check_required_tool "dsymutil" "Please install Xcode and Xcode Command Line Tools (xcode-select --install)"
  54. set -e
  55. ## Clean up previous builds
  56. rm -rf build-apple
  57. rm -rf build-ios-sim
  58. rm -rf build-ios-device
  59. rm -rf build-macos
  60. rm -rf build-visionos
  61. rm -rf build-visionos-sim
  62. rm -rf build-tvos-sim
  63. rm -rf build-tvos-device
  64. # Setup the xcframework build directory structure
  65. setup_framework_structure() {
  66. local build_dir=$1
  67. local min_os_version=$2
  68. local platform=$3 # "ios", "macos", "visionos", or "tvos"
  69. local framework_name="llama"
  70. echo "Creating ${platform}-style framework structure for ${build_dir}"
  71. if [[ "$platform" == "macos" ]]; then
  72. # macOS versioned structure uses versioned directories
  73. mkdir -p ${build_dir}/framework/${framework_name}.framework/Versions/A/Headers
  74. mkdir -p ${build_dir}/framework/${framework_name}.framework/Versions/A/Modules
  75. mkdir -p ${build_dir}/framework/${framework_name}.framework/Versions/A/Resources
  76. # Create symbolic links
  77. ln -sf A ${build_dir}/framework/${framework_name}.framework/Versions/Current
  78. ln -sf Versions/Current/Headers ${build_dir}/framework/${framework_name}.framework/Headers
  79. ln -sf Versions/Current/Modules ${build_dir}/framework/${framework_name}.framework/Modules
  80. ln -sf Versions/Current/Resources ${build_dir}/framework/${framework_name}.framework/Resources
  81. ln -sf Versions/Current/${framework_name} ${build_dir}/framework/${framework_name}.framework/${framework_name}
  82. # Set header and module paths
  83. local header_path=${build_dir}/framework/${framework_name}.framework/Versions/A/Headers/
  84. local module_path=${build_dir}/framework/${framework_name}.framework/Versions/A/Modules/
  85. else
  86. # iOS/VisionOS/tvOS use a flat structure
  87. mkdir -p ${build_dir}/framework/${framework_name}.framework/Headers
  88. mkdir -p ${build_dir}/framework/${framework_name}.framework/Modules
  89. # Remove any existing structure to ensure clean build
  90. rm -rf ${build_dir}/framework/${framework_name}.framework/Versions
  91. # Set header and module paths
  92. local header_path=${build_dir}/framework/${framework_name}.framework/Headers/
  93. local module_path=${build_dir}/framework/${framework_name}.framework/Modules/
  94. fi
  95. # Copy all required headers (common for all platforms)
  96. cp include/llama.h ${header_path}
  97. cp ggml/include/ggml.h ${header_path}
  98. cp ggml/include/ggml-alloc.h ${header_path}
  99. cp ggml/include/ggml-backend.h ${header_path}
  100. cp ggml/include/ggml-metal.h ${header_path}
  101. cp ggml/include/ggml-cpu.h ${header_path}
  102. cp ggml/include/ggml-blas.h ${header_path}
  103. cp ggml/include/gguf.h ${header_path}
  104. # Create module map (common for all platforms)
  105. cat > ${module_path}module.modulemap << EOF
  106. framework module llama {
  107. header "llama.h"
  108. header "ggml.h"
  109. header "ggml-alloc.h"
  110. header "ggml-backend.h"
  111. header "ggml-metal.h"
  112. header "ggml-cpu.h"
  113. header "ggml-blas.h"
  114. header "gguf.h"
  115. link "c++"
  116. link framework "Accelerate"
  117. link framework "Metal"
  118. link framework "Foundation"
  119. export *
  120. }
  121. EOF
  122. # Platform-specific settings for Info.plist
  123. local platform_name=""
  124. local sdk_name=""
  125. local supported_platform=""
  126. case "$platform" in
  127. "ios")
  128. platform_name="iphoneos"
  129. sdk_name="iphoneos${min_os_version}"
  130. supported_platform="iPhoneOS"
  131. local plist_path="${build_dir}/framework/${framework_name}.framework/Info.plist"
  132. local device_family=' <key>UIDeviceFamily</key>
  133. <array>
  134. <integer>1</integer>
  135. <integer>2</integer>
  136. </array>'
  137. ;;
  138. "macos")
  139. platform_name="macosx"
  140. sdk_name="macosx${min_os_version}"
  141. supported_platform="MacOSX"
  142. local plist_path="${build_dir}/framework/${framework_name}.framework/Versions/A/Resources/Info.plist"
  143. local device_family=""
  144. ;;
  145. "visionos")
  146. platform_name="xros"
  147. sdk_name="xros${min_os_version}"
  148. supported_platform="XRPlatform"
  149. local plist_path="${build_dir}/framework/${framework_name}.framework/Info.plist"
  150. local device_family=""
  151. ;;
  152. "tvos")
  153. platform_name="appletvos"
  154. sdk_name="appletvos${min_os_version}"
  155. supported_platform="AppleTVOS"
  156. local plist_path="${build_dir}/framework/${framework_name}.framework/Info.plist"
  157. local device_family=' <key>UIDeviceFamily</key>
  158. <array>
  159. <integer>3</integer>
  160. </array>'
  161. ;;
  162. esac
  163. # Create Info.plist
  164. cat > ${plist_path} << EOF
  165. <?xml version="1.0" encoding="UTF-8"?>
  166. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  167. <plist version="1.0">
  168. <dict>
  169. <key>CFBundleDevelopmentRegion</key>
  170. <string>en</string>
  171. <key>CFBundleExecutable</key>
  172. <string>llama</string>
  173. <key>CFBundleIdentifier</key>
  174. <string>org.ggml.llama</string>
  175. <key>CFBundleInfoDictionaryVersion</key>
  176. <string>6.0</string>
  177. <key>CFBundleName</key>
  178. <string>llama</string>
  179. <key>CFBundlePackageType</key>
  180. <string>FMWK</string>
  181. <key>CFBundleShortVersionString</key>
  182. <string>1.0</string>
  183. <key>CFBundleVersion</key>
  184. <string>1</string>
  185. <key>MinimumOSVersion</key>
  186. <string>${min_os_version}</string>
  187. <key>CFBundleSupportedPlatforms</key>
  188. <array>
  189. <string>${supported_platform}</string>
  190. </array>${device_family}
  191. <key>DTPlatformName</key>
  192. <string>${platform_name}</string>
  193. <key>DTSDKName</key>
  194. <string>${sdk_name}</string>
  195. </dict>
  196. </plist>
  197. EOF
  198. }
  199. # Create dynamic libraries from static libraries.
  200. combine_static_libraries() {
  201. local build_dir="$1"
  202. local release_dir="$2"
  203. local platform="$3" # "ios", "macos", "visionos", or "tvos"
  204. local is_simulator="$4"
  205. local base_dir="$(pwd)"
  206. local framework_name="llama"
  207. # Determine output path based on platform
  208. local output_lib=""
  209. if [[ "$platform" == "macos" ]]; then
  210. # macOS uses versioned structure
  211. output_lib="${build_dir}/framework/${framework_name}.framework/Versions/A/${framework_name}"
  212. else
  213. # iOS, visionOS, and tvOS use a directory flat structure
  214. output_lib="${build_dir}/framework/${framework_name}.framework/${framework_name}"
  215. fi
  216. local libs=(
  217. "${base_dir}/${build_dir}/src/${release_dir}/libllama.a"
  218. "${base_dir}/${build_dir}/ggml/src/${release_dir}/libggml.a"
  219. "${base_dir}/${build_dir}/ggml/src/${release_dir}/libggml-base.a"
  220. "${base_dir}/${build_dir}/ggml/src/${release_dir}/libggml-cpu.a"
  221. "${base_dir}/${build_dir}/ggml/src/ggml-metal/${release_dir}/libggml-metal.a"
  222. "${base_dir}/${build_dir}/ggml/src/ggml-blas/${release_dir}/libggml-blas.a"
  223. )
  224. # Create temporary directory for processing
  225. local temp_dir="${base_dir}/${build_dir}/temp"
  226. mkdir -p "${temp_dir}"
  227. # Since we have multiple architectures libtool will find object files that do not
  228. # match the target architecture. We suppress these warnings.
  229. libtool -static -o "${temp_dir}/combined.a" "${libs[@]}" 2> /dev/null
  230. # Determine SDK, architectures, and install_name based on platform and simulator flag.
  231. local sdk=""
  232. local archs=""
  233. local min_version_flag=""
  234. local install_name=""
  235. case "$platform" in
  236. "ios")
  237. if [[ "$is_simulator" == "true" ]]; then
  238. sdk="iphonesimulator"
  239. archs="arm64 x86_64"
  240. min_version_flag="-mios-simulator-version-min=${IOS_MIN_OS_VERSION}"
  241. else
  242. sdk="iphoneos"
  243. archs="arm64"
  244. min_version_flag="-mios-version-min=${IOS_MIN_OS_VERSION}"
  245. fi
  246. install_name="@rpath/llama.framework/llama"
  247. ;;
  248. "macos")
  249. sdk="macosx"
  250. archs="arm64 x86_64"
  251. min_version_flag="-mmacosx-version-min=${MACOS_MIN_OS_VERSION}"
  252. install_name="@rpath/llama.framework/Versions/Current/llama"
  253. ;;
  254. "visionos")
  255. if [[ "$is_simulator" == "true" ]]; then
  256. sdk="xrsimulator"
  257. archs="arm64 x86_64"
  258. min_version_flag="-mtargetos=xros${VISIONOS_MIN_OS_VERSION}-simulator"
  259. else
  260. sdk="xros"
  261. archs="arm64"
  262. min_version_flag="-mtargetos=xros${VISIONOS_MIN_OS_VERSION}"
  263. fi
  264. # Use flat structure for visionOS, same as iOS
  265. install_name="@rpath/llama.framework/llama"
  266. ;;
  267. "tvos")
  268. if [[ "$is_simulator" == "true" ]]; then
  269. sdk="appletvsimulator"
  270. archs="arm64 x86_64"
  271. min_version_flag="-mtvos-simulator-version-min=${TVOS_MIN_OS_VERSION}"
  272. else
  273. sdk="appletvos"
  274. archs="arm64"
  275. min_version_flag="-mtvos-version-min=${TVOS_MIN_OS_VERSION}"
  276. fi
  277. install_name="@rpath/llama.framework/llama"
  278. ;;
  279. esac
  280. # Build architecture flags
  281. local arch_flags=""
  282. for arch in $archs; do
  283. arch_flags+=" -arch $arch"
  284. done
  285. # Create dynamic library
  286. echo "Creating dynamic library for ${platform}."
  287. xcrun -sdk $sdk clang++ -dynamiclib \
  288. -isysroot $(xcrun --sdk $sdk --show-sdk-path) \
  289. $arch_flags \
  290. $min_version_flag \
  291. -Wl,-force_load,"${temp_dir}/combined.a" \
  292. -framework Foundation -framework Metal -framework Accelerate \
  293. -install_name "$install_name" \
  294. -o "${base_dir}/${output_lib}"
  295. # Platform-specific post-processing for device builds
  296. if [[ "$is_simulator" == "false" ]]; then
  297. if command -v vtool &>/dev/null; then
  298. case "$platform" in
  299. "ios")
  300. echo "Marking binary as a framework binary for iOS..."
  301. vtool -set-build-version ios ${IOS_MIN_OS_VERSION} ${IOS_MIN_OS_VERSION} -replace \
  302. -output "${base_dir}/${output_lib}" "${base_dir}/${output_lib}"
  303. ;;
  304. "visionos")
  305. echo "Marking binary as a framework binary for visionOS..."
  306. vtool -set-build-version xros ${VISIONOS_MIN_OS_VERSION} ${VISIONOS_MIN_OS_VERSION} -replace \
  307. -output "${base_dir}/${output_lib}" "${base_dir}/${output_lib}"
  308. ;;
  309. "tvos")
  310. echo "Marking binary as a framework binary for tvOS..."
  311. vtool -set-build-version tvos ${TVOS_MIN_OS_VERSION} ${TVOS_MIN_OS_VERSION} -replace \
  312. -output "${base_dir}/${output_lib}" "${base_dir}/${output_lib}"
  313. ;;
  314. esac
  315. else
  316. echo "Warning: vtool not found. Binary may not pass App Store validation."
  317. fi
  318. fi
  319. echo "Creating properly formatted dSYM..."
  320. # Create a separate directory for dSYMs for all platforms
  321. mkdir -p "${base_dir}/${build_dir}/dSYMs"
  322. # iOS and visionOS style dSYM (flat structure)
  323. if [[ "$platform" == "ios" || "$platform" == "visionos" || "$platform" == "tvos" ]]; then
  324. # Generate dSYM in the dSYMs directory
  325. xcrun dsymutil "${base_dir}/${output_lib}" -o "${base_dir}/${build_dir}/dSYMs/llama.dSYM"
  326. # Create a copy of the binary that will be stripped
  327. cp "${base_dir}/${output_lib}" "${temp_dir}/binary_to_strip"
  328. # Strip debug symbols from the copy
  329. xcrun strip -S "${temp_dir}/binary_to_strip" -o "${temp_dir}/stripped_lib"
  330. # Replace the original with the stripped version
  331. mv "${temp_dir}/stripped_lib" "${base_dir}/${output_lib}"
  332. else
  333. # macOS style dSYM
  334. # First strip debug info to a separate file
  335. xcrun strip -S "${base_dir}/${output_lib}" -o "${temp_dir}/stripped_lib"
  336. # Generate dSYM in the dSYMs directory
  337. xcrun dsymutil "${base_dir}/${output_lib}" -o "${base_dir}/${build_dir}/dSYMs/llama.dSYM"
  338. # Replace original binary with stripped version
  339. mv "${temp_dir}/stripped_lib" "${base_dir}/${output_lib}"
  340. fi
  341. # Remove any automatically generated dSYM files in the framework structure as they will
  342. # otherwise case Invalid Bundle Structure validation errors.
  343. if [ -d "${base_dir}/${output_lib}.dSYM" ]; then
  344. echo "Removing generated dSYM file in framework structure: ${base_dir}/${output_lib}.dSYM"
  345. rm -rf "${base_dir}/${output_lib}.dSYM"
  346. fi
  347. # Clean up
  348. rm -rf "${temp_dir}"
  349. }
  350. echo "Building for iOS simulator..."
  351. cmake -B build-ios-sim -G Xcode \
  352. "${COMMON_CMAKE_ARGS[@]}" \
  353. -DCMAKE_OSX_DEPLOYMENT_TARGET=${IOS_MIN_OS_VERSION} \
  354. -DIOS=ON \
  355. -DCMAKE_SYSTEM_NAME=iOS \
  356. -DCMAKE_OSX_SYSROOT=iphonesimulator \
  357. -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
  358. -DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=iphonesimulator \
  359. -DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
  360. -DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
  361. -DLLAMA_CURL=OFF \
  362. -S .
  363. cmake --build build-ios-sim --config Release -- -quiet
  364. echo "Building for iOS devices..."
  365. cmake -B build-ios-device -G Xcode \
  366. "${COMMON_CMAKE_ARGS[@]}" \
  367. -DCMAKE_OSX_DEPLOYMENT_TARGET=${IOS_MIN_OS_VERSION} \
  368. -DCMAKE_OSX_SYSROOT=iphoneos \
  369. -DCMAKE_OSX_ARCHITECTURES="arm64" \
  370. -DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=iphoneos \
  371. -DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
  372. -DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
  373. -DLLAMA_CURL=OFF \
  374. -S .
  375. cmake --build build-ios-device --config Release -- -quiet
  376. echo "Building for macOS..."
  377. cmake -B build-macos -G Xcode \
  378. "${COMMON_CMAKE_ARGS[@]}" \
  379. -DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOS_MIN_OS_VERSION} \
  380. -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
  381. -DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
  382. -DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
  383. -DLLAMA_CURL=OFF \
  384. -S .
  385. cmake --build build-macos --config Release -- -quiet
  386. echo "Building for visionOS..."
  387. cmake -B build-visionos -G Xcode \
  388. "${COMMON_CMAKE_ARGS[@]}" \
  389. -DCMAKE_OSX_DEPLOYMENT_TARGET=${VISIONOS_MIN_OS_VERSION} \
  390. -DCMAKE_OSX_ARCHITECTURES="arm64" \
  391. -DCMAKE_SYSTEM_NAME=visionOS \
  392. -DCMAKE_OSX_SYSROOT=xros \
  393. -DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=xros \
  394. -DCMAKE_C_FLAGS="-D_XOPEN_SOURCE=700 ${COMMON_C_FLAGS}" \
  395. -DCMAKE_CXX_FLAGS="-D_XOPEN_SOURCE=700 ${COMMON_CXX_FLAGS}" \
  396. -DLLAMA_CURL=OFF \
  397. -S .
  398. cmake --build build-visionos --config Release -- -quiet
  399. echo "Building for visionOS simulator..."
  400. cmake -B build-visionos-sim -G Xcode \
  401. "${COMMON_CMAKE_ARGS[@]}" \
  402. -DCMAKE_OSX_DEPLOYMENT_TARGET=${VISIONOS_MIN_OS_VERSION} \
  403. -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
  404. -DCMAKE_SYSTEM_NAME=visionOS \
  405. -DCMAKE_OSX_SYSROOT=xrsimulator \
  406. -DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=xrsimulator \
  407. -DCMAKE_C_FLAGS="-D_XOPEN_SOURCE=700 ${COMMON_C_FLAGS}" \
  408. -DCMAKE_CXX_FLAGS="-D_XOPEN_SOURCE=700 ${COMMON_CXX_FLAGS}" \
  409. -DLLAMA_CURL=OFF \
  410. -S .
  411. cmake --build build-visionos-sim --config Release -- -quiet
  412. # Add tvOS builds (might need the same u_int definitions as watchOS and visionOS)
  413. echo "Building for tvOS simulator..."
  414. cmake -B build-tvos-sim -G Xcode \
  415. "${COMMON_CMAKE_ARGS[@]}" \
  416. -DCMAKE_OSX_DEPLOYMENT_TARGET=${TVOS_MIN_OS_VERSION} \
  417. -DCMAKE_SYSTEM_NAME=tvOS \
  418. -DCMAKE_OSX_SYSROOT=appletvsimulator \
  419. -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" \
  420. -DGGML_METAL=ON \
  421. -DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=appletvsimulator \
  422. -DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
  423. -DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
  424. -DLLAMA_CURL=OFF \
  425. -S .
  426. cmake --build build-tvos-sim --config Release -- -quiet
  427. echo "Building for tvOS devices..."
  428. cmake -B build-tvos-device -G Xcode \
  429. "${COMMON_CMAKE_ARGS[@]}" \
  430. -DCMAKE_OSX_DEPLOYMENT_TARGET=${TVOS_MIN_OS_VERSION} \
  431. -DCMAKE_SYSTEM_NAME=tvOS \
  432. -DCMAKE_OSX_SYSROOT=appletvos \
  433. -DCMAKE_OSX_ARCHITECTURES="arm64" \
  434. -DGGML_METAL=ON \
  435. -DCMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS=appletvos \
  436. -DCMAKE_C_FLAGS="${COMMON_C_FLAGS}" \
  437. -DCMAKE_CXX_FLAGS="${COMMON_CXX_FLAGS}" \
  438. -DLLAMA_CURL=OFF \
  439. -S .
  440. cmake --build build-tvos-device --config Release -- -quiet
  441. # Setup frameworks and copy binaries and headers
  442. echo "Setting up framework structures..."
  443. setup_framework_structure "build-ios-sim" ${IOS_MIN_OS_VERSION} "ios"
  444. setup_framework_structure "build-ios-device" ${IOS_MIN_OS_VERSION} "ios"
  445. setup_framework_structure "build-macos" ${MACOS_MIN_OS_VERSION} "macos"
  446. setup_framework_structure "build-visionos" ${VISIONOS_MIN_OS_VERSION} "visionos"
  447. setup_framework_structure "build-visionos-sim" ${VISIONOS_MIN_OS_VERSION} "visionos"
  448. setup_framework_structure "build-tvos-sim" ${TVOS_MIN_OS_VERSION} "tvos"
  449. setup_framework_structure "build-tvos-device" ${TVOS_MIN_OS_VERSION} "tvos"
  450. # Create dynamic libraries from static libraries
  451. echo "Creating dynamic libraries from static libraries..."
  452. combine_static_libraries "build-ios-sim" "Release-iphonesimulator" "ios" "true"
  453. combine_static_libraries "build-ios-device" "Release-iphoneos" "ios" "false"
  454. combine_static_libraries "build-macos" "Release" "macos" "false"
  455. combine_static_libraries "build-visionos" "Release-xros" "visionos" "false"
  456. combine_static_libraries "build-visionos-sim" "Release-xrsimulator" "visionos" "true"
  457. combine_static_libraries "build-tvos-sim" "Release-appletvsimulator" "tvos" "true"
  458. combine_static_libraries "build-tvos-device" "Release-appletvos" "tvos" "false"
  459. # Create XCFramework with correct debug symbols paths
  460. echo "Creating XCFramework..."
  461. xcodebuild -create-xcframework \
  462. -framework $(pwd)/build-ios-sim/framework/llama.framework \
  463. -debug-symbols $(pwd)/build-ios-sim/dSYMs/llama.dSYM \
  464. -framework $(pwd)/build-ios-device/framework/llama.framework \
  465. -debug-symbols $(pwd)/build-ios-device/dSYMs/llama.dSYM \
  466. -framework $(pwd)/build-macos/framework/llama.framework \
  467. -debug-symbols $(pwd)/build-macos/dSYMS/llama.dSYM \
  468. -framework $(pwd)/build-visionos/framework/llama.framework \
  469. -debug-symbols $(pwd)/build-visionos/dSYMs/llama.dSYM \
  470. -framework $(pwd)/build-visionos-sim/framework/llama.framework \
  471. -debug-symbols $(pwd)/build-visionos-sim/dSYMs/llama.dSYM \
  472. -framework $(pwd)/build-tvos-device/framework/llama.framework \
  473. -debug-symbols $(pwd)/build-tvos-device/dSYMs/llama.dSYM \
  474. -framework $(pwd)/build-tvos-sim/framework/llama.framework \
  475. -debug-symbols $(pwd)/build-tvos-sim/dSYMs/llama.dSYM \
  476. -output $(pwd)/build-apple/llama.xcframework