iosbuild.sh 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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-darwin16-gcc
  38. x86_64-darwin16-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 '' -e '$d' "${config_file}"
  122. printf "#endif\n\n" >> "${config_file}"
  123. printf "#endif // ${include_guard}" >> "${config_file}"
  124. }
  125. # Verifies that $FRAMEWORK_LIB fat library contains requested builds.
  126. verify_framework_targets() {
  127. local requested_cpus=""
  128. local cpu=""
  129. # Extract CPU from full target name.
  130. for target; do
  131. cpu="${target%%-*}"
  132. if [ "${cpu}" = "x86" ]; then
  133. # lipo -info outputs i386 for libvpx x86 targets.
  134. cpu="i386"
  135. fi
  136. requested_cpus="${requested_cpus}${cpu} "
  137. done
  138. # Get target CPUs present in framework library.
  139. local targets_built=$(${LIPO} -info ${FRAMEWORK_LIB})
  140. # $LIPO -info outputs a string like the following:
  141. # Architectures in the fat file: $FRAMEWORK_LIB <architectures>
  142. # Capture only the architecture strings.
  143. targets_built=${targets_built##*: }
  144. # Sort CPU strings to make the next step a simple string compare.
  145. local actual=$(echo ${targets_built} | tr " " "\n" | sort | tr "\n" " ")
  146. local requested=$(echo ${requested_cpus} | tr " " "\n" | sort | tr "\n" " ")
  147. vlog "Requested ${FRAMEWORK_LIB} CPUs: ${requested}"
  148. vlog "Actual ${FRAMEWORK_LIB} CPUs: ${actual}"
  149. if [ "${requested}" != "${actual}" ]; then
  150. elog "Actual ${FRAMEWORK_LIB} targets do not match requested target list."
  151. elog " Requested target CPUs: ${requested}"
  152. elog " Actual target CPUs: ${actual}"
  153. return 1
  154. fi
  155. }
  156. # Configures and builds each target specified by $1, and then builds
  157. # VPX.framework.
  158. build_framework() {
  159. local lib_list=""
  160. local targets="$1"
  161. local target=""
  162. local target_dist_dir=""
  163. # Clean up from previous build(s).
  164. rm -rf "${BUILD_ROOT}" "${FRAMEWORK_DIR}"
  165. # Create output dirs.
  166. mkdir -p "${BUILD_ROOT}"
  167. mkdir -p "${HEADER_DIR}"
  168. cd "${BUILD_ROOT}"
  169. for target in ${targets}; do
  170. build_target "${target}"
  171. target_dist_dir="${BUILD_ROOT}/${target}/${DIST_DIR}"
  172. if [ "${ENABLE_SHARED}" = "yes" ]; then
  173. local suffix="dylib"
  174. else
  175. local suffix="a"
  176. fi
  177. lib_list="${lib_list} ${target_dist_dir}/lib/libvpx.${suffix}"
  178. done
  179. cd "${ORIG_PWD}"
  180. # The basic libvpx API includes are all the same; just grab the most recent
  181. # set.
  182. cp -p "${target_dist_dir}"/include/vpx/* "${HEADER_DIR}"
  183. # Build the fat library.
  184. ${LIPO} -create ${lib_list} -output ${FRAMEWORK_DIR}/VPX
  185. # Create the vpx_config.h shim that allows usage of vpx_config.h from
  186. # within VPX.framework.
  187. create_vpx_framework_config_shim "${targets}"
  188. # Copy in vpx_version.h.
  189. cp -p "${BUILD_ROOT}/${target}/vpx_version.h" "${HEADER_DIR}"
  190. if [ "${ENABLE_SHARED}" = "yes" ]; then
  191. # Adjust the dylib's name so dynamic linking in apps works as expected.
  192. install_name_tool -id '@rpath/VPX.framework/VPX' ${FRAMEWORK_DIR}/VPX
  193. # Copy in Info.plist.
  194. cat "${SCRIPT_DIR}/ios-Info.plist" \
  195. | sed "s/\${FULLVERSION}/${FULLVERSION}/g" \
  196. | sed "s/\${VERSION}/${VERSION}/g" \
  197. | sed "s/\${IOS_VERSION_MIN}/${IOS_VERSION_MIN}/g" \
  198. > "${FRAMEWORK_DIR}/Info.plist"
  199. fi
  200. # Confirm VPX.framework/VPX contains the targets requested.
  201. verify_framework_targets ${targets}
  202. vlog "Created fat library ${FRAMEWORK_LIB} containing:"
  203. for lib in ${lib_list}; do
  204. vlog " $(echo ${lib} | awk -F / '{print $2, $NF}')"
  205. done
  206. }
  207. # Trap function. Cleans up the subtree used to build all targets contained in
  208. # $TARGETS.
  209. cleanup() {
  210. local readonly res=$?
  211. cd "${ORIG_PWD}"
  212. if [ $res -ne 0 ]; then
  213. elog "build exited with error ($res)"
  214. fi
  215. if [ "${PRESERVE_BUILD_OUTPUT}" != "yes" ]; then
  216. rm -rf "${BUILD_ROOT}"
  217. fi
  218. }
  219. print_list() {
  220. local indent="$1"
  221. shift
  222. local list="$@"
  223. for entry in ${list}; do
  224. echo "${indent}${entry}"
  225. done
  226. }
  227. iosbuild_usage() {
  228. cat << EOF
  229. Usage: ${0##*/} [arguments]
  230. --help: Display this message and exit.
  231. --enable-shared: Build a dynamic framework for use on iOS 8 or later.
  232. --extra-configure-args <args>: Extra args to pass when configuring libvpx.
  233. --macosx: Uses darwin16 targets instead of iphonesimulator targets for x86
  234. and x86_64. Allows linking to framework when builds target MacOSX
  235. instead of iOS.
  236. --preserve-build-output: Do not delete the build directory.
  237. --show-build-output: Show output from each library build.
  238. --targets <targets>: Override default target list. Defaults:
  239. $(print_list " " ${TARGETS})
  240. --test-link: Confirms all targets can be linked. Functionally identical to
  241. passing --enable-examples via --extra-configure-args.
  242. --verbose: Output information about the environment and each stage of the
  243. build.
  244. EOF
  245. }
  246. elog() {
  247. echo "${0##*/} failed because: $@" 1>&2
  248. }
  249. vlog() {
  250. if [ "${VERBOSE}" = "yes" ]; then
  251. echo "$@"
  252. fi
  253. }
  254. trap cleanup EXIT
  255. # Parse the command line.
  256. while [ -n "$1" ]; do
  257. case "$1" in
  258. --extra-configure-args)
  259. EXTRA_CONFIGURE_ARGS="$2"
  260. shift
  261. ;;
  262. --help)
  263. iosbuild_usage
  264. exit
  265. ;;
  266. --enable-shared)
  267. ENABLE_SHARED=yes
  268. ;;
  269. --preserve-build-output)
  270. PRESERVE_BUILD_OUTPUT=yes
  271. ;;
  272. --show-build-output)
  273. devnull=
  274. ;;
  275. --test-link)
  276. EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --enable-examples"
  277. ;;
  278. --targets)
  279. TARGETS="$2"
  280. shift
  281. ;;
  282. --macosx)
  283. TARGETS="${ARM_TARGETS} ${OSX_TARGETS}"
  284. ;;
  285. --verbose)
  286. VERBOSE=yes
  287. ;;
  288. *)
  289. iosbuild_usage
  290. exit 1
  291. ;;
  292. esac
  293. shift
  294. done
  295. if [ "${ENABLE_SHARED}" = "yes" ]; then
  296. CONFIGURE_ARGS="--enable-shared ${CONFIGURE_ARGS}"
  297. fi
  298. FULLVERSION=$("${SCRIPT_DIR}"/version.sh --bare "${LIBVPX_SOURCE_DIR}")
  299. VERSION=$(echo "${FULLVERSION}" | sed -E 's/^v([0-9]+\.[0-9]+\.[0-9]+).*$/\1/')
  300. if [ "$ENABLE_SHARED" = "yes" ]; then
  301. IOS_VERSION_OPTIONS="--enable-shared"
  302. IOS_VERSION_MIN="8.0"
  303. else
  304. IOS_VERSION_OPTIONS=""
  305. IOS_VERSION_MIN="6.0"
  306. fi
  307. if [ "${VERBOSE}" = "yes" ]; then
  308. cat << EOF
  309. BUILD_ROOT=${BUILD_ROOT}
  310. DIST_DIR=${DIST_DIR}
  311. CONFIGURE_ARGS=${CONFIGURE_ARGS}
  312. EXTRA_CONFIGURE_ARGS=${EXTRA_CONFIGURE_ARGS}
  313. FRAMEWORK_DIR=${FRAMEWORK_DIR}
  314. FRAMEWORK_LIB=${FRAMEWORK_LIB}
  315. HEADER_DIR=${HEADER_DIR}
  316. LIBVPX_SOURCE_DIR=${LIBVPX_SOURCE_DIR}
  317. LIPO=${LIPO}
  318. MAKEFLAGS=${MAKEFLAGS}
  319. ORIG_PWD=${ORIG_PWD}
  320. PRESERVE_BUILD_OUTPUT=${PRESERVE_BUILD_OUTPUT}
  321. TARGETS="$(print_list "" ${TARGETS})"
  322. ENABLE_SHARED=${ENABLE_SHARED}
  323. OSX_TARGETS="${OSX_TARGETS}"
  324. SIM_TARGETS="${SIM_TARGETS}"
  325. SCRIPT_DIR="${SCRIPT_DIR}"
  326. FULLVERSION="${FULLVERSION}"
  327. VERSION="${VERSION}"
  328. IOS_VERSION_MIN="${IOS_VERSION_MIN}"
  329. EOF
  330. fi
  331. build_framework "${TARGETS}"
  332. echo "Successfully built '${FRAMEWORK_DIR}' for:"
  333. print_list "" ${TARGETS}