iosbuild.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. #!/bin/sh
  2. ##
  3. ## Copyright (c) 2014 The WebM project authors. All Rights Reserved.
  4. ##
  5. ## Use of this source code is governed by a BSD-style license
  6. ## that can be found in the LICENSE file in the root of the source
  7. ## tree. An additional intellectual property rights grant can be found
  8. ## in the file PATENTS. All contributing project authors may
  9. ## be found in the AUTHORS file in the root of the source tree.
  10. ##
  11. ##
  12. ## This script generates 'VPX.framework'. An iOS app can encode and decode VPx
  13. ## video by including 'VPX.framework'.
  14. ##
  15. ## Run iosbuild.sh to create 'VPX.framework' in the current directory.
  16. ##
  17. set -e
  18. devnull='> /dev/null 2>&1'
  19. BUILD_ROOT="_iosbuild"
  20. CONFIGURE_ARGS="--disable-docs
  21. --disable-examples
  22. --disable-libyuv
  23. --disable-unit-tests"
  24. DIST_DIR="_dist"
  25. FRAMEWORK_DIR="VPX.framework"
  26. FRAMEWORK_LIB="VPX.framework/VPX"
  27. HEADER_DIR="${FRAMEWORK_DIR}/Headers/vpx"
  28. SCRIPT_DIR=$(dirname "$0")
  29. LIBVPX_SOURCE_DIR=$(cd ${SCRIPT_DIR}/../..; pwd)
  30. LIPO=$(xcrun -sdk iphoneos${SDK} -find lipo)
  31. ORIG_PWD="$(pwd)"
  32. ARM_TARGETS="arm64-darwin-gcc
  33. armv7-darwin-gcc
  34. armv7s-darwin-gcc"
  35. SIM_TARGETS="x86-iphonesimulator-gcc
  36. x86_64-iphonesimulator-gcc"
  37. OSX_TARGETS="x86-darwin20-gcc
  38. x86_64-darwin20-gcc"
  39. TARGETS="${ARM_TARGETS} ${SIM_TARGETS}"
  40. # Configures for the target specified by $1, and invokes make with the dist
  41. # target using $DIST_DIR as the distribution output directory.
  42. build_target() {
  43. local target="$1"
  44. local old_pwd="$(pwd)"
  45. local target_specific_flags=""
  46. vlog "***Building target: ${target}***"
  47. case "${target}" in
  48. x86-*)
  49. target_specific_flags="--enable-pic"
  50. vlog "Enabled PIC for ${target}"
  51. ;;
  52. esac
  53. mkdir "${target}"
  54. cd "${target}"
  55. eval "${LIBVPX_SOURCE_DIR}/configure" --target="${target}" \
  56. ${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS} ${target_specific_flags} \
  57. ${devnull}
  58. export DIST_DIR
  59. eval make dist ${devnull}
  60. cd "${old_pwd}"
  61. vlog "***Done building target: ${target}***"
  62. }
  63. # Returns the preprocessor symbol for the target specified by $1.
  64. target_to_preproc_symbol() {
  65. target="$1"
  66. case "${target}" in
  67. arm64-*)
  68. echo "__aarch64__"
  69. ;;
  70. armv7-*)
  71. echo "__ARM_ARCH_7A__"
  72. ;;
  73. armv7s-*)
  74. echo "__ARM_ARCH_7S__"
  75. ;;
  76. x86-*)
  77. echo "__i386__"
  78. ;;
  79. x86_64-*)
  80. echo "__x86_64__"
  81. ;;
  82. *)
  83. echo "#error ${target} unknown/unsupported"
  84. return 1
  85. ;;
  86. esac
  87. }
  88. # Create a vpx_config.h shim that, based on preprocessor settings for the
  89. # current target CPU, includes the real vpx_config.h for the current target.
  90. # $1 is the list of targets.
  91. create_vpx_framework_config_shim() {
  92. local targets="$1"
  93. local config_file="${HEADER_DIR}/vpx_config.h"
  94. local preproc_symbol=""
  95. local target=""
  96. local include_guard="VPX_FRAMEWORK_HEADERS_VPX_VPX_CONFIG_H_"
  97. local file_header="/*
  98. * Copyright (c) $(date +%Y) The WebM project authors. All Rights Reserved.
  99. *
  100. * Use of this source code is governed by a BSD-style license
  101. * that can be found in the LICENSE file in the root of the source
  102. * tree. An additional intellectual property rights grant can be found
  103. * in the file PATENTS. All contributing project authors may
  104. * be found in the AUTHORS file in the root of the source tree.
  105. */
  106. /* GENERATED FILE: DO NOT EDIT! */
  107. #ifndef ${include_guard}
  108. #define ${include_guard}
  109. #if defined"
  110. printf "%s" "${file_header}" > "${config_file}"
  111. for target in ${targets}; do
  112. preproc_symbol=$(target_to_preproc_symbol "${target}")
  113. printf " ${preproc_symbol}\n" >> "${config_file}"
  114. printf "#define VPX_FRAMEWORK_TARGET \"${target}\"\n" >> "${config_file}"
  115. printf "#include \"VPX/vpx/${target}/vpx_config.h\"\n" >> "${config_file}"
  116. printf "#elif defined" >> "${config_file}"
  117. mkdir "${HEADER_DIR}/${target}"
  118. cp -p "${BUILD_ROOT}/${target}/vpx_config.h" "${HEADER_DIR}/${target}"
  119. done
  120. # Consume the last line of output from the loop: We don't want it.
  121. sed -i.bak -e '$d' "${config_file}"
  122. rm "${config_file}.bak"
  123. printf "#endif\n\n" >> "${config_file}"
  124. printf "#endif // ${include_guard}" >> "${config_file}"
  125. }
  126. # Verifies that $FRAMEWORK_LIB fat library contains requested builds.
  127. verify_framework_targets() {
  128. local requested_cpus=""
  129. local cpu=""
  130. # Extract CPU from full target name.
  131. for target; do
  132. cpu="${target%%-*}"
  133. if [ "${cpu}" = "x86" ]; then
  134. # lipo -info outputs i386 for libvpx x86 targets.
  135. cpu="i386"
  136. fi
  137. requested_cpus="${requested_cpus}${cpu} "
  138. done
  139. # Get target CPUs present in framework library.
  140. local targets_built=$(${LIPO} -info ${FRAMEWORK_LIB})
  141. # $LIPO -info outputs a string like the following:
  142. # Architectures in the fat file: $FRAMEWORK_LIB <architectures>
  143. # Capture only the architecture strings.
  144. targets_built=${targets_built##*: }
  145. # Sort CPU strings to make the next step a simple string compare.
  146. local actual=$(echo ${targets_built} | tr " " "\n" | sort | tr "\n" " ")
  147. local requested=$(echo ${requested_cpus} | tr " " "\n" | sort | tr "\n" " ")
  148. vlog "Requested ${FRAMEWORK_LIB} CPUs: ${requested}"
  149. vlog "Actual ${FRAMEWORK_LIB} CPUs: ${actual}"
  150. if [ "${requested}" != "${actual}" ]; then
  151. elog "Actual ${FRAMEWORK_LIB} targets do not match requested target list."
  152. elog " Requested target CPUs: ${requested}"
  153. elog " Actual target CPUs: ${actual}"
  154. return 1
  155. fi
  156. }
  157. # Configures and builds each target specified by $1, and then builds
  158. # VPX.framework.
  159. build_framework() {
  160. local lib_list=""
  161. local targets="$1"
  162. local target=""
  163. local target_dist_dir=""
  164. # Clean up from previous build(s).
  165. rm -rf "${BUILD_ROOT}" "${FRAMEWORK_DIR}"
  166. # Create output dirs.
  167. mkdir -p "${BUILD_ROOT}"
  168. mkdir -p "${HEADER_DIR}"
  169. cd "${BUILD_ROOT}"
  170. for target in ${targets}; do
  171. build_target "${target}"
  172. target_dist_dir="${BUILD_ROOT}/${target}/${DIST_DIR}"
  173. if [ "${ENABLE_SHARED}" = "yes" ]; then
  174. local suffix="dylib"
  175. else
  176. local suffix="a"
  177. fi
  178. lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.${suffix}"
  179. done
  180. cd "${ORIG_PWD}"
  181. # The basic libvpx API includes are all the same; just grab the most recent
  182. # set.
  183. cp -p "${target_dist_dir}"/include/vpx/* "${HEADER_DIR}"
  184. # Build the fat library.
  185. ${LIPO} -create ${lib_list} -output ${FRAMEWORK_DIR}/VPX
  186. # Create the vpx_config.h shim that allows usage of vpx_config.h from
  187. # within VPX.framework.
  188. create_vpx_framework_config_shim "${targets}"
  189. # Copy in vpx_version.h.
  190. cp -p "${BUILD_ROOT}/${target}/vpx_version.h" "${HEADER_DIR}"
  191. if [ "${ENABLE_SHARED}" = "yes" ]; then
  192. # Adjust the dylib's name so dynamic linking in apps works as expected.
  193. install_name_tool -id '@rpath/VPX.framework/VPX' ${FRAMEWORK_DIR}/VPX
  194. # Copy in Info.plist.
  195. cat "${SCRIPT_DIR}/ios-Info.plist" \
  196. | sed "s/\${FULLVERSION}/${FULLVERSION}/g" \
  197. | sed "s/\${VERSION}/${VERSION}/g" \
  198. | sed "s/\${IOS_VERSION_MIN}/${IOS_VERSION_MIN}/g" \
  199. > "${FRAMEWORK_DIR}/Info.plist"
  200. fi
  201. # Confirm VPX.framework/VPX contains the targets requested.
  202. verify_framework_targets ${targets}
  203. vlog "Created fat library ${FRAMEWORK_LIB} containing:"
  204. for lib in ${lib_list}; do
  205. vlog " $(echo ${lib} | awk -F / '{print $2, $NF}')"
  206. done
  207. }
  208. # Trap function. Cleans up the subtree used to build all targets contained in
  209. # $TARGETS.
  210. cleanup() {
  211. local res=$?
  212. cd "${ORIG_PWD}"
  213. if [ $res -ne 0 ]; then
  214. elog "build exited with error ($res)"
  215. fi
  216. if [ "${PRESERVE_BUILD_OUTPUT}" != "yes" ]; then
  217. rm -rf "${BUILD_ROOT}"
  218. fi
  219. }
  220. print_list() {
  221. local indent="$1"
  222. shift
  223. local list="$@"
  224. for entry in ${list}; do
  225. echo "${indent}${entry}"
  226. done
  227. }
  228. iosbuild_usage() {
  229. cat << EOF
  230. Usage: ${0##*/} [arguments]
  231. --help: Display this message and exit.
  232. --enable-shared: Build a dynamic framework for use on iOS 8 or later.
  233. --extra-configure-args <args>: Extra args to pass when configuring libvpx.
  234. --macosx: Uses darwin20 targets instead of iphonesimulator targets for x86
  235. and x86_64. Allows linking to framework when builds target MacOSX
  236. instead of iOS.
  237. --preserve-build-output: Do not delete the build directory.
  238. --show-build-output: Show output from each library build.
  239. --targets <targets>: Override default target list. Defaults:
  240. $(print_list " " ${TARGETS})
  241. --test-link: Confirms all targets can be linked. Functionally identical to
  242. passing --enable-examples via --extra-configure-args.
  243. --verbose: Output information about the environment and each stage of the
  244. build.
  245. EOF
  246. }
  247. elog() {
  248. echo "${0##*/} failed because: $@" 1>&2
  249. }
  250. vlog() {
  251. if [ "${VERBOSE}" = "yes" ]; then
  252. echo "$@"
  253. fi
  254. }
  255. trap cleanup EXIT
  256. # Parse the command line.
  257. while [ -n "$1" ]; do
  258. case "$1" in
  259. --extra-configure-args)
  260. EXTRA_CONFIGURE_ARGS="$2"
  261. shift
  262. ;;
  263. --help)
  264. iosbuild_usage
  265. exit
  266. ;;
  267. --enable-shared)
  268. ENABLE_SHARED=yes
  269. ;;
  270. --preserve-build-output)
  271. PRESERVE_BUILD_OUTPUT=yes
  272. ;;
  273. --show-build-output)
  274. devnull=
  275. ;;
  276. --test-link)
  277. EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --enable-examples"
  278. ;;
  279. --targets)
  280. TARGETS="$2"
  281. shift
  282. ;;
  283. --macosx)
  284. TARGETS="${ARM_TARGETS} ${OSX_TARGETS}"
  285. ;;
  286. --verbose)
  287. VERBOSE=yes
  288. ;;
  289. *)
  290. iosbuild_usage
  291. exit 1
  292. ;;
  293. esac
  294. shift
  295. done
  296. if [ "${ENABLE_SHARED}" = "yes" ]; then
  297. CONFIGURE_ARGS="--enable-shared ${CONFIGURE_ARGS}"
  298. fi
  299. FULLVERSION=$("${SCRIPT_DIR}"/version.sh --bare "${LIBVPX_SOURCE_DIR}")
  300. VERSION=$(echo "${FULLVERSION}" | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')
  301. if [ "$ENABLE_SHARED" = "yes" ]; then
  302. IOS_VERSION_OPTIONS="--enable-shared"
  303. IOS_VERSION_MIN="8.0"
  304. else
  305. IOS_VERSION_OPTIONS=""
  306. IOS_VERSION_MIN="7.0"
  307. fi
  308. if [ "${VERBOSE}" = "yes" ]; then
  309. cat << EOF
  310. BUILD_ROOT=${BUILD_ROOT}
  311. DIST_DIR=${DIST_DIR}
  312. CONFIGURE_ARGS=${CONFIGURE_ARGS}
  313. EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS}
  314. FRAMEWORK_DIR=${FRAMEWORK_DIR}
  315. FRAMEWORK_LIB=${FRAMEWORK_LIB}
  316. HEADER_DIR=${HEADER_DIR}
  317. LIBVPX_SOURCE_DIR=${LIBVPX_SOURCE_DIR}
  318. LIPO=${LIPO}
  319. MAKEFLAGS=${MAKEFLAGS}
  320. ORIG_PWD=${ORIG_PWD}
  321. PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
  322. TARGETS="$(print_list "" ${TARGETS})"
  323. ENABLE_SHARED=${ENABLE_SHARED}
  324. OSX_TARGETS="${OSX_TARGETS}"
  325. SIM_TARGETS="${SIM_TARGETS}"
  326. SCRIPT_DIR="${SCRIPT_DIR}"
  327. FULLVERSION="${FULLVERSION}"
  328. VERSION="${VERSION}"
  329. IOS_VERSION_MIN="${IOS_VERSION_MIN}"
  330. EOF
  331. fi
  332. build_framework "${TARGETS}"
  333. echo "Successfully built '${FRAMEWORK_DIR}' for:"
  334. print_list "" ${TARGETS}