build-xcframework.sh 21 KB

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