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.

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