build_dependencies.sh 26 KB

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