From 5fa51e29479ed584a8879363240863152294abd1 Mon Sep 17 00:00:00 2001 From: tkchin Date: Wed, 5 Oct 2016 13:16:03 -0700 Subject: [PATCH] Add iOS static library GN build script. NOTRY=True BUG=webrtc:6372 Review-Url: https://codereview.webrtc.org/2391123002 Cr-Commit-Position: refs/heads/master@{#14532} --- webrtc/build/ios/build_ios_libs.sh | 276 ++---------------- .../audio_device/ios/objc/RTCAudioSession.h | 4 + .../ios/objc/RTCAudioSessionConfiguration.h | 3 + .../objc/Framework/Classes/RTCVideoTrack.mm | 4 +- 4 files changed, 41 insertions(+), 246 deletions(-) diff --git a/webrtc/build/ios/build_ios_libs.sh b/webrtc/build/ios/build_ios_libs.sh index 9797b8dd2c..a50140e335 100755 --- a/webrtc/build/ios/build_ios_libs.sh +++ b/webrtc/build/ios/build_ios_libs.sh @@ -8,262 +8,50 @@ # 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. +# Generates static 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 +SDK_OUTPUT_DIR=${WEBRTC_BASE_DIR}/out_ios_libs +SDK_LIB_NAME="librtc_sdk_objc.a" +GN_BASE_ARGS="target_os=\"ios\" is_debug=false ios_enable_code_signing=false \ +rtc_libvpx_build_vp9=false" +GN_STATIC_TARGET_NAMES="rtc_sdk_peerconnection_objc field_trial_default \ +metrics_default" - # Check for libtool. - if [[ -z $(which libtool) ]]; then - echo "Missing libtool binary." >&2 - exit 1 - fi +# TODO(tkchin): Restore functionality of old script to build dynamic framework, +# symbols and license file. - # Check for GYP generator. - if [[ ! -x ${GYP_WEBRTC_SCRIPT} ]]; then - echo "Failed to find gyp generator." >&2 - exit 1 - fi +function build_static_webrtc { + local arch=$1 + local xcode_arch=$2 - # Check for merge script. - if [[ ! -x ${MERGE_SCRIPT} ]]; then - echo "Failed to find library merging script." >&2 - exit 1 - fi + OUTPUT_DIR=${SDK_OUTPUT_DIR}/${arch}_libs + OUTPUT_LIB=${OUTPUT_DIR}/${SDK_LIB_NAME} + GN_ARGS="${GN_BASE_ARGS} target_cpu=\"${arch}\"" + gn gen ${OUTPUT_DIR} --args="${GN_ARGS}" + ninja -C ${OUTPUT_DIR} ${GN_STATIC_TARGET_NAMES} + # Combine the object files together into a single archive and strip debug + # symbols. + find ${OUTPUT_DIR}/obj -type f -name "*.o" | + xargs ld -r -static -S -all_load -arch ${xcode_arch} -o ${OUTPUT_LIB} } -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} \ -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 +build_static_webrtc "arm" "armv7" +build_static_webrtc "arm64" "arm64" +build_static_webrtc "x86" "i386" +build_static_webrtc "x64" "x86_64" -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 +# Combine the libraries. +lipo ${SDK_OUTPUT_DIR}/arm_libs/${SDK_LIB_NAME} \ + ${SDK_OUTPUT_DIR}/arm64_libs/${SDK_LIB_NAME} \ + ${SDK_OUTPUT_DIR}/x86_libs/${SDK_LIB_NAME} \ + ${SDK_OUTPUT_DIR}/x64_libs/${SDK_LIB_NAME} \ + -create -output ${SDK_OUTPUT_DIR}/${SDK_LIB_NAME} -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!" +echo "Done." diff --git a/webrtc/modules/audio_device/ios/objc/RTCAudioSession.h b/webrtc/modules/audio_device/ios/objc/RTCAudioSession.h index 274cc2bc97..ef5cec4600 100644 --- a/webrtc/modules/audio_device/ios/objc/RTCAudioSession.h +++ b/webrtc/modules/audio_device/ios/objc/RTCAudioSession.h @@ -11,6 +11,8 @@ #import #import +#import "WebRTC/RTCMacros.h" + NS_ASSUME_NONNULL_BEGIN extern NSString * const kRTCAudioSessionErrorDomain; @@ -25,6 +27,7 @@ extern NSInteger const kRTCAudioSessionErrorConfiguration; // Surfaces AVAudioSession events. WebRTC will listen directly for notifications // from AVAudioSession and handle them before calling these delegate methods, // at which point applications can perform additional processing if required. +RTC_EXPORT @protocol RTCAudioSessionDelegate @optional @@ -80,6 +83,7 @@ extern NSInteger const kRTCAudioSessionErrorConfiguration; * RTCAudioSession also coordinates activation so that the audio session is * activated only once. See |setActive:error:|. */ +RTC_EXPORT @interface RTCAudioSession : NSObject /** Convenience property to access the AVAudioSession singleton. Callers should diff --git a/webrtc/modules/audio_device/ios/objc/RTCAudioSessionConfiguration.h b/webrtc/modules/audio_device/ios/objc/RTCAudioSessionConfiguration.h index 7832a82d4f..6a02751d29 100644 --- a/webrtc/modules/audio_device/ios/objc/RTCAudioSessionConfiguration.h +++ b/webrtc/modules/audio_device/ios/objc/RTCAudioSessionConfiguration.h @@ -11,6 +11,8 @@ #import #import +#import "WebRTC/RTCMacros.h" + NS_ASSUME_NONNULL_BEGIN extern const int kRTCAudioSessionPreferredNumberOfChannels; @@ -20,6 +22,7 @@ extern const double kRTCAudioSessionHighPerformanceIOBufferDuration; extern const double kRTCAudioSessionLowComplexityIOBufferDuration; // Struct to hold configuration values. +RTC_EXPORT @interface RTCAudioSessionConfiguration : NSObject @property(nonatomic, strong) NSString *category; diff --git a/webrtc/sdk/objc/Framework/Classes/RTCVideoTrack.mm b/webrtc/sdk/objc/Framework/Classes/RTCVideoTrack.mm index 6691375fbf..9fa6111411 100644 --- a/webrtc/sdk/objc/Framework/Classes/RTCVideoTrack.mm +++ b/webrtc/sdk/objc/Framework/Classes/RTCVideoTrack.mm @@ -69,9 +69,9 @@ - (void)addRenderer:(id)renderer { // Make sure we don't have this renderer yet. for (RTCVideoRendererAdapter *adapter in _adapters) { - // Getting around unused variable error - if (adapter.videoRenderer != renderer) { + if (adapter.videoRenderer == renderer) { NSAssert(NO, @"|renderer| is already attached to this track"); + return; } } // Create a wrapper that provides a native pointer for us.