Run virtual machines on iOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

789 lines
25 KiB

  1. #!/bin/sh
  2. # Based off of https://github.com/szanni/ios-autotools/blob/master/iconfigure
  3. # Copyright (c) 2014, Angelo Haller
  4. #
  5. # Permission to use, copy, modify, and/or distribute this software for any
  6. # purpose with or without fee is hereby granted, provided that the above
  7. # copyright notice and this permission notice appear in all copies.
  8. #
  9. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. set -e
  17. # Printing coloured lines
  18. GREEN='\033[0;32m'
  19. RED='\033[0;31m'
  20. NC='\033[0m'
  21. # Knobs
  22. IOS_SDKMINVER="11.0"
  23. MAC_SDKMINVER="10.11"
  24. VISIONOS_SDKMINVER="1.0"
  25. # Build environment
  26. PLATFORM=
  27. CHOST=
  28. SDK=
  29. SDKMINVER=
  30. command -v realpath >/dev/null 2>&1 || realpath() {
  31. [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
  32. }
  33. version_check() {
  34. [ "$1" = "$(echo "$1\n$2" | sort -V | head -n1)" ]
  35. }
  36. usage () {
  37. echo "Usage: [VARIABLE...] $(basename $0) [-p platform] [-a architecture] [-q qemu_path] [-d] [-r]"
  38. echo ""
  39. echo " -p platform Target platform. Default ios. [ios|ios_simulator|ios-tci|ios_simulator-tci|macos|visionos|visionos_simulator]"
  40. echo " -a architecture Target architecture. Default arm64. [armv7|armv7s|arm64|i386|x86_64]"
  41. echo " -q qemu_path Do not download QEMU, use qemu_path instead."
  42. echo " -d, --download Force re-download of source even if already downloaded."
  43. echo " -r, --rebuild Avoid cleaning build directory."
  44. echo ""
  45. echo " VARIABLEs are:"
  46. echo " NCPU Number of CPUs to use in 'make', 0 to use all cores."
  47. echo " SDKVERSION Target a specific SDK version."
  48. echo " CHOST Configure host, set if not deducable by ARCH."
  49. echo ""
  50. echo " CFLAGS CPPFLAGS CXXFLAGS LDFLAGS"
  51. echo ""
  52. exit 1
  53. }
  54. python_module_test () {
  55. python3 -c "import $1"
  56. }
  57. check_env () {
  58. command -v python3 >/dev/null 2>&1 || { echo >&2 "${RED}You must install 'python3' on your host machine.${NC}"; exit 1; }
  59. python_module_test six >/dev/null 2>&1 || { echo >&2 "${RED}'six' not found in your Python 3 installation.${NC}"; exit 1; }
  60. python_module_test pyparsing >/dev/null 2>&1 || { echo >&2 "${RED}'pyparsing' not found in your Python 3 installation.${NC}"; exit 1; }
  61. command -v meson >/dev/null 2>&1 || { echo >&2 "${RED}You must install 'meson' on your host machine.${NC}"; exit 1; }
  62. command -v msgfmt >/dev/null 2>&1 || { echo >&2 "${RED}You must install 'gettext' on your host machine.\n\t'msgfmt' needs to be in your \$PATH as well.${NC}"; exit 1; }
  63. command -v glib-mkenums >/dev/null 2>&1 || { echo >&2 "${RED}You must install 'glib-utils' on your host machine.\n\t'glib-mkenums' needs to be in your \$PATH as well.${NC}"; exit 1; }
  64. command -v gpg-error-config >/dev/null 2>&1 || { echo >&2 "${RED}You must install 'libgpg-error' on your host machine.\n\t'gpg-error-config' needs to be in your \$PATH as well.${NC}"; exit 1; }
  65. command -v xcrun >/dev/null 2>&1 || { echo >&2 "${RED}'xcrun' is not found. Make sure you are running on OSX."; exit 1; }
  66. command -v otool >/dev/null 2>&1 || { echo >&2 "${RED}'otool' is not found. Make sure you are running on OSX."; exit 1; }
  67. command -v install_name_tool >/dev/null 2>&1 || { echo >&2 "${RED}'install_name_tool' is not found. Make sure you are running on OSX."; exit 1; }
  68. version_check "2.4" "$(bison -V | head -1 | awk '{ print $NF }')" || { echo >&2 "${RED}'bison' >= 2.4 is required. Did you install from Homebrew and updated your \$PATH variable?"; exit 1; }
  69. }
  70. download () {
  71. URL=$1
  72. FILE="$(basename $URL)"
  73. NAME="${FILE%.tar.*}"
  74. TARGET="$BUILD_DIR/$FILE"
  75. DIR="$BUILD_DIR/$NAME"
  76. PATCH="$PATCHES_DIR/${NAME}.patch"
  77. DATA="$PATCHES_DIR/data/${NAME}"
  78. if [ -f "$TARGET" -a -z "$REDOWNLOAD" ]; then
  79. echo "${GREEN}$TARGET already downloaded! Run with -d to force re-download.${NC}"
  80. else
  81. echo "${GREEN}Downloading ${URL}...${NC}"
  82. curl -L -O "$URL"
  83. mv "$FILE" "$TARGET"
  84. fi
  85. if [ -d "$DIR" ]; then
  86. echo "${GREEN}Deleting existing build directory ${DIR}...${NC}"
  87. rm -rf "$DIR"
  88. fi
  89. echo "${GREEN}Unpacking ${NAME}...${NC}"
  90. tar -xf "$TARGET" -C "$BUILD_DIR"
  91. if [ -f "$PATCH" ]; then
  92. echo "${GREEN}Patching ${NAME}...${NC}"
  93. patch -d "$DIR" -p1 < "$PATCH"
  94. fi
  95. if [ -d "$DATA" ]; then
  96. echo "${GREEN}Patching data ${NAME}...${NC}"
  97. cp -r "$DATA/" "$DIR"
  98. fi
  99. }
  100. clone () {
  101. REPO="$1"
  102. COMMIT="$2"
  103. SUBDIRS="$3"
  104. NAME="$(basename $REPO)"
  105. DIR="$BUILD_DIR/$NAME"
  106. if [ -d "$DIR" -a -z "$REDOWNLOAD" ]; then
  107. echo "${GREEN}$DIR already downloaded! Run with -d to force re-download.${NC}"
  108. else
  109. rm -rf "$DIR"
  110. echo "${GREEN}Cloning ${URL}...${NC}"
  111. git clone --filter=tree:0 --no-checkout "$REPO" "$DIR"
  112. if [ ! -z "$SUBDIRS" ]; then
  113. git -C "$DIR" sparse-checkout init
  114. git -C "$DIR" sparse-checkout set $SUBDIRS
  115. fi
  116. fi
  117. git -C "$DIR" checkout "$COMMIT"
  118. }
  119. download_all () {
  120. [ -d "$BUILD_DIR" ] || mkdir -p "$BUILD_DIR"
  121. download $PKG_CONFIG_SRC
  122. download $FFI_SRC
  123. download $ICONV_SRC
  124. download $GETTEXT_SRC
  125. download $PNG_SRC
  126. download $JPEG_TURBO_SRC
  127. download $GLIB_SRC
  128. download $GPG_ERROR_SRC
  129. download $GCRYPT_SRC
  130. download $PIXMAN_SRC
  131. download $OPENSSL_SRC
  132. download $TPMS_SRC
  133. download $SWTPM_SRC
  134. download $OPUS_SRC
  135. download $SPICE_PROTOCOL_SRC
  136. download $SPICE_SERVER_SRC
  137. download $JSON_GLIB_SRC
  138. download $GST_SRC
  139. download $GST_BASE_SRC
  140. download $GST_GOOD_SRC
  141. download $XML2_SRC
  142. download $SOUP_SRC
  143. download $PHODAV_SRC
  144. download $SPICE_CLIENT_SRC
  145. download $ZSTD_SRC
  146. download $SLIRP_SRC
  147. download $QEMU_SRC
  148. if [ -z "$SKIP_USB_BUILD" ]; then
  149. download $USB_SRC
  150. download $USBREDIR_SRC
  151. fi
  152. clone $WEBKIT_REPO $WEBKIT_COMMIT "$WEBKIT_SUBDIRS"
  153. clone $EPOXY_REPO $EPOXY_COMMIT
  154. clone $VIRGLRENDERER_REPO $VIRGLRENDERER_COMMIT
  155. clone $HYPERVISOR_REPO $HYPERVISOR_COMMIT
  156. }
  157. copy_private_headers() {
  158. MACOS_SDK_PATH="$(xcrun --sdk macosx --show-sdk-path)"
  159. IOKIT_HEADERS_PATH="$MACOS_SDK_PATH/System/Library/Frameworks/IOKit.framework/Headers"
  160. OSTYPES_HEADERS_PATH="$MACOS_SDK_PATH/usr/include/libkern"
  161. OUTPUT_INCLUDES="$PREFIX/include"
  162. if [ ! -d "$IOKIT_HEADERS_PATH" ]; then
  163. echo "${RED}Failed to find IOKit headers in: $IOKIT_HEADERS_PATH${NC}"
  164. exit 1
  165. fi
  166. if [ ! -d "$OSTYPES_HEADERS_PATH" ]; then
  167. echo "${RED}Failed to find libkern headers in: $OSTYPES_HEADERS_PATH${NC}"
  168. exit 1
  169. fi
  170. echo "${GREEN}Copying private headers...${NC}"
  171. mkdir -p "$OUTPUT_INCLUDES"
  172. cp -r "$IOKIT_HEADERS_PATH" "$OUTPUT_INCLUDES/IOKit"
  173. rm "$OUTPUT_INCLUDES/IOKit/storage/IOMedia.h" # needed to pass QEMU check
  174. # patch headers
  175. LC_ALL=C sed -i '' -e 's/#if KERNEL_USER32/#if 0/g' $(find "$OUTPUT_INCLUDES/IOKit" -type f)
  176. LC_ALL=C sed -i '' -e 's/#if !KERNEL_USER32/#if 1/g' $(find "$OUTPUT_INCLUDES/IOKit" -type f)
  177. LC_ALL=C sed -i '' -e 's/#if KERNEL/#if 0/g' $(find "$OUTPUT_INCLUDES/IOKit" -type f)
  178. LC_ALL=C sed -i '' -e 's/#if !KERNEL/#if 1/g' $(find "$OUTPUT_INCLUDES/IOKit" -type f)
  179. LC_ALL=C sed -i '' -e 's/__UNAVAILABLE_PUBLIC_IOS;/;/g' $(find "$OUTPUT_INCLUDES/IOKit" -type f)
  180. mkdir -p "$OUTPUT_INCLUDES/libkern"
  181. cp -r "$OSTYPES_HEADERS_PATH/OSTypes.h" "$OUTPUT_INCLUDES/libkern/OSTypes.h"
  182. }
  183. meson_quote() {
  184. echo "'$(echo $* | sed "s/ /','/g")'"
  185. }
  186. generate_meson_cross() {
  187. cross="$1"
  188. echo "# Automatically generated - do not modify" > $cross
  189. echo "[properties]" >> $cross
  190. echo "needs_exe_wrapper = true" >> $cross
  191. echo "[built-in options]" >> $cross
  192. echo "c_args = [${CFLAGS:+$(meson_quote $CFLAGS)}]" >> $cross
  193. echo "cpp_args = [${CXXFLAGS:+$(meson_quote $CXXFLAGS)}]" >> $cross
  194. echo "c_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
  195. echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
  196. echo "[binaries]" >> $cross
  197. echo "c = [$(meson_quote $CC)]" >> $cross
  198. echo "cpp = [$(meson_quote $CXX)]" >> $cross
  199. echo "objc = [$(meson_quote $OBJCC)]" >> $cross
  200. echo "ar = [$(meson_quote $AR)]" >> $cross
  201. echo "nm = [$(meson_quote $NM)]" >> $cross
  202. echo "pkgconfig = ['$PREFIX/host/bin/pkg-config']" >> $cross
  203. echo "ranlib = [$(meson_quote $RANLIB)]" >> $cross
  204. echo "strip = [$(meson_quote $STRIP), '-x']" >> $cross
  205. echo "python = ['$(which python3)']" >> $cross
  206. echo "[host_machine]" >> $cross
  207. case $PLATFORM in
  208. ios* | visionos* )
  209. echo "system = 'ios'" >> $cross
  210. ;;
  211. macos )
  212. echo "system = 'darwin'" >> $cross
  213. ;;
  214. esac
  215. case "$ARCH" in
  216. armv7 | armv7s )
  217. echo "cpu_family = 'arm'" >> $cross
  218. ;;
  219. arm64 )
  220. echo "cpu_family = 'aarch64'" >> $cross
  221. ;;
  222. i386 )
  223. echo "cpu_family = 'x86'" >> $cross
  224. ;;
  225. x86_64 )
  226. echo "cpu_family = 'x86_64'" >> $cross
  227. ;;
  228. *)
  229. echo "cpu_family = '$ARCH'" >> $cross
  230. ;;
  231. esac
  232. echo "cpu = '$ARCH'" >> $cross
  233. echo "endian = 'little'" >> $cross
  234. }
  235. # Prevent contamination from host pkg-config files by building our own
  236. build_pkg_config() {
  237. FILE="$(basename $PKG_CONFIG_SRC)"
  238. NAME="${FILE%.tar.*}"
  239. DIR="$BUILD_DIR/$NAME"
  240. pwd="$(pwd)"
  241. cd "$DIR"
  242. if [ -z "$REBUILD" ]; then
  243. echo "${GREEN}Configuring ${NAME}...${NC}"
  244. env -i ./configure --prefix="$PREFIX" --bindir="$PREFIX/host/bin" --with-internal-glib $@
  245. fi
  246. echo "${GREEN}Building ${NAME}...${NC}"
  247. make -j$NCPU
  248. echo "${GREEN}Installing ${NAME}...${NC}"
  249. make install
  250. cd "$pwd"
  251. export PATH="$PREFIX/host/bin:$PATH"
  252. export PKG_CONFIG="$PREFIX/host/bin/pkg-config"
  253. }
  254. build_openssl() {
  255. URL=$1
  256. shift 1
  257. FILE="$(basename $URL)"
  258. NAME="${FILE%.tar.*}"
  259. DIR="$BUILD_DIR/$NAME"
  260. pwd="$(pwd)"
  261. TOOLCHAIN_PATH="$(dirname $(xcrun --sdk $SDK -find clang))"
  262. PATH="$PATH:$TOOLCHAIN_PATH"
  263. CROSS_TOP="$(xcrun --sdk $SDK --show-sdk-platform-path)/Developer" # for openssl
  264. CROSS_SDK="$SDKNAME$SDKVERSION.sdk" # for openssl
  265. export CROSS_TOP
  266. export CROSS_SDK
  267. export PATH
  268. case $ARCH in
  269. armv7 | armv7s )
  270. OPENSSL_CROSS=iphoneos-cross
  271. ;;
  272. arm64 )
  273. OPENSSL_CROSS=ios64-cross
  274. ;;
  275. i386 )
  276. OPENSSL_CROSS=darwin-i386-cc
  277. ;;
  278. x86_64 )
  279. OPENSSL_CROSS=darwin64-x86_64-cc
  280. ;;
  281. esac
  282. case $PLATFORM in
  283. ios | ios-tci )
  284. case $ARCH in
  285. armv7 | armv7s )
  286. OPENSSL_CROSS=iphoneos-cross
  287. ;;
  288. arm64 )
  289. OPENSSL_CROSS=ios64-cross
  290. ;;
  291. i386 | x86_64 )
  292. OPENSSL_CROSS=iossimulator64-cross
  293. ;;
  294. esac
  295. ;;
  296. macos )
  297. case $ARCH in
  298. arm64 )
  299. OPENSSL_CROSS=darwin64-arm64-cc
  300. ;;
  301. i386 )
  302. OPENSSL_CROSS=darwin-i386-cc
  303. ;;
  304. x86_64 )
  305. OPENSSL_CROSS=darwin64-x86_64-cc
  306. ;;
  307. esac
  308. ;;
  309. visionos_simulator )
  310. OPENSSL_CROSS=visionos-sim-cross-$ARCH
  311. ;;
  312. visionos* )
  313. OPENSSL_CROSS=visionos-cross-$ARCH
  314. ;;
  315. esac
  316. if [ -z "$OPENSSL_CROSS" ]; then
  317. echo "${RED}Unsupported configuration for OpenSSL $PLATFORM, $ARCH${NC}"
  318. exit 1
  319. fi
  320. cd "$DIR"
  321. if [ -z "$REBUILD" ]; then
  322. echo "${GREEN}Configuring ${NAME}...${NC}"
  323. ./Configure $OPENSSL_CROSS no-dso no-hw no-engine --prefix="$PREFIX" $@
  324. fi
  325. echo "${GREEN}Building ${NAME}...${NC}"
  326. make -j$NCPU
  327. echo "${GREEN}Installing ${NAME}...${NC}"
  328. make install
  329. cd "$pwd"
  330. }
  331. build () {
  332. if [ -d "$1" ]; then
  333. DIR="$1"
  334. NAME="$(basename "$DIR")"
  335. else
  336. URL=$1
  337. shift 1
  338. FILE="$(basename $URL)"
  339. NAME="${FILE%.tar.*}"
  340. DIR="$BUILD_DIR/$NAME"
  341. fi
  342. pwd="$(pwd)"
  343. cd "$DIR"
  344. if [ -z "$REBUILD" ]; then
  345. echo "${GREEN}Configuring ${NAME}...${NC}"
  346. ./configure --prefix="$PREFIX" --host="$CHOST" $@
  347. fi
  348. echo "${GREEN}Building ${NAME}...${NC}"
  349. make -j$NCPU
  350. echo "${GREEN}Installing ${NAME}...${NC}"
  351. make install
  352. cd "$pwd"
  353. }
  354. meson_build () {
  355. SRCDIR="$1"
  356. shift 1
  357. FILE="$(basename $SRCDIR)"
  358. NAME="${FILE%.tar.*}"
  359. case $SRCDIR in
  360. http* | ftp* )
  361. SRCDIR="$BUILD_DIR/$NAME"
  362. ;;
  363. esac
  364. MESON_CROSS="$(realpath "$BUILD_DIR")/meson.cross"
  365. if [ ! -f "$MESON_CROSS" ]; then
  366. generate_meson_cross "$MESON_CROSS"
  367. fi
  368. pwd="$(pwd)"
  369. cd "$SRCDIR"
  370. if [ -z "$REBUILD" ]; then
  371. rm -rf utm_build
  372. echo "${GREEN}Configuring ${NAME}...${NC}"
  373. meson utm_build --prefix="$PREFIX" --buildtype=plain --cross-file "$MESON_CROSS" "$@"
  374. fi
  375. echo "${GREEN}Building ${NAME}...${NC}"
  376. meson compile -C utm_build -j $NCPU
  377. echo "${GREEN}Installing ${NAME}...${NC}"
  378. meson install -C utm_build
  379. cd "$pwd"
  380. }
  381. build_angle () {
  382. OLD_PATH=$PATH
  383. export PATH="$(realpath "$BUILD_DIR/depot_tools.git"):$OLD_PATH"
  384. pwd="$(pwd)"
  385. cd "$BUILD_DIR/WebKit.git/Source/ThirdParty/ANGLE"
  386. xcodebuild archive -archivePath "ANGLE" -scheme "ANGLE" -sdk $SDK -arch $ARCH -configuration Release WEBCORE_LIBRARY_DIR="/usr/local/lib" IPHONEOS_DEPLOYMENT_TARGET="14.0" MACOSX_DEPLOYMENT_TARGET="11.0" XROS_DEPLOYMENT_TARGET="1.0"
  387. rsync -a "ANGLE.xcarchive/Products/usr/local/lib/" "$PREFIX/lib"
  388. rsync -a "include/" "$PREFIX/include"
  389. cd "$pwd"
  390. export PATH=$OLD_PATH
  391. }
  392. build_hypervisor () {
  393. OLD_PATH=$PATH
  394. export PATH="$(realpath "$BUILD_DIR/depot_tools.git"):$OLD_PATH"
  395. pwd="$(pwd)"
  396. cd "$BUILD_DIR/Hypervisor.git"
  397. echo "${GREEN}Building Hypervisor...${NC}"
  398. env -i PATH=$PATH xcodebuild archive -archivePath "Hypervisor" -scheme "Hypervisor" -sdk $SDK -configuration Release
  399. rsync -a "Hypervisor.xcarchive/Products/Library/Frameworks/" "$PREFIX/Frameworks"
  400. cd "$pwd"
  401. export PATH=$OLD_PATH
  402. }
  403. generate_fake_hypervisor () {
  404. mkdir "$PREFIX/Frameworks/Hypervisor.framework"
  405. touch "$PREFIX/Frameworks/Hypervisor.framework/Hypervisor"
  406. /usr/libexec/PlistBuddy -c "Add :CFBundleExecutable string Hypervisor" "$PREFIX/Frameworks/Hypervisor.framework/Info.plist"
  407. /usr/libexec/PlistBuddy -c "Add :CFBundleIdentifier string com.pomegranate.Hypervisor" "$PREFIX/Frameworks/Hypervisor.framework/Info.plist"
  408. /usr/libexec/PlistBuddy -c "Add :MinimumOSVersion string $SDKMINVER" "$PREFIX/Frameworks/Hypervisor.framework/Info.plist"
  409. /usr/libexec/PlistBuddy -c "Add :CFBundleVersion string 1" "$PREFIX/Frameworks/Hypervisor.framework/Info.plist"
  410. /usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string 1.0" "$PREFIX/Frameworks/Hypervisor.framework/Info.plist"
  411. }
  412. build_qemu_dependencies () {
  413. build $FFI_SRC
  414. build $ICONV_SRC
  415. build $GETTEXT_SRC --disable-java
  416. build $PNG_SRC
  417. build $JPEG_TURBO_SRC
  418. meson_build $GLIB_SRC -Dtests=false
  419. build $GPG_ERROR_SRC
  420. build $GCRYPT_SRC
  421. build $PIXMAN_SRC
  422. build_openssl $OPENSSL_SRC
  423. build $TPMS_SRC --disable-shared
  424. build $SWTPM_SRC --enable-shared-lib
  425. build $OPUS_SRC
  426. ZSTD_BASENAME="$(basename $ZSTD_SRC)"
  427. meson_build "$BUILD_DIR/${ZSTD_BASENAME%.tar.*}/build/meson"
  428. meson_build $GST_SRC -Dtests=disabled -Ddefault_library=both -Dregistry=false
  429. meson_build $GST_BASE_SRC -Dtests=disabled -Ddefault_library=both -Dgl=disabled
  430. meson_build $GST_GOOD_SRC -Dtests=disabled -Ddefault_library=both
  431. meson_build $SPICE_PROTOCOL_SRC
  432. meson_build $SPICE_SERVER_SRC -Dlz4=false -Dsasl=false
  433. meson_build $SLIRP_SRC
  434. # USB support
  435. if [ -z "$SKIP_USB_BUILD" ]; then
  436. build $USB_SRC
  437. meson_build $USBREDIR_SRC
  438. fi
  439. # GPU support
  440. build_angle
  441. meson_build $EPOXY_REPO -Dtests=false -Dglx=no -Degl=yes
  442. meson_build $VIRGLRENDERER_REPO -Dtests=false -Dcheck-gl-errors=false
  443. # Hypervisor for iOS
  444. if [ "$PLATFORM" == "ios" ]; then
  445. build_hypervisor
  446. fi
  447. }
  448. build_spice_client () {
  449. meson_build "$QEMU_DIR/subprojects/libucontext" -Ddefault_library=static -Dfreestanding=true
  450. meson_build $JSON_GLIB_SRC -Dintrospection=disabled
  451. build $XML2_SRC --enable-shared=no --without-python
  452. meson_build $SOUP_SRC --default-library static -Dsysprof=disabled -Dtls_check=false -Dintrospection=disabled
  453. meson_build $PHODAV_SRC
  454. meson_build $SPICE_CLIENT_SRC -Dcoroutine=libucontext -Dphysical-cd=disabled
  455. }
  456. fixup () {
  457. FILE=$1
  458. BASE=$(basename "$FILE")
  459. BASEFILENAME=${BASE%.*}
  460. LIBNAME=${BASEFILENAME#lib*}
  461. BUNDLE_ID="com.utmapp.${LIBNAME//_/-}"
  462. FRAMEWORKNAME="$LIBNAME.framework"
  463. BASEFRAMEWORKPATH="$PREFIX/Frameworks/$FRAMEWORKNAME"
  464. if [ "$PLATFORM" == "macos" ]; then
  465. FRAMEWORKPATH="$BASEFRAMEWORKPATH/Versions/A"
  466. INFOPATH="$FRAMEWORKPATH/Resources"
  467. else
  468. FRAMEWORKPATH="$BASEFRAMEWORKPATH"
  469. INFOPATH="$FRAMEWORKPATH"
  470. fi
  471. NEWFILE="$FRAMEWORKPATH/$LIBNAME"
  472. LIST=$(otool -L "$FILE" | tail -n +2 | cut -d ' ' -f 1 | awk '{$1=$1};1')
  473. OLDIFS=$IFS
  474. IFS=$'\n'
  475. echo "${GREEN}Fixing up $FILE...${NC}"
  476. mkdir -p "$FRAMEWORKPATH"
  477. mkdir -p "$INFOPATH"
  478. cp -a "$FILE" "$NEWFILE"
  479. /usr/libexec/PlistBuddy -c "Add :CFBundleExecutable string $LIBNAME" "$INFOPATH/Info.plist"
  480. /usr/libexec/PlistBuddy -c "Add :CFBundleIdentifier string $BUNDLE_ID" "$INFOPATH/Info.plist"
  481. /usr/libexec/PlistBuddy -c "Add :MinimumOSVersion string $SDKMINVER" "$INFOPATH/Info.plist"
  482. /usr/libexec/PlistBuddy -c "Add :CFBundleVersion string 1" "$INFOPATH/Info.plist"
  483. /usr/libexec/PlistBuddy -c "Add :CFBundleShortVersionString string 1.0" "$INFOPATH/Info.plist"
  484. if [ "$PLATFORM" == "macos" ]; then
  485. ln -sf "A" "$BASEFRAMEWORKPATH/Versions/Current"
  486. ln -sf "Versions/Current/Resources" "$BASEFRAMEWORKPATH/Resources"
  487. ln -sf "Versions/Current/$LIBNAME" "$BASEFRAMEWORKPATH/$LIBNAME"
  488. fi
  489. newname="@rpath/$FRAMEWORKNAME/$LIBNAME"
  490. install_name_tool -id "$newname" "$NEWFILE"
  491. for g in $LIST
  492. do
  493. base=$(basename "$g")
  494. basefilename=${base%.*}
  495. libname=${basefilename#lib*}
  496. dir=$(dirname "$g")
  497. if [ "$dir" == "$PREFIX/lib" ]; then
  498. if [ "$PLATFORM" == "macos" ]; then
  499. newname="@rpath/$libname.framework/Versions/A/$libname"
  500. else
  501. newname="@rpath/$libname.framework/$libname"
  502. fi
  503. install_name_tool -change "$g" "$newname" "$NEWFILE"
  504. fi
  505. done
  506. IFS=$OLDIFS
  507. }
  508. fixup_all () {
  509. OLDIFS=$IFS
  510. IFS=$'\n'
  511. FILES=$(find "$SYSROOT_DIR/lib" -type f -maxdepth 1 -name "*.dylib")
  512. for f in $FILES
  513. do
  514. fixup $f
  515. done
  516. IFS=$OLDIFS
  517. }
  518. remove_shared_gst_plugins () {
  519. find "$SYSROOT_DIR/lib/gstreamer-1.0" -name '*.dylib' -exec rm \{\} \;
  520. }
  521. # parse args
  522. ARCH=
  523. REBUILD=
  524. QEMU_DIR=
  525. REDOWNLOAD=
  526. PLATFORM_FAMILY_NAME=
  527. while [ "x$1" != "x" ]; do
  528. case $1 in
  529. -a )
  530. ARCH=$(echo "$2" | tr '[:upper:]' '[:lower:]')
  531. shift
  532. ;;
  533. -d | --download )
  534. REDOWNLOAD=y
  535. ;;
  536. -r | --rebuild )
  537. REBUILD=y
  538. ;;
  539. -q | --qemu )
  540. QEMU_DIR="$2"
  541. shift
  542. ;;
  543. -p )
  544. PLATFORM=$(echo "$2" | tr '[:upper:]' '[:lower:]')
  545. shift
  546. ;;
  547. * )
  548. usage
  549. ;;
  550. esac
  551. shift
  552. done
  553. if [ "x$ARCH" == "x" ]; then
  554. ARCH=arm64
  555. fi
  556. export ARCH
  557. if [ "x$PLATFORM" == "x" ]; then
  558. PLATFORM=ios
  559. fi
  560. # Export supplied CHOST or deduce by ARCH
  561. if [ -z "$CHOST" ]; then
  562. case $ARCH in
  563. armv7 | armv7s )
  564. CPU=arm
  565. ;;
  566. arm64 )
  567. CPU=aarch64
  568. ;;
  569. i386 | x86_64 )
  570. CPU=$ARCH
  571. ;;
  572. * )
  573. usage
  574. ;;
  575. esac
  576. fi
  577. CHOST=$CPU-apple-darwin
  578. export CHOST
  579. case $PLATFORM in
  580. ios* | visionos* )
  581. if [ -z "$SDKMINVER" ]; then
  582. case $PLATFORM in
  583. ios* )
  584. SDKMINVER="$IOS_SDKMINVER"
  585. ;;
  586. visionos* )
  587. SDKMINVER="$VISIONOS_SDKMINVER"
  588. ;;
  589. esac
  590. fi
  591. HVF_FLAGS="--disable-hvf"
  592. case $PLATFORM in
  593. ios_simulator* )
  594. SDK=iphonesimulator
  595. CFLAGS_MINVER="-mios-simulator-version-min=$SDKMINVER"
  596. PLATFORM_FAMILY_PREFIX="iOS_Simulator"
  597. ;;
  598. ios* )
  599. SDK=iphoneos
  600. CFLAGS_MINVER="-miphoneos-version-min=$SDKMINVER"
  601. PLATFORM_FAMILY_PREFIX="iOS"
  602. HVF_FLAGS="--enable-hvf-private"
  603. ;;
  604. visionos_simulator* )
  605. SDK=xrsimulator
  606. PLATFORM_FAMILY_PREFIX="visionOS_Simulator"
  607. ;;
  608. visionos* )
  609. SDK=xros
  610. PLATFORM_FAMILY_PREFIX="visionOS"
  611. ;;
  612. esac
  613. CFLAGS_TARGET=
  614. case $PLATFORM in
  615. *-tci )
  616. if [ "$ARCH" == "arm64" ]; then
  617. TCI_BUILD_FLAGS="--enable-tcg-threaded-interpreter --target-list=aarch64-softmmu,arm-softmmu,i386-softmmu,ppc-softmmu,ppc64-softmmu,riscv32-softmmu,riscv64-softmmu,x86_64-softmmu --extra-cflags=-Wno-unused-command-line-argument --extra-ldflags=-Wl,-no_deduplicate --extra-ldflags=-Wl,-random_uuid --extra-ldflags=-Wl,-no_compact_unwind"
  618. else
  619. TCI_BUILD_FLAGS="--enable-tcg-interpreter"
  620. fi
  621. PLATFORM_FAMILY_NAME="$PLATFORM_FAMILY_PREFIX-TCI"
  622. SKIP_USB_BUILD=1
  623. ;;
  624. * )
  625. PLATFORM_FAMILY_NAME="$PLATFORM_FAMILY_PREFIX"
  626. ;;
  627. esac
  628. QEMU_PLATFORM_BUILD_FLAGS="--disable-debug-info --enable-shared-lib --disable-cocoa --disable-coreaudio --disable-slirp-smbd --enable-ucontext --with-coroutine=libucontext $HVF_FLAGS $TCI_BUILD_FLAGS"
  629. ;;
  630. macos )
  631. if [ -z "$SDKMINVER" ]; then
  632. SDKMINVER="$MAC_SDKMINVER"
  633. fi
  634. SDK=macosx
  635. CFLAGS_MINVER="-mmacos-version-min=$SDKMINVER"
  636. CFLAGS_TARGET="-target $ARCH-apple-macos"
  637. PLATFORM_FAMILY_NAME="macOS"
  638. QEMU_PLATFORM_BUILD_FLAGS="--disable-debug-info --enable-shared-lib --disable-cocoa --cpu=$CPU"
  639. ;;
  640. * )
  641. usage
  642. ;;
  643. esac
  644. export SDK
  645. export SDKMINVER
  646. # Setup directories
  647. BASEDIR="$(dirname "$(realpath $0)")"
  648. BUILD_DIR="build-$PLATFORM_FAMILY_NAME-$ARCH"
  649. SYSROOT_DIR="sysroot-$PLATFORM_FAMILY_NAME-$ARCH"
  650. PATCHES_DIR="$BASEDIR/../patches"
  651. # Include URL list
  652. source "$PATCHES_DIR/sources"
  653. if [ -z "$QEMU_DIR" ]; then
  654. FILE="$(basename $QEMU_SRC)"
  655. QEMU_DIR="$BUILD_DIR/${FILE%.tar.*}"
  656. elif [ ! -d "$QEMU_DIR" ]; then
  657. echo "${RED}Cannot find: ${QEMU_DIR}...${NC}"
  658. exit 1
  659. else
  660. QEMU_DIR="$(realpath "$QEMU_DIR")"
  661. fi
  662. [ -d "$SYSROOT_DIR" ] || mkdir -p "$SYSROOT_DIR"
  663. PREFIX="$(realpath "$SYSROOT_DIR")"
  664. # Export supplied SDKVERSION or use system default
  665. SDKNAME=$(basename $(xcrun --sdk $SDK --show-sdk-platform-path) .platform)
  666. if [ ! -z "$SDKVERSION" ]; then
  667. SDKROOT=$(xcrun --sdk $SDK --show-sdk-platform-path)"/Developer/SDKs/$SDKNAME$SDKVERSION.sdk"
  668. else
  669. SDKVERSION=$(xcrun --sdk $SDK --show-sdk-version) # current version
  670. SDKROOT=$(xcrun --sdk $SDK --show-sdk-path) # current version
  671. fi
  672. if [ -z "$SDKMINVER" ]; then
  673. SDKMINVER="$SDKVERSION"
  674. fi
  675. # Set NCPU
  676. if [ -z "$NCPU" ] || [ $NCPU -eq 0 ]; then
  677. NCPU="$(sysctl -n hw.ncpu)"
  678. fi
  679. export NCPU
  680. # Export tools
  681. CC=$(xcrun --sdk $SDK --find gcc)
  682. CPP=$(xcrun --sdk $SDK --find gcc)" -E"
  683. CXX=$(xcrun --sdk $SDK --find g++)
  684. OBJCC=$(xcrun --sdk $SDK --find clang)
  685. LD=$(xcrun --sdk $SDK --find ld)
  686. AR=$(xcrun --sdk $SDK --find ar)
  687. NM=$(xcrun --sdk $SDK --find nm)
  688. RANLIB=$(xcrun --sdk $SDK --find ranlib)
  689. STRIP=$(xcrun --sdk $SDK --find strip)
  690. export CC
  691. export CPP
  692. export CXX
  693. export OBJCC
  694. export LD
  695. export AR
  696. export NM
  697. export RANLIB
  698. export STRIP
  699. export PREFIX
  700. # Flags
  701. CFLAGS="$CFLAGS -arch $ARCH -isysroot $SDKROOT -I$PREFIX/include -F$PREFIX/Frameworks $CFLAGS_MINVER $CFLAGS_TARGET"
  702. CPPFLAGS="$CPPFLAGS -arch $ARCH -isysroot $SDKROOT -I$PREFIX/include -F$PREFIX/Frameworks $CFLAGS_MINVER $CFLAGS_TARGET"
  703. CXXFLAGS="$CXXFLAGS -arch $ARCH -isysroot $SDKROOT -I$PREFIX/include -F$PREFIX/Frameworks $CFLAGS_MINVER $CFLAGS_TARGET"
  704. OBJCFLAGS="$OBJCFLAGS -arch $ARCH -isysroot $SDKROOT -I$PREFIX/include -F$PREFIX/Frameworks $CFLAGS_MINVER $CFLAGS_TARGET"
  705. LDFLAGS="$LDFLAGS -arch $ARCH -isysroot $SDKROOT -L$PREFIX/lib -F$PREFIX/Frameworks $CFLAGS_MINVER $CFLAGS_TARGET"
  706. export CFLAGS
  707. export CPPFLAGS
  708. export CXXFLAGS
  709. export OBJCFLAGS
  710. export LDFLAGS
  711. check_env
  712. echo "${GREEN}Starting build for ${PLATFORM_FAMILY_NAME} ${ARCH} [${NCPU} jobs]${NC}"
  713. if [ ! -f "$BUILD_DIR/BUILD_SUCCESS" ]; then
  714. if [ ! -z "$REBUILD" ]; then
  715. echo "${RED}Error, no previous successful build found.${NC}"
  716. exit 1
  717. fi
  718. fi
  719. if [ -z "$REBUILD" ]; then
  720. download_all
  721. fi
  722. echo "${GREEN}Deleting old sysroot!${NC}"
  723. rm -rf "$PREFIX/"*
  724. rm -f "$BUILD_DIR/BUILD_SUCCESS"
  725. rm -f "$BUILD_DIR/meson.cross"
  726. copy_private_headers
  727. build_pkg_config
  728. build_qemu_dependencies
  729. build $QEMU_DIR --cross-prefix="" $QEMU_PLATFORM_BUILD_FLAGS
  730. build_spice_client
  731. fixup_all
  732. # Fake Hypervisor to get iOS Simulator to build
  733. if [ "$PLATFORM" == "ios_simulator" ]; then
  734. generate_fake_hypervisor
  735. fi
  736. remove_shared_gst_plugins # another hack...
  737. echo "${GREEN}All done!${NC}"
  738. touch "$BUILD_DIR/BUILD_SUCCESS"