#!/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 # 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 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 legacy." gyp_file=webrtc/build/ios/merge_ios_libs.gyp gyp_target=libjingle_peerconnection_objc_no_op override_visibility=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}" 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, static_only or legacy." 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, static_only and # legacy. BUILD_TYPE="framework" PERFORM_CLEAN=0 FLAVOR="Profile" POINT_VERSION="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} 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 else 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" if [[ ${BUILD_TYPE} = "legacy" ]]; then TARGET_NAME="libjingle_peerconnection_objc_no_op" fi 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 if [[ ${BUILD_TYPE} = "legacy" ]]; then INPUT_HEADER_DIR="${WEBRTC_BASE_DIR}/talk/app/webrtc/objc/public" ln -sf ${INPUT_HEADER_DIR} ${OUTPUT_HEADER_DIR} else mkdir -p ${OUTPUT_HEADER_DIR} ln -sf ${INPUT_HEADER_DIR} ${OUTPUT_HEADER_DIR}/WebRTC fi fi echo "Generating LICENSE.html." ${LICENSE_SCRIPT} ${OUTPUT_DIR}/arm64_libs ${OUTPUT_DIR} echo "Done!"