| #!/bin/bash |
| |
| # Copyright 2015 The WebRTC project authors. All Rights Reserved. |
| # |
| # Use of this source code is governed by a BSD-style license |
| # that can be found in the LICENSE file in the root of the source |
| # tree. An additional intellectual property rights grant can be found |
| # in the file PATENTS. All contributing project authors may |
| # be found in the AUTHORS file in the root of the source tree. |
| |
| # Generates static or dynamic FAT libraries for ios in out_ios_libs. |
| |
| # Exit on errors. |
| set -e |
| |
| # Environment |
| export PATH=/usr/libexec:$PATH |
| |
| # Globals. |
| SCRIPT_DIR=$(cd $(dirname $0) && pwd) |
| WEBRTC_BASE_DIR=${SCRIPT_DIR}/../../.. |
| GYP_WEBRTC_SCRIPT=${WEBRTC_BASE_DIR}/webrtc/build/gyp_webrtc.py |
| MERGE_SCRIPT=${SCRIPT_DIR}/merge_ios_libs.py |
| LICENSE_SCRIPT=${SCRIPT_DIR}/generate_licenses.py |
| |
| function check_preconditions { |
| # Check for Darwin. |
| if [[ ! $(uname) = "Darwin" ]]; then |
| echo "OS/X required." >&2 |
| exit 1 |
| fi |
| |
| # Check for libtool. |
| if [[ -z $(which libtool) ]]; then |
| echo "Missing libtool binary." >&2 |
| exit 1 |
| fi |
| |
| # Check for GYP generator. |
| if [[ ! -x ${GYP_WEBRTC_SCRIPT} ]]; then |
| echo "Failed to find gyp generator." >&2 |
| exit 1 |
| fi |
| |
| # Check for merge script. |
| if [[ ! -x ${MERGE_SCRIPT} ]]; then |
| echo "Failed to find library merging script." >&2 |
| exit 1 |
| fi |
| } |
| |
| function build_webrtc { |
| local base_output_dir=$1 |
| local flavor=$2 |
| local target_arch=$3 |
| local build_type=$4 |
| local libvpx_build_vp9=$5 |
| |
| local ninja_output_dir=${base_output_dir}/${target_arch}_ninja |
| local library_output_dir=${base_output_dir}/${target_arch}_libs |
| if [[ ${target_arch} = 'arm' || ${target_arch} = 'arm64' ]]; then |
| flavor="${flavor}-iphoneos" |
| else |
| flavor="${flavor}-iphonesimulator" |
| fi |
| local ninja_flavor_dir=${ninja_output_dir}/${flavor} |
| |
| # Compile framework by default. |
| local gyp_file=webrtc/sdk/sdk.gyp |
| local gyp_target=rtc_sdk_framework_objc |
| # Set to 1 to explicitly not hide symbols. We'll want this if we're just |
| # generating static libs. |
| local override_visibility=0 |
| if [[ ${build_type} = "legacy" ]]; then |
| echo "Building objc legacy libraries no longer supported." |
| exit 1 |
| elif [[ ${build_type} = "static_only" ]]; then |
| echo "Building static only." |
| gyp_file=webrtc/build/ios/merge_ios_libs.gyp |
| gyp_target=rtc_sdk_peerconnection_objc_no_op |
| override_visibility=1 |
| elif [[ ${build_type} == "framework" ]]; then |
| echo "Building framework." |
| else |
| echo "Unexpected build type: ${build_type}" |
| exit 1 |
| fi |
| |
| export GYP_DEFINES="OS=ios target_arch=${target_arch} use_objc_h264=1 \ |
| clang_xcode=1 ios_deployment_target=8.0 \ |
| ios_override_visibility=${override_visibility} \ |
| libvpx_build_vp9=${libvpx_build_vp9}" |
| export GYP_GENERATORS="ninja" |
| export GYP_GENERATOR_FLAGS="output_dir=${ninja_output_dir}" |
| |
| # GYP generation requires relative path for some reason. |
| pushd ${WEBRTC_BASE_DIR} |
| webrtc/build/gyp_webrtc.py ${gyp_file} |
| popd |
| # Compile the target we're interested in. |
| ninja -C ${ninja_flavor_dir} ${gyp_target} |
| |
| if [[ ${build_type} = "framework" ]]; then |
| # Manually generate the dSYM files before stripping them. GYP does not seem |
| # to instruct ninja to generate dSYM files. |
| dsymutil --out=${ninja_flavor_dir}/WebRTC.framework.dSYM \ |
| ${ninja_flavor_dir}/WebRTC.framework/WebRTC |
| fi |
| |
| # Make links to the generated static archives. |
| mkdir -p ${library_output_dir} |
| for f in ${ninja_flavor_dir}/*.a |
| do |
| ln -sf "${f}" "${library_output_dir}/$(basename ${f})" |
| done |
| } |
| |
| function clean_artifacts { |
| local output_dir=$1 |
| if [[ -d ${output_dir} ]]; then |
| rm -r ${output_dir} |
| fi |
| } |
| |
| function usage { |
| echo "WebRTC iOS FAT libraries build script." |
| echo "Each architecture is compiled separately before being merged together." |
| echo "By default, the fat libraries will be created in out_ios_libs/fat_libs." |
| echo "The headers will be copied to out_ios_libs/include." |
| echo "Usage: $0 [-h] [-b build_type] [-c] [-o output_dir]" |
| echo " -h Print this help." |
| echo " -b The build type. Can be framework or static_only." |
| echo " Defaults to framework." |
| echo " -c Removes generated build output." |
| echo " -o Specifies a directory to output build artifacts to." |
| echo " If specified together with -c, deletes the dir." |
| echo " -r Specifies a revision number to embed if building the framework." |
| exit 0 |
| } |
| |
| check_preconditions |
| |
| # Set default arguments. |
| # Output directory for build artifacts. |
| OUTPUT_DIR=${WEBRTC_BASE_DIR}/out_ios_libs |
| # The type of build to perform. Valid arguments are framework and static_only. |
| BUILD_TYPE="framework" |
| PERFORM_CLEAN=0 |
| FLAVOR="Profile" |
| POINT_VERSION="0" |
| # TODO(tkchin): Add ability to pass in a flag to build vp9. Odds are mobile |
| # clients will not want it though because of the higher CPU usage. |
| LIBVPX_BUILD_VP9=0 |
| |
| # Parse arguments. |
| while getopts "hb:co:r:" opt; do |
| case "${opt}" in |
| h) usage;; |
| b) BUILD_TYPE="${OPTARG}";; |
| c) PERFORM_CLEAN=1;; |
| o) OUTPUT_DIR="${OPTARG}";; |
| r) POINT_VERSION="${OPTARG}";; |
| *) |
| usage |
| exit 1 |
| ;; |
| esac |
| done |
| |
| if [[ ${PERFORM_CLEAN} -ne 0 ]]; then |
| clean_artifacts ${OUTPUT_DIR} |
| exit 0 |
| fi |
| |
| # Build all the common architectures. |
| ARCHS=( "arm" "arm64" "ia32" "x64" ) |
| for ARCH in "${ARCHS[@]}" |
| do |
| echo "Building WebRTC arch: ${ARCH}" |
| build_webrtc ${OUTPUT_DIR} ${FLAVOR} $ARCH ${BUILD_TYPE} ${LIBVPX_BUILD_VP9} |
| done |
| |
| ARM_NINJA_DIR=${OUTPUT_DIR}/arm_ninja/${FLAVOR}-iphoneos |
| ARM64_NINJA_DIR=${OUTPUT_DIR}/arm64_ninja/${FLAVOR}-iphoneos |
| IA32_NINJA_DIR=${OUTPUT_DIR}/ia32_ninja/${FLAVOR}-iphonesimulator |
| X64_NINJA_DIR=${OUTPUT_DIR}/x64_ninja/${FLAVOR}-iphonesimulator |
| |
| if [[ ${BUILD_TYPE} = "framework" ]]; then |
| # Merge the framework slices together into a FAT library by copying one arch |
| # output and merging the rest in. |
| DYLIB_PATH="WebRTC.framework/WebRTC" |
| cp -R ${ARM_NINJA_DIR}/WebRTC.framework ${OUTPUT_DIR} |
| rm ${OUTPUT_DIR}/${DYLIB_PATH} |
| echo "Merging framework slices." |
| lipo ${ARM_NINJA_DIR}/${DYLIB_PATH} \ |
| ${ARM64_NINJA_DIR}/${DYLIB_PATH} \ |
| ${IA32_NINJA_DIR}/${DYLIB_PATH} \ |
| ${X64_NINJA_DIR}/${DYLIB_PATH} \ |
| -create -output ${OUTPUT_DIR}/${DYLIB_PATH} |
| |
| # Merge the dSYM files together in a similar fashion. |
| DSYM_PATH="WebRTC.framework.dSYM/Contents/Resources/DWARF/WebRTC" |
| cp -R ${ARM_NINJA_DIR}/WebRTC.framework.dSYM ${OUTPUT_DIR} |
| rm ${OUTPUT_DIR}/${DSYM_PATH} |
| echo "Merging dSYM slices." |
| lipo ${ARM_NINJA_DIR}/${DSYM_PATH} \ |
| ${ARM64_NINJA_DIR}/${DSYM_PATH} \ |
| ${IA32_NINJA_DIR}/${DSYM_PATH} \ |
| ${X64_NINJA_DIR}/${DSYM_PATH} \ |
| -create -output ${OUTPUT_DIR}/${DSYM_PATH} |
| |
| # Strip the dynamic framework of non-global symbols. |
| # TODO(tkchin): Override chromium strip settings in supplement.gypi instead. |
| echo "Stripping non-global symbols." |
| strip -x ${OUTPUT_DIR}/${DYLIB_PATH} |
| |
| # Modify the version number. |
| INFOPLIST_PATH=${OUTPUT_DIR}/WebRTC.framework/Info.plist |
| MAJOR_MINOR=$(PlistBuddy -c "Print :CFBundleShortVersionString" \ |
| ${INFOPLIST_PATH}) |
| VERSION_NUMBER="${MAJOR_MINOR}.${POINT_VERSION}" |
| echo "Substituting revision number: ${VERSION_NUMBER}" |
| PlistBuddy -c "Set :CFBundleVersion ${VERSION_NUMBER}" ${INFOPLIST_PATH} |
| plutil -convert binary1 ${INFOPLIST_PATH} |
| |
| # Copy pod file. |
| FORMAT_STRING=s/\${FRAMEWORK_VERSION_NUMBER}/${VERSION_NUMBER}/g |
| sed -e ${FORMAT_STRING} ${WEBRTC_BASE_DIR}/webrtc/sdk/objc/WebRTC.podspec > \ |
| ${OUTPUT_DIR}/WebRTC.podspec |
| elif [[ ${BUILD_TYPE} = "static_only" ]]; then |
| echo "Merging static library slices." |
| # Merge the static libraries together into individual FAT archives. |
| ${MERGE_SCRIPT} ${OUTPUT_DIR} |
| |
| # Merge the dSYM files together. |
| TARGET_NAME="rtc_sdk_peerconnection_objc_no_op" |
| DSYM_PATH="${TARGET_NAME}.app.dSYM/Contents/Resources/DWARF/${TARGET_NAME}" |
| cp -R ${ARM_NINJA_DIR}/${TARGET_NAME}.app.dSYM ${OUTPUT_DIR} |
| echo "Merging dSYM slices." |
| lipo ${ARM_NINJA_DIR}/${DSYM_PATH} \ |
| ${ARM64_NINJA_DIR}/${DSYM_PATH} \ |
| ${IA32_NINJA_DIR}/${DSYM_PATH} \ |
| ${X64_NINJA_DIR}/${DSYM_PATH} \ |
| -create -output ${OUTPUT_DIR}/${DSYM_PATH} |
| |
| # Strip debugging symbols. |
| # TODO(tkchin): Override chromium settings in supplement.gypi instead to do |
| # stripping at build time. |
| echo "Stripping debug symbols." |
| strip -S ${OUTPUT_DIR}/fat_libs/*.a |
| |
| # Symlink the headers. |
| echo "Symlinking headers." |
| INPUT_HEADER_DIR="${WEBRTC_BASE_DIR}/webrtc/sdk/objc/Framework/Headers/WebRTC" |
| OUTPUT_HEADER_DIR="${OUTPUT_DIR}/include" |
| if [[ -d ${OUTPUT_HEADER_DIR} ]]; then |
| rm -rf ${OUTPUT_HEADER_DIR} |
| fi |
| mkdir -p ${OUTPUT_HEADER_DIR} |
| ln -sf ${INPUT_HEADER_DIR} ${OUTPUT_HEADER_DIR}/WebRTC |
| else |
| echo "BUILD_TYPE ${BUILD_TYPE} not supported." |
| exit 1 |
| fi |
| |
| echo "Generating LICENSE.html." |
| ${LICENSE_SCRIPT} ${OUTPUT_DIR}/arm64_libs ${OUTPUT_DIR} |
| |
| echo "Done!" |