blob: ef64ab0c95b42c72f18afbcc6adba4e59ef819f3 [file] [log] [blame]
hjonbc73fe12016-03-21 11:38:26 -07001#!/bin/bash
2
3# Copyright 2015 The WebRTC 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
tkchin9eeb6242016-04-27 01:54:20 -070011# Generates static or dynamic FAT libraries for ios in out_ios_libs.
hjonbc73fe12016-03-21 11:38:26 -070012
tkchin5209d672016-04-16 12:06:33 -070013# Exit on errors.
14set -e
hjonbc73fe12016-03-21 11:38:26 -070015
tkchin5209d672016-04-16 12:06:33 -070016# Globals.
17SCRIPT_DIR=$(cd $(dirname $0) && pwd)
hjonbc73fe12016-03-21 11:38:26 -070018WEBRTC_BASE_DIR=${SCRIPT_DIR}/../../..
kjellander@webrtc.org001c20d2016-04-18 16:32:52 +020019GYP_WEBRTC_SCRIPT=${WEBRTC_BASE_DIR}/webrtc/build/gyp_webrtc.py
tkchin5209d672016-04-16 12:06:33 -070020MERGE_SCRIPT=${SCRIPT_DIR}/merge_ios_libs.py
hjonbc73fe12016-03-21 11:38:26 -070021
tkchin5209d672016-04-16 12:06:33 -070022function check_preconditions {
23 # Check for Darwin.
24 if [[ ! $(uname) = "Darwin" ]]; then
25 echo "OS/X required." >&2
26 exit 1
27 fi
hjonbc73fe12016-03-21 11:38:26 -070028
tkchin5209d672016-04-16 12:06:33 -070029 # Check for libtool.
30 if [[ -z $(which libtool) ]]; then
31 echo "Missing libtool binary." >&2
32 exit 1
hjonbc73fe12016-03-21 11:38:26 -070033 fi
tkchin5209d672016-04-16 12:06:33 -070034
35 # Check for GYP generator.
36 if [[ ! -x ${GYP_WEBRTC_SCRIPT} ]]; then
37 echo "Failed to find gyp generator." >&2
38 exit 1
hjonbc73fe12016-03-21 11:38:26 -070039 fi
tkchin5209d672016-04-16 12:06:33 -070040
tkchin5209d672016-04-16 12:06:33 -070041 # Check for merge script.
42 if [[ ! -x ${MERGE_SCRIPT} ]]; then
43 echo "Failed to find library merging script." >&2
44 exit 1
45 fi
hjonbc73fe12016-03-21 11:38:26 -070046}
47
tkchin5209d672016-04-16 12:06:33 -070048function build_webrtc {
49 local base_output_dir=$1
50 local flavor=$2
51 local target_arch=$3
tkchin9eeb6242016-04-27 01:54:20 -070052 local build_type=$4
53
tkchin5209d672016-04-16 12:06:33 -070054 local ninja_output_dir=${base_output_dir}/${target_arch}_ninja
55 local library_output_dir=${base_output_dir}/${target_arch}_libs
56 if [[ ${target_arch} = 'arm' || ${target_arch} = 'arm64' ]]; then
57 flavor="${flavor}-iphoneos"
58 else
59 flavor="${flavor}-iphonesimulator"
60 fi
tkchin9eeb6242016-04-27 01:54:20 -070061 local ninja_flavor_dir=${ninja_output_dir}/${flavor}
62
63 # Compile framework by default.
64 local gyp_file=webrtc/sdk/sdk.gyp
65 local gyp_target=rtc_sdk_framework_objc
66 # Set to 1 to explicitly not hide symbols. We'll want this if we're just
67 # generating static libs.
68 local override_visibility=0
69 if [[ ${build_type} = "legacy" ]]; then
70 echo "Building legacy."
71 gyp_file=webrtc/build/ios/merge_ios_libs.gyp
72 gyp_target=libjingle_peerconnection_objc_no_op
73 override_visibility=1
74 elif [[ ${build_type} = "static_only" ]]; then
75 echo "Building static only."
76 gyp_file=webrtc/build/ios/merge_ios_libs.gyp
77 gyp_target=rtc_sdk_peerconnection_objc_no_op
78 override_visibility=1
79 elif [[ ${build_type} == "framework" ]]; then
80 echo "Building framework."
81 else
82 echo "Unexpected build type: ${build_type}"
83 exit 1
84 fi
85
tkchin5209d672016-04-16 12:06:33 -070086 export GYP_DEFINES="OS=ios target_arch=${target_arch} use_objc_h264=1 \
tkchin9eeb6242016-04-27 01:54:20 -070087clang_xcode=1 ios_deployment_target=8.0 \
88ios_override_visibility=${override_visibility}"
tkchin5209d672016-04-16 12:06:33 -070089 export GYP_GENERATORS="ninja"
90 export GYP_GENERATOR_FLAGS="output_dir=${ninja_output_dir}"
hjonbc73fe12016-03-21 11:38:26 -070091
tkchin5209d672016-04-16 12:06:33 -070092 # GYP generation requires relative path for some reason.
93 pushd ${WEBRTC_BASE_DIR}
tkchin9eeb6242016-04-27 01:54:20 -070094 webrtc/build/gyp_webrtc.py ${gyp_file}
tkchin5209d672016-04-16 12:06:33 -070095 popd
tkchin9eeb6242016-04-27 01:54:20 -070096 # Compile the target we're interested in.
97 ninja -C ${ninja_flavor_dir} ${gyp_target}
tkchin5209d672016-04-16 12:06:33 -070098
tkchin9eeb6242016-04-27 01:54:20 -070099 if [[ ${build_type} = "framework" ]]; then
100 # Manually generate the dSYM files before stripping them. GYP does not seem
101 # to instruct ninja to generate dSYM files.
102 dsymutil --out=${ninja_flavor_dir}/WebRTC.framework.dSYM \
103 ${ninja_flavor_dir}/WebRTC.framework/WebRTC
104 fi
105
106 # Make links to the generated static archives.
107 mkdir -p ${library_output_dir}
108 for f in ${ninja_flavor_dir}/*.a
tkchin5209d672016-04-16 12:06:33 -0700109 do
110 ln -sf "${f}" "${library_output_dir}/$(basename ${f})"
111 done
112}
113
114function clean_artifacts {
115 local output_dir=$1
116 if [[ -d ${output_dir} ]]; then
117 rm -r ${output_dir}
118 fi
119}
120
121function usage {
122 echo "WebRTC iOS FAT libraries build script."
123 echo "Each architecture is compiled separately before being merged together."
124 echo "By default, the fat libraries will be created in out_ios_libs/fat_libs."
125 echo "The headers will be copied to out_ios_libs/include."
tkchin9eeb6242016-04-27 01:54:20 -0700126 echo "Usage: $0 [-h] [-b build_type] [-c] [-o output_dir]"
tkchin5209d672016-04-16 12:06:33 -0700127 echo " -h Print this help."
tkchin9eeb6242016-04-27 01:54:20 -0700128 echo " -b The build type. Can be framework, static_only or legacy."
129 echo " Defaults to framework."
tkchin5209d672016-04-16 12:06:33 -0700130 echo " -c Removes generated build output."
131 echo " -o Specifies a directory to output build artifacts to."
132 echo " If specified together with -c, deletes the dir."
tkchin9eeb6242016-04-27 01:54:20 -0700133 echo " -r Specifies a revision number to embed if building the framework."
tkchin5209d672016-04-16 12:06:33 -0700134 exit 0
135}
136
137check_preconditions
138
139# Set default arguments.
140# Output directory for build artifacts.
141OUTPUT_DIR=${WEBRTC_BASE_DIR}/out_ios_libs
tkchin9eeb6242016-04-27 01:54:20 -0700142# The type of build to perform. Valid arguments are framework, static_only and
143# legacy.
144BUILD_TYPE="framework"
tkchin5209d672016-04-16 12:06:33 -0700145PERFORM_CLEAN=0
tkchin9eeb6242016-04-27 01:54:20 -0700146FLAVOR="Profile"
147POINT_VERSION="0"
tkchin5209d672016-04-16 12:06:33 -0700148
149# Parse arguments.
tkchin9eeb6242016-04-27 01:54:20 -0700150while getopts "hb:co:r:" opt; do
tkchin5209d672016-04-16 12:06:33 -0700151 case "${opt}" in
152 h) usage;;
tkchin9eeb6242016-04-27 01:54:20 -0700153 b) BUILD_TYPE="${OPTARG}";;
tkchin5209d672016-04-16 12:06:33 -0700154 c) PERFORM_CLEAN=1;;
155 o) OUTPUT_DIR="${OPTARG}";;
tkchin9eeb6242016-04-27 01:54:20 -0700156 r) POINT_VERSION="${OPTARG}";;
tkchin5209d672016-04-16 12:06:33 -0700157 *)
158 usage
159 exit 1
160 ;;
161 esac
162done
163
164if [[ ${PERFORM_CLEAN} -ne 0 ]]; then
165 clean_artifacts ${OUTPUT_DIR}
166 exit 0
167fi
168
169# Build all the common architectures.
tkchin9eeb6242016-04-27 01:54:20 -0700170ARCHS=( "arm" "arm64" "ia32" "x64" )
171for ARCH in "${ARCHS[@]}"
tkchin5209d672016-04-16 12:06:33 -0700172do
tkchin9eeb6242016-04-27 01:54:20 -0700173 echo "Building WebRTC arch: ${ARCH}"
174 build_webrtc ${OUTPUT_DIR} ${FLAVOR} $ARCH ${BUILD_TYPE}
tkchin5209d672016-04-16 12:06:33 -0700175done
hjonbc73fe12016-03-21 11:38:26 -0700176
tkchin9eeb6242016-04-27 01:54:20 -0700177ARM_NINJA_DIR=${OUTPUT_DIR}/arm_ninja/${FLAVOR}-iphoneos
178ARM64_NINJA_DIR=${OUTPUT_DIR}/arm64_ninja/${FLAVOR}-iphoneos
179IA32_NINJA_DIR=${OUTPUT_DIR}/ia32_ninja/${FLAVOR}-iphonesimulator
180X64_NINJA_DIR=${OUTPUT_DIR}/x64_ninja/${FLAVOR}-iphonesimulator
hjonbc73fe12016-03-21 11:38:26 -0700181
tkchin9eeb6242016-04-27 01:54:20 -0700182if [[ ${BUILD_TYPE} = "framework" ]]; then
183 # Merge the framework slices together into a FAT library by copying one arch
184 # output and merging the rest in.
185 DYLIB_PATH="WebRTC.framework/WebRTC"
186 cp -R ${ARM_NINJA_DIR}/WebRTC.framework ${OUTPUT_DIR}
187 rm ${OUTPUT_DIR}/${DYLIB_PATH}
188 echo "Merging framework slices."
189 lipo ${ARM_NINJA_DIR}/${DYLIB_PATH} \
190 ${ARM64_NINJA_DIR}/${DYLIB_PATH} \
191 ${IA32_NINJA_DIR}/${DYLIB_PATH} \
192 ${X64_NINJA_DIR}/${DYLIB_PATH} \
193 -create -output ${OUTPUT_DIR}/${DYLIB_PATH}
194
195 # Merge the dSYM files together in a similar fashion.
196 DSYM_PATH="WebRTC.framework.dSYM/Contents/Resources/DWARF/WebRTC"
197 cp -R ${ARM_NINJA_DIR}/WebRTC.framework.dSYM ${OUTPUT_DIR}
198 rm ${OUTPUT_DIR}/${DSYM_PATH}
199 echo "Merging dSYM slices."
200 lipo ${ARM_NINJA_DIR}/${DSYM_PATH} \
201 ${ARM64_NINJA_DIR}/${DSYM_PATH} \
202 ${IA32_NINJA_DIR}/${DSYM_PATH} \
203 ${X64_NINJA_DIR}/${DSYM_PATH} \
204 -create -output ${OUTPUT_DIR}/${DSYM_PATH}
205
206 # Strip the dynamic framework of non-global symbols.
207 # TODO(tkchin): Override chromium strip settings in supplement.gypi instead.
208 echo "Stripping non-global symbols."
209 strip -x ${OUTPUT_DIR}/${DYLIB_PATH}
210
211 # Modify the version number.
212 INFOPLIST_PATH=${OUTPUT_DIR}/WebRTC.framework/Resources/Info.plist
213 MAJOR_MINOR=$(plistbuddy -c "Print :CFBundleShortVersionString" \
214 ${INFOPLIST_PATH})
215 VERSION_NUMBER="${MAJOR_MINOR}.${POINT_VERSION}"
216 echo "Substituting revision number: ${VERSION_NUMBER}"
217 plistbuddy -c "Set :CFBundleVersion ${VERSION_NUMBER}" ${INFOPLIST_PATH}
218 plutil -convert binary1 ${INFOPLIST_PATH}
219
220 # Copy pod file.
221 FORMAT_STRING=s/\${FRAMEWORK_VERSION_NUMBER}/${VERSION_NUMBER}/g
222 sed -e ${FORMAT_STRING} ${WEBRTC_BASE_DIR}/webrtc/sdk/objc/WebRTC.podspec > \
223 ${OUTPUT_DIR}/WebRTC.podspec
224else
225 echo "Merging static library slices."
226 # Merge the static libraries together into individual FAT archives.
227 ${MERGE_SCRIPT} ${OUTPUT_DIR}
228
229 # Merge the dSYM files together.
230 TARGET_NAME="rtc_sdk_peerconnection_objc_no_op"
231 if [[ ${BUILD_TYPE} = "legacy" ]]; then
232 TARGET_NAME="libjingle_peerconnection_objc_no_op"
233 fi
234 DSYM_PATH="${TARGET_NAME}.app.dSYM/Contents/Resources/DWARF/${TARGET_NAME}"
235 cp -R ${ARM_NINJA_DIR}/${TARGET_NAME}.app.dSYM ${OUTPUT_DIR}
236 echo "Merging dSYM slices."
237 lipo ${ARM_NINJA_DIR}/${DSYM_PATH} \
238 ${ARM64_NINJA_DIR}/${DSYM_PATH} \
239 ${IA32_NINJA_DIR}/${DSYM_PATH} \
240 ${X64_NINJA_DIR}/${DSYM_PATH} \
241 -create -output ${OUTPUT_DIR}/${DSYM_PATH}
242
243 # Strip debugging symbols.
244 # TODO(tkchin): Override chromium settings in supplement.gypi instead to do
245 # stripping at build time.
246 echo "Stripping debug symbols."
247 strip -S ${OUTPUT_DIR}/fat_libs/*.a
248
249 # Symlink the headers.
250 echo "Symlinking headers."
251 INPUT_HEADER_DIR="${WEBRTC_BASE_DIR}/webrtc/sdk/objc/Framework/Headers/WebRTC"
252 OUTPUT_HEADER_DIR="${OUTPUT_DIR}/include"
253 if [[ -d ${OUTPUT_HEADER_DIR} ]]; then
254 rm -rf ${OUTPUT_HEADER_DIR}
255 fi
256 if [[ ${BUILD_TYPE} = "legacy" ]]; then
257 INPUT_HEADER_DIR="${WEBRTC_BASE_DIR}/talk/app/webrtc/objc/public"
258 ln -sf ${INPUT_HEADER_DIR} ${OUTPUT_HEADER_DIR}
259 else
260 mkdir -p ${OUTPUT_HEADER_DIR}
261 ln -sf ${INPUT_HEADER_DIR} ${OUTPUT_HEADER_DIR}/WebRTC
262 fi
263fi
264
265echo "Done!"