build.sh 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. #!/bin/bash
  2. #
  3. # Written and maintained by [email protected] (2014)
  4. #
  5. BUILD_DIR="./lib/iOS"
  6. ###################################
  7. # SDK Version
  8. ###################################
  9. IOS_SDK_VERSION=$(xcodebuild -version -sdk iphoneos | grep SDKVersion | cut -f2 -d ':' | tr -d '[[:space:]]')
  10. ###################################
  11. ###################################
  12. # BUILD Configuration
  13. ###################################
  14. BUILD_SHARED_LIBS=OFF
  15. BUILD_TYPE=Release
  16. ################################################
  17. # Minimum iOS deployment target version
  18. ################################################
  19. MIN_IOS_VERSION="10.0"
  20. IOS_SDK_TARGET=$MIN_IOS_VERSION
  21. XCODE_ROOT_DIR=$(xcode-select --print-path)
  22. TOOLCHAIN=$XCODE_ROOT_DIR/Toolchains/XcodeDefault.xctoolchain
  23. CMAKE_C_COMPILER=$(xcrun -find cc)
  24. CMAKE_CXX_COMPILER=$(xcrun -find c++)
  25. BUILD_ARCHS_DEVICE="arm64e arm64"
  26. BUILD_ARCHS_SIMULATOR="arm64-simulator x86_64-simulator"
  27. CPP_DEV_TARGET_LIST=(miphoneos-version-min mios-simulator-version-min)
  28. CPP_DEV_TARGET=
  29. CPP_STD_LIB_LIST=(libc++ libstdc++)
  30. CPP_STD_LIB=
  31. CPP_STD_LIST=(c++11 c++14)
  32. CPP_STD=c++11
  33. function join { local IFS="$1"; shift; echo "$*"; }
  34. build_arch()
  35. {
  36. ARCH=$1
  37. if [[ "$ARCH" == *"-simulator" ]]; then
  38. echo '[!] Target SDK set to SIMULATOR.'
  39. IOS_SDK_DEVICE="iphonesimulator" # Use lowercase matching xcrun naming
  40. BUILD_ARCH="${ARCH%-simulator}" # Remove "-simulator" from architecture name
  41. OUTPUT_FOLDER="$BUILD_DIR/ios-$ARCH"
  42. MIN_VERSION_FLAG="-mios-simulator-version-min=$IOS_SDK_TARGET"
  43. else
  44. echo '[!] Target SDK set to DEVICE.'
  45. IOS_SDK_DEVICE="iphoneos" # For device builds
  46. BUILD_ARCH="$ARCH"
  47. OUTPUT_FOLDER="$BUILD_DIR/ios-$ARCH"
  48. MIN_VERSION_FLAG="-miphoneos-version-min=$IOS_SDK_TARGET"
  49. fi
  50. unset DEVROOT SDKROOT CFLAGS LDFLAGS CPPFLAGS CXXFLAGS CMAKE_CLI_INPUT
  51. # Use xcrun with the correct SDK to find clang
  52. export CC="$(xcrun -sdk $IOS_SDK_DEVICE -find clang)"
  53. export CPP="$CC -E"
  54. # Derive correct platform directory names
  55. # Note: iPhoneOS.platform and iPhoneSimulator.platform are used by Xcode internally.
  56. if [[ "$IOS_SDK_DEVICE" == "iphonesimulator" ]]; then
  57. PLATFORM_NAME="iPhoneSimulator"
  58. else
  59. PLATFORM_NAME="iPhoneOS"
  60. fi
  61. export DEVROOT="$XCODE_ROOT_DIR/Platforms/$PLATFORM_NAME.platform/Developer"
  62. export SDKROOT="$DEVROOT/SDKs/$PLATFORM_NAME$IOS_SDK_VERSION.sdk"
  63. # Set flags. For simulator builds, we use -mios-simulator-version-min; for device, -miphoneos-version-min.
  64. export CFLAGS="-arch $BUILD_ARCH -pipe -no-cpp-precomp -isysroot $SDKROOT -I$SDKROOT/usr/include/ $MIN_VERSION_FLAG"
  65. if [[ "$BUILD_TYPE" =~ "Debug" ]]; then
  66. export CFLAGS="$CFLAGS -Og"
  67. else
  68. export CFLAGS="$CFLAGS -O3"
  69. fi
  70. export LDFLAGS="-arch $BUILD_ARCH -isysroot $SDKROOT -L$SDKROOT/usr/lib/"
  71. export CPPFLAGS="$CFLAGS"
  72. export CXXFLAGS="$CFLAGS -std=$CPP_STD"
  73. rm -f CMakeCache.txt
  74. # Construct the CMake toolchain file path
  75. # Make sure these toolchain files differentiate between device and simulator builds properly.
  76. TOOLCHAIN_FILE="./port/iOS/${PLATFORM_NAME}_$(echo "$BUILD_ARCH" | tr '[:lower:]' '[:upper:]')_TOOLCHAIN.cmake"
  77. CMAKE_CLI_INPUT="-DCMAKE_C_COMPILER=$CMAKE_C_COMPILER -DCMAKE_CXX_COMPILER=$CMAKE_CXX_COMPILER \
  78. -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN_FILE \
  79. -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
  80. -DBUILD_SHARED_LIBS=$BUILD_SHARED_LIBS \
  81. -DASSIMP_BUILD_ZLIB=ON"
  82. echo "[!] Running CMake with -G 'Unix Makefiles' $CMAKE_CLI_INPUT"
  83. cmake -G 'Unix Makefiles' ${CMAKE_CLI_INPUT}
  84. echo "[!] Building $ARCH library"
  85. xcrun -run make clean
  86. xcrun -run make assimp -j 8 -l
  87. mkdir -p $OUTPUT_FOLDER
  88. if [[ "$BUILD_SHARED_LIBS" =~ "ON" ]]; then
  89. echo "[!] Moving built dynamic libraries into: $OUTPUT_FOLDER"
  90. mv ./lib/*.dylib $OUTPUT_FOLDER/
  91. fi
  92. echo "[!] Moving built static libraries into: $OUTPUT_FOLDER"
  93. mv ./lib/*.a $OUTPUT_FOLDER/
  94. }
  95. echo "[!] $0 - assimp iOS build script"
  96. CPP_STD_LIB=${CPP_STD_LIB_LIST[0]}
  97. CPP_STD=${CPP_STD_LIST[0]}
  98. DEPLOY_FAT=1
  99. DEPLOY_XCFramework=1
  100. for i in "$@"; do
  101. case $i in
  102. -s=*|--std=*)
  103. CPP_STD=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
  104. echo "[!] Selecting c++ standard: $CPP_STD"
  105. ;;
  106. -l=*|--stdlib=*)
  107. CPP_STD_LIB=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
  108. echo "[!] Selecting c++ std lib: $CPP_STD_LIB"
  109. ;;
  110. -a=*|--archs=*)
  111. DEPLOY_ARCHS=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
  112. echo "[!] Selecting architectures: $DEPLOY_ARCHS"
  113. ;;
  114. --min-version=*)
  115. MIN_IOS_VERSION=`echo $i | sed 's/[-a-zA-Z0-9]*=//'`
  116. IOS_SDK_TARGET=$MIN_IOS_VERSION
  117. echo "[!] Selecting minimum iOS version: $MIN_IOS_VERSION"
  118. ;;
  119. --debug)
  120. BUILD_TYPE=Debug
  121. echo "[!] Selecting build type: Debug"
  122. ;;
  123. --shared-lib)
  124. BUILD_SHARED_LIBS=ON
  125. echo "[!] Will generate dynamic libraries"
  126. ;;
  127. -n|--no-fat)
  128. DEPLOY_FAT=0
  129. echo "[!] Fat binary will not be created."
  130. ;;
  131. --no-xcframework)
  132. DEPLOY_XCFramework=0
  133. echo "[!] XCFramework will not be created."
  134. ;;
  135. -h|--help)
  136. echo " - don't build fat library (--no-fat)."
  137. echo " - don't build XCFramework (--no-xcframework)."
  138. echo " - Include debug information and symbols, no compiler optimizations (--debug)."
  139. echo " - generate dynamic libraries rather than static ones (--shared-lib)."
  140. echo " - supported architectures (--archs): $(echo $(join , ${BUILD_ARCHS_ALL[*]}) | sed 's/,/, /g')"
  141. echo " - minimum iOS version (--min-version): 16.0"
  142. echo " - supported C++ STD libs (--stdlib): $(echo $(join , ${CPP_STD_LIB_LIST[*]}) | sed 's/,/, /g')"
  143. echo " - supported C++ standards (--std): $(echo $(join , ${CPP_STD_LIST[*]}) | sed 's/,/, /g')"
  144. exit
  145. ;;
  146. *)
  147. ;;
  148. esac
  149. done
  150. cd ../../
  151. rm -rf $BUILD_DIR
  152. for ARCH in $BUILD_ARCHS_DEVICE; do
  153. echo "Building for DEVICE arch: $ARCH"
  154. build_arch $ARCH
  155. done
  156. for ARCH in $BUILD_ARCHS_SIMULATOR; do
  157. echo "Building for SIMULATOR arch: $ARCH"
  158. build_arch $ARCH
  159. done
  160. make_fat_static_or_shared_binary()
  161. {
  162. LIB_NAME=$1
  163. LIPO_ARGS=''
  164. for ARCH_TARGET in $DEPLOY_ARCHS; do
  165. if [[ "$BUILD_SHARED_LIBS" =~ "ON" ]]; then
  166. LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.dylib "
  167. else
  168. LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.a "
  169. fi
  170. done
  171. if [[ "$BUILD_SHARED_LIBS" =~ "ON" ]]; then
  172. LIPO_ARGS="$LIPO_ARGS -create -output $BUILD_DIR/$LIB_NAME-fat.dylib"
  173. else
  174. LIPO_ARGS="$LIPO_ARGS -create -output $BUILD_DIR/$LIB_NAME-fat.a"
  175. fi
  176. lipo $LIPO_ARGS
  177. }
  178. make_fat_static_binary()
  179. {
  180. LIB_NAME=$1
  181. LIPO_ARGS=''
  182. for ARCH_TARGET in $DEPLOY_ARCHS; do
  183. LIPO_ARGS="$LIPO_ARGS-arch $ARCH_TARGET $BUILD_DIR/$ARCH_TARGET/$LIB_NAME.a "
  184. done
  185. LIPO_ARGS="$LIPO_ARGS -create -output $BUILD_DIR/$LIB_NAME-fat.a"
  186. lipo $LIPO_ARGS
  187. }
  188. if [[ "$DEPLOY_FAT" -eq 1 ]]; then
  189. echo '[+] Creating fat binaries ...'
  190. if [[ "$BUILD_TYPE" =~ "Debug" ]]; then
  191. make_fat_static_or_shared_binary 'libassimpd'
  192. else
  193. make_fat_static_or_shared_binary 'libassimp'
  194. fi
  195. echo "[!] Done! The fat binaries can be found at $BUILD_DIR"
  196. fi
  197. make_xcframework() {
  198. LIB_NAME=$1
  199. FRAMEWORK_PATH="$BUILD_DIR/$LIB_NAME.xcframework"
  200. # Paths to device and simulator libraries
  201. DEVICE_LIB_PATH="$BUILD_DIR/ios-arm64/libassimp.a"
  202. ARM64_SIM_LIB_PATH="$BUILD_DIR/ios-arm64-simulator/libassimp.a"
  203. X86_64_SIM_LIB_PATH="$BUILD_DIR/ios-x86_64-simulator/libassimp.a"
  204. UNIVERSAL_SIM_LIB_PATH="$BUILD_DIR/ios-simulator/libassimp.a"
  205. # Ensure we have a clean location for the universal simulator lib
  206. mkdir -p "$BUILD_DIR/ios-simulator"
  207. # Combine simulator libraries if both arm64 and x86_64 simulator slices are present
  208. if [[ -f "$ARM64_SIM_LIB_PATH" && -f "$X86_64_SIM_LIB_PATH" ]]; then
  209. echo "[+] Combining arm64 and x86_64 simulator libs into a universal simulator library..."
  210. lipo -create "$ARM64_SIM_LIB_PATH" "$X86_64_SIM_LIB_PATH" -output "$UNIVERSAL_SIM_LIB_PATH" || {
  211. echo "[ERROR] lipo failed to combine simulator libraries."
  212. exit 1
  213. }
  214. SIM_LIB_PATH="$UNIVERSAL_SIM_LIB_PATH"
  215. elif [[ -f "$ARM64_SIM_LIB_PATH" ]]; then
  216. echo "[!] Only arm64 simulator library found. Using it as is."
  217. SIM_LIB_PATH="$ARM64_SIM_LIB_PATH"
  218. elif [[ -f "$X86_64_SIM_LIB_PATH" ]]; then
  219. echo "[!] Only x86_64 simulator library found. Using it as is."
  220. SIM_LIB_PATH="$X86_64_SIM_LIB_PATH"
  221. else
  222. SIM_LIB_PATH=""
  223. fi
  224. ARGS=""
  225. # Device library
  226. if [[ -f "$DEVICE_LIB_PATH" ]]; then
  227. echo "[DEBUG] Adding library $DEVICE_LIB_PATH for device arm64"
  228. ARGS="$ARGS -library $DEVICE_LIB_PATH -headers ./include"
  229. else
  230. echo "[WARNING] Device library not found: $DEVICE_LIB_PATH"
  231. fi
  232. # Simulator library (could be universal or a single-arch one)
  233. if [[ -n "$SIM_LIB_PATH" && -f "$SIM_LIB_PATH" ]]; then
  234. echo "[DEBUG] Adding library $SIM_LIB_PATH for simulator"
  235. ARGS="$ARGS -library $SIM_LIB_PATH -headers ./include"
  236. fi
  237. if [[ -z "$ARGS" ]]; then
  238. echo "[ERROR] No valid libraries found to create XCFramework."
  239. exit 1
  240. fi
  241. # Create XCFramework
  242. echo "[+] Creating XCFramework ..."
  243. xcodebuild -create-xcframework $ARGS -output $FRAMEWORK_PATH
  244. echo "[!] Done! The XCFramework can be found at $FRAMEWORK_PATH"
  245. }
  246. if [[ "$DEPLOY_XCFramework" -eq 1 ]]; then
  247. echo '[+] Creating XCFramework ...'
  248. if [[ "$BUILD_TYPE" =~ "Debug" ]]; then
  249. make_xcframework 'libassimpd'
  250. else
  251. make_xcframework 'libassimp'
  252. fi
  253. echo "[!] Done! The XCFramework can be found at $BUILD_DIR"
  254. fi