commit 3ebe1ee8ec043d2b0d47f2e641b662376d798ee8 Author: Taner Sener Date: Wed Aug 5 01:26:42 2020 +0100 add top level build scripts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..50e1322 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/*.log diff --git a/android.sh b/android.sh new file mode 100755 index 0000000..cc0a798 --- /dev/null +++ b/android.sh @@ -0,0 +1,369 @@ +#!/bin/bash + +export FFMPEG_KIT_BUILD_TYPE="android" +export BASEDIR="$(pwd)" + +source "${BASEDIR}"/scripts/common-${FFMPEG_KIT_BUILD_TYPE}.sh + +# ENABLE ARCH +ENABLED_ARCHITECTURES=(1 1 0 0 1 0 0 0 1 1 0) + +# ENABLE LIBRARIES +ENABLED_LIBRARIES=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +# USING API LEVEL 24 / Android 7.0 (NOUGAT) +export API=24 + +RECONF_LIBRARIES=() +REBUILD_LIBRARIES=() +REDOWNLOAD_LIBRARIES=() + +get_ffmpeg_kit_version() { + local FFMPEG_KIT_VERSION=$(grep '#define FFMPEG_KIT_VERSION' "${BASEDIR}"/android/app/src/main/cpp/ffmpegkit.h | grep -Eo '\".*\"' | sed -e 's/\"//g') + + echo "${FFMPEG_KIT_VERSION}" +} + +display_help() { + local COMMAND=$(echo "$0" | sed -e 's/\.\///g') + + echo -e "\n'$COMMAND' builds FFmpegKit for Android platform. By default five Android ABIs (armeabi-v7a, \ +armeabi-v7a-neon, arm64-v8a, x86 and x86_64) are built without any external libraries enabled. Options can be used to \ +disable ABIs and/or enable external libraries. Please note that GPL libraries (external libraries with GPL license) \ +need --enable-gpl flag to be set explicitly. When compilation ends an Android Archive (AAR) file is created under the \ +prebuilt folder.\n" + echo -e "Usage: ./$COMMAND [OPTION]... [VAR=VALUE]...\n" + echo -e "Specify environment variables as VARIABLE=VALUE to override default build options.\n" + + display_help_options " --api-level=api\t\tset Android api level [${API}]" + display_help_licensing + + echo -e "Architectures:" + echo -e " --disable-arm-v7a\t\tdo not build arm-v7a architecture [yes]" + echo -e " --disable-arm-v7a-neon\tdo not build arm-v7a-neon architecture [yes]" + echo -e " --disable-arm64-v8a\t\tdo not build arm64-v8a architecture [yes]" + echo -e " --disable-x86\t\t\tdo not build x86 architecture [yes]" + echo -e " --disable-x86-64\t\tdo not build x86-64 architecture [yes]\n" + + echo -e "Libraries:" + echo -e " --full\t\t\tenables all external libraries" + echo -e " --enable-android-media-codec\tbuild with built-in Android MediaCodec support[no]" + echo -e " --enable-android-zlib\t\tbuild with built-in zlib support[no]" + + display_help_common_libraries + display_help_gpl_libraries + display_help_advanced_options +} + +enable_lts_build() { + export FFMPEG_KIT_LTS_BUILD="1" + + # USING API LEVEL 16 / Android 4.1 (JELLY BEAN) + export API=16 +} + +build_application_mk() { + if [[ -n ${FFMPEG_KIT_LTS_BUILD} ]]; then + local LTS_BUILD_FLAG="-DFFMPEG_KIT_LTS " + fi + + if [[ ${ENABLED_LIBRARIES[$LIBRARY_X265]} -eq 1 ]] || [[ ${ENABLED_LIBRARIES[$LIBRARY_TESSERACT]} -eq 1 ]] || [[ ${ENABLED_LIBRARIES[$LIBRARY_OPENH264]} -eq 1 ]] || [[ ${ENABLED_LIBRARIES[$LIBRARY_SNAPPY]} -eq 1 ]] || [[ ${ENABLED_LIBRARIES[$LIBRARY_RUBBERBAND]} -eq 1 ]]; then + local APP_STL="c++_shared" + else + local APP_STL="none" + fi + + local BUILD_DATE="-DFFMPEG_KIT_BUILD_DATE=$(date +%Y%m%d 2>>"${BASEDIR}"/build.log)" + + rm -f "${BASEDIR}/android/jni/Application.mk" + + cat >"${BASEDIR}/android/jni/Application.mk" <>"${BASEDIR}"/build.log 2>&1 +echo -e "INFO: Build options: $*\n" 1>>"${BASEDIR}"/build.log 2>&1 + +GPL_ENABLED="no" +DISPLAY_HELP="" +BUILD_LTS="" +BUILD_FULL="" +BUILD_TYPE_ID="" +BUILD_VERSION=$(git describe --tags 2>>"${BASEDIR}"/build.log) + +while [ ! $# -eq 0 ]; do + + case $1 in + -h | --help) + DISPLAY_HELP="1" + ;; + -v | --version) + display_version + exit 0 + ;; + --skip-*) + SKIP_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + skip_library "${SKIP_LIBRARY}" + ;; + --no-output-redirection) + no_output_redirection + ;; + --no-workspace-cleanup-*) + NO_WORKSPACE_CLEANUP_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-[A-Za-z]*-[A-Za-z]*-//g') + + no_workspace_cleanup_library "${NO_WORKSPACE_CLEANUP_LIBRARY}" + ;; + --no-link-time-optimization) + no_link_time_optimization + ;; + -d | --debug) + enable_debug + ;; + -s | --speed) + optimize_for_speed + ;; + -l | --lts) + BUILD_LTS="1" + ;; + -f | --force) + BUILD_FORCE="1" + ;; + --reconf-*) + CONF_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + reconf_library "${CONF_LIBRARY}" + ;; + --rebuild-*) + BUILD_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + rebuild_library "${BUILD_LIBRARY}" + ;; + --redownload-*) + DOWNLOAD_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + redownload_library "${DOWNLOAD_LIBRARY}" + ;; + --full) + BUILD_FULL="1" + ;; + --enable-gpl) + GPL_ENABLED="yes" + ;; + --enable-*) + ENABLED_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + enable_library "${ENABLED_LIBRARY}" + ;; + --disable-*) + DISABLED_ARCH=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + disable_arch "${DISABLED_ARCH}" + ;; + --api-level=*) + API_LEVEL=$(echo $1 | sed -e 's/^--[A-Za-z]*-[A-Za-z]*=//g') + + export API=${API_LEVEL} + ;; + *) + print_unknown_option "$1" + ;; + esac + shift +done + +if [[ -z ${BUILD_VERSION} ]]; then + echo -e "\n(*) error: Can not run git commands in this folder. See build.log.\n" + exit 1 +fi + +# DETECT BUILD TYPE +rm -f "${BASEDIR}"/android/app/build.gradle 1>>"${BASEDIR}"/build.log 2>&1 +if [[ -n ${BUILD_LTS} ]]; then + enable_lts_build + BUILD_TYPE_ID+="LTS " + + cp "${BASEDIR}"/tools/release/android/build.lts.gradle "${BASEDIR}"/android/app/build.gradle 1>>"${BASEDIR}"/build.log 2>&1 +else + cp "${BASEDIR}"/tools/release/android/build.gradle "${BASEDIR}"/android/app/build.gradle 1>>"${BASEDIR}"/build.log 2>&1 +fi + +# HELP DISPLAYED AFTER SETTING LTS FLAG +if [[ -n ${DISPLAY_HELP} ]]; then + display_help + exit 0 +fi + +# PROCESS FULL FLAG +if [[ -n ${BUILD_FULL} ]]; then + for library in {0..60}; do + if [ ${GPL_ENABLED} == "yes" ]; then + enable_library "$(get_library_name $library)" + else + if [[ $library -ne $LIBRARY_X264 ]] && [[ $library -ne $LIBRARY_XVIDCORE ]] && [[ $library -ne $LIBRARY_X265 ]] && [[ $library -ne $LIBRARY_LIBVIDSTAB ]] && [[ $library -ne $LIBRARY_RUBBERBAND ]]; then + enable_library "$(get_library_name $library)" + fi + fi + done +fi + +echo -e "\nBuilding ffmpeg-kit ${BUILD_TYPE_ID}library for Android\n" +echo -e -n "INFO: Building ffmpeg-kit ${BUILD_VERSION} ${BUILD_TYPE_ID}library for Android: " 1>>"${BASEDIR}"/build.log 2>&1 +echo -e "$(date)" 1>>"${BASEDIR}"/build.log 2>&1 + +# PRINT BUILD SUMMARY +print_enabled_architectures +print_enabled_libraries +print_reconfigure_requested_libraries +print_rebuild_requested_libraries +print_redownload_requested_libraries + +# CHECK GPL FLAG AND DOWNLOAD LIBRARIES +for gpl_library in {$LIBRARY_X264,$LIBRARY_XVIDCORE,$LIBRARY_X265,$LIBRARY_LIBVIDSTAB,$LIBRARY_RUBBERBAND}; do + if [[ ${ENABLED_LIBRARIES[$gpl_library]} -eq 1 ]]; then + library_name=$(get_library_name ${gpl_library}) + + if [ ${GPL_ENABLED} != "yes" ]; then + echo -e "\n(*) Invalid configuration detected. GPL library ${library_name} enabled without --enable-gpl flag.\n" + echo -e "\n(*) Invalid configuration detected. GPL library ${library_name} enabled without --enable-gpl flag.\n" 1>>"${BASEDIR}"/build.log 2>&1 + exit 1 + else + DOWNLOAD_RESULT=$(download_gpl_library_source "${library_name}") + if [[ ${DOWNLOAD_RESULT} -ne 0 ]]; then + echo -e "\n(*) Failed to download GPL library ${library_name} source. Please check build.log file for details. If the problem persists refer to offline building instructions.\n" + echo -e "\n(*) Failed to download GPL library ${library_name} source.\n" 1>>"${BASEDIR}"/build.log 2>&1 + exit 1 + fi + fi + fi +done + +# SAVE API VALUE +export ORIGINAL_API=${API} + +# BUILD ALL ENABLED ARCHITECTURES +for run_arch in {0..10}; do + if [[ ${ENABLED_ARCHITECTURES[$run_arch]} -eq 1 ]]; then + if [[ (${run_arch} -eq ${ARCH_ARM64_V8A} || ${run_arch} -eq ${ARCH_X86_64}) && ${API} -lt 21 ]]; then + + # 64 bit ABIs supported after API 21 + export API=21 + else + export API=${ORIGINAL_API} + fi + + export ARCH=$(get_arch_name $run_arch) + export TOOLCHAIN=$(get_toolchain) + export TOOLCHAIN_ARCH=$(get_toolchain_arch) + + . "${BASEDIR}"/scripts/main-android.sh "${ENABLED_LIBRARIES[@]}" || exit 1 + + # CLEAR FLAGS + for library in {0..60}; do + library_name=$(get_library_name ${library}) + unset "$(echo "OK_${library_name}" | sed "s/\-/\_/g")" + unset "$(echo "DEPENDENCY_REBUILT_${library_name}" | sed "s/\-/\_/g")" + done + fi +done + +export API=${ORIGINAL_API} + +# SET ARCHITECTURES INSIDE Application.mk +rm -f "${BASEDIR}"/android/build/.armv7 1>>"${BASEDIR}"/build.log 2>&1 +rm -f "${BASEDIR}"/android/build/.armv7neon 1>>"${BASEDIR}"/build.log 2>&1 +ANDROID_ARCHITECTURES="" +if [[ ${ENABLED_ARCHITECTURES[0]} -eq 1 ]] || [[ ${ENABLED_ARCHITECTURES[1]} -eq 1 ]]; then + ANDROID_ARCHITECTURES+="$(get_android_arch 0) " +fi +if [[ ${ENABLED_ARCHITECTURES[0]} -eq 1 ]]; then + mkdir -p "${BASEDIR}"/android/build 1>>"${BASEDIR}"/build.log 2>&1 + cat >"${BASEDIR}"/android/build/.armv7 <>"${BASEDIR}"/build.log 2>&1 + cat >"${BASEDIR}"/android/build/.armv7neon <>"${BASEDIR}"/build.log 2>&1 + + mkdir -p "${FFMPEG_KIT_AAR}" 1>>"${BASEDIR}"/build.log 2>&1 + + cd "${BASEDIR}"/android 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + # CLEAR OLD NDK LIBS + rm -rf "${BASEDIR}"/android/libs 1>>"${BASEDIR}"/build.log 2>&1 + rm -rf "${BASEDIR}"/android/obj 1>>"${BASEDIR}"/build.log 2>&1 + + "${ANDROID_NDK_ROOT}"/ndk-build -B 1>>"${BASEDIR}"/build.log 2>&1 + + if [ $? -eq 0 ]; then + echo "ok" + else + echo "failed" + exit 1 + fi + + echo -e -n "\n\nCreating Android archive under prebuilt/android-aar: " + + ./gradlew app:clean app:assembleRelease app:testReleaseUnitTest 1>>"${BASEDIR}"/build.log 2>&1 + + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + cp "${BASEDIR}"/android/app/build/outputs/aar/ffmpeg-kit-release.aar "${FFMPEG_KIT_AAR}"/ffmpeg-kit.aar 1>>"${BASEDIR}"/build.log 2>&1 + + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + echo -e "Created ffmpeg-kit Android archive successfully.\n" 1>>"${BASEDIR}"/build.log 2>&1 + + echo -e "ok\n" +fi diff --git a/ios.sh b/ios.sh new file mode 100755 index 0000000..03a186c --- /dev/null +++ b/ios.sh @@ -0,0 +1,799 @@ +#!/bin/bash + +export FFMPEG_KIT_BUILD_TYPE="ios" +export BASEDIR="$(pwd)" + +source "${BASEDIR}"/scripts/common-${FFMPEG_KIT_BUILD_TYPE}.sh + +# ENABLE ARCH +ENABLED_ARCHITECTURES=(0 0 1 1 0 1 1 1 0 1 1) + +# ENABLE LIBRARIES +ENABLED_LIBRARIES=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +# USE 12.1 AS DEFAULT IOS_MIN_VERSION +export IOS_MIN_VERSION=12.1 + +RECONF_LIBRARIES=() +REBUILD_LIBRARIES=() +REDOWNLOAD_LIBRARIES=() + +get_ffmpeg_kit_version() { + local FFMPEG_KIT_VERSION=$(grep 'const FFMPEG_KIT_VERSION' "${BASEDIR}"/ios/src/FFmpegKit.m | grep -Eo '\".*\"' | sed -e 's/\"//g') + + if [[ -z ${FFMPEG_KIT_LTS_BUILD} ]]; then + echo "${FFMPEG_KIT_VERSION}" + else + echo "${FFMPEG_KIT_VERSION}.LTS" + fi +} + +display_help() { + COMMAND=$(echo "$0" | sed -e 's/\.\///g') + + echo -e "\n$COMMAND builds FFmpegKit for iOS platform. By default seven architectures (armv7, armv7s, arm64, arm64e, \ +i386, x86-64 and x86-64-mac-catalyst) are built without any external libraries enabled. Options can be used to disable \ +architectures and/or enable external libraries. Please note that GPL libraries (external libraries with GPL license) \ +need --enable-gpl flag to be set explicitly. When compilation ends, library bundles are created under the prebuilt \ +folder. By default framework bundles and universal fat binaries are created. If --xcframework option is provided then \ +xcframework bundles are created.\n" + echo -e "Usage: ./$COMMAND [OPTION]...\n" + echo -e "Specify environment variables as VARIABLE=VALUE to override default build options.\n" + + display_help_options " -x, --xcframework\t\tbuild xcframework bundles instead of framework bundles and universal libraries" + display_help_licensing + + echo -e "Architectures:" + echo -e " --disable-armv7\t\tdo not build armv7 architecture [yes]" + echo -e " --disable-armv7s\t\tdo not build armv7s architecture [yes]" + echo -e " --disable-arm64\t\tdo not build arm64 architecture [yes]" + echo -e " --disable-arm64e\t\tdo not build arm64e architecture [yes]" + echo -e " --disable-i386\t\tdo not build i386 architecture [yes]" + echo -e " --disable-x86-64\t\tdo not build x86-64 architecture [yes]" + echo -e " --disable-x86-64-mac-catalyst\tdo not build x86-64-mac-catalyst architecture [yes]\n" + + echo -e "Libraries:" + + echo -e " --full\t\t\tenables all non-GPL external libraries" + echo -e " --enable-ios-audiotoolbox\tbuild with built-in Apple AudioToolbox support[no]" + echo -e " --enable-ios-avfoundation\tbuild with built-in Apple AVFoundation support[no]" + echo -e " --enable-ios-bzip2\t\tbuild with built-in bzip2 support[no]" + echo -e " --enable-ios-videotoolbox\tbuild with built-in Apple VideoToolbox support[no]" + echo -e " --enable-ios-zlib\t\tbuild with built-in zlib [no]" + echo -e " --enable-ios-libiconv\t\tbuild with built-in libiconv [no]" + + display_help_common_libraries + display_help_gpl_libraries + display_help_advanced_options +} + +enable_lts_build() { + export FFMPEG_KIT_LTS_BUILD="1" + + # XCODE 7.3 HAS IOS SDK 9.3 + export IOS_MIN_VERSION=9.3 +} + +# 1 - library index +# 2 - library name +# 3 - static library name +# 4 - library version +create_external_library_package() { + if [[ -n ${FFMPEG_KIT_XCF_BUILD} ]]; then + + # 1. CREATE INDIVIDUAL FRAMEWORKS + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + if [[ ${TARGET_ARCH} != "arm64e" ]]; then + local FRAMEWORK_PATH=${BASEDIR}/prebuilt/ios-xcframework/.tmp/ios-${TARGET_ARCH}/$2.framework + mkdir -p "${FRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + local STATIC_LIBRARY_PATH=$(find "${BASEDIR}"/prebuilt/ios-${TARGET_ARCH} -name $3) + local CAPITAL_CASE_LIBRARY_NAME=$(to_capital_case "$2") + + build_info_plist "${FRAMEWORK_PATH}/Info.plist" "$2" "com.arthenica.ffmpegkit.${CAPITAL_CASE_LIBRARY_NAME}" "$4" "$4" + cp "${STATIC_LIBRARY_PATH}" "${FRAMEWORK_PATH}/$2" 1>>"${BASEDIR}"/build.log 2>&1 + fi + done + + # 2. CREATE XCFRAMEWORKS + local XCFRAMEWORK_PATH=${BASEDIR}/prebuilt/ios-xcframework/$2.xcframework + mkdir -p "${XCFRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + BUILD_COMMAND="xcodebuild -create-xcframework " + + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + if [[ ${TARGET_ARCH} != "arm64e" ]]; then + local FRAMEWORK_PATH=${BASEDIR}/prebuilt/ios-xcframework/.tmp/ios-${TARGET_ARCH}/$2.framework + BUILD_COMMAND+=" -framework ${FRAMEWORK_PATH}" + fi + done + + BUILD_COMMAND+=" -output ${XCFRAMEWORK_PATH}" + + COMMAND_OUTPUT=$(${BUILD_COMMAND} 2>&1) + + echo "${COMMAND_OUTPUT}" 1>>"${BASEDIR}"/build.log 2>&1 + + echo "" 1>>"${BASEDIR}"/build.log 2>&1 + + if [[ ${COMMAND_OUTPUT} == *"is empty in library"* ]]; then + RC=1 + else + RC=0 + fi + + else + + # 1. CREATE FAT LIBRARY + local FAT_LIBRARY_PATH=${BASEDIR}/prebuilt/ios-universal/$2-universal + + mkdir -p "${FAT_LIBRARY_PATH}/lib" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + LIPO_COMMAND="${LIPO} -create" + + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + LIPO_COMMAND+=" $(find "${BASEDIR}"/prebuilt/ios-"${TARGET_ARCH}" -name $3)" + done + + LIPO_COMMAND+=" -output ${FAT_LIBRARY_PATH}/lib/$3" + + RC=$(${LIPO_COMMAND} 1>>"${BASEDIR}"/build.log 2>&1) + + if [[ ${RC} -eq 0 ]]; then + + # 2. CREATE FRAMEWORK + RC=$(create_static_framework "$2" "$3" "$4") + + if [[ ${RC} -eq 0 ]]; then + + # 3. COPY LICENSES + if [[ ${LIBRARY_LIBTHEORA} == "$1" ]]; then + license_directories=("${BASEDIR}/prebuilt/ios-universal/libtheora-universal" "${BASEDIR}/prebuilt/ios-universal/libtheoraenc-universal" "${BASEDIR}/prebuilt/ios-universal/libtheoradec-universal" "${BASEDIR}/prebuilt/ios-framework/libtheora.framework" "${BASEDIR}/prebuilt/ios-framework/libtheoraenc.framework" "${BASEDIR}/prebuilt/ios-framework/libtheoradec.framework") + elif [[ ${LIBRARY_LIBVORBIS} == "$1" ]]; then + license_directories=("${BASEDIR}/prebuilt/ios-universal/libvorbisfile-universal" "${BASEDIR}/prebuilt/ios-universal/libvorbisenc-universal" "${BASEDIR}/prebuilt/ios-universal/libvorbis-universal" "${BASEDIR}/prebuilt/ios-framework/libvorbisfile.framework" "${BASEDIR}/prebuilt/ios-framework/libvorbisenc.framework" "${BASEDIR}/prebuilt/ios-framework/libvorbis.framework") + elif [[ ${LIBRARY_LIBWEBP} == "$1" ]]; then + license_directories=("${BASEDIR}/prebuilt/ios-universal/libwebpmux-universal" "${BASEDIR}/prebuilt/ios-universal/libwebpdemux-universal" "${BASEDIR}/prebuilt/ios-universal/libwebp-universal" "${BASEDIR}/prebuilt/ios-framework/libwebpmux.framework" "${BASEDIR}/prebuilt/ios-framework/libwebpdemux.framework" "${BASEDIR}/prebuilt/ios-framework/libwebp.framework") + elif [[ ${LIBRARY_OPENCOREAMR} == "$1" ]]; then + license_directories=("${BASEDIR}/prebuilt/ios-universal/libopencore-amrnb-universal" "${BASEDIR}/prebuilt/ios-framework/libopencore-amrnb.framework") + elif [[ ${LIBRARY_NETTLE} == "$1" ]]; then + license_directories=("${BASEDIR}/prebuilt/ios-universal/libnettle-universal" "${BASEDIR}/prebuilt/ios-universal/libhogweed-universal" "${BASEDIR}/prebuilt/ios-framework/libnettle.framework" "${BASEDIR}/prebuilt/ios-framework/libhogweed.framework") + else + license_directories=("${BASEDIR}/prebuilt/ios-universal/$2-universal" "${BASEDIR}/prebuilt/ios-framework/$2.framework") + fi + + RC=$(copy_external_library_license "$1" "${license_directories[@]}") + fi + + fi + + fi + + echo "${RC}" +} + +# 1 - library index +# 2 - output path +copy_external_library_license() { + output_path_array="$2" + for output_path in "${output_path_array[@]}" + do + $(cp $(get_external_library_license_path "$1") "${output_path}/LICENSE" 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo 1 + return + fi + done; + echo 0 +} + +get_external_library_version() { + local library_version=$(grep Version "${BASEDIR}"/prebuilt/ios-"${TARGET_ARCH_LIST[0]}"/pkgconfig/"$1".pc 2>>"${BASEDIR}"/build.log | sed 's/Version://g;s/\ //g') + + echo "${library_version}" +} + +# CHECKING IF XCODE IS INSTALLED +if ! [ -x "$(command -v xcrun)" ]; then + echo -e "\n(*) xcrun command not found. Please check your Xcode installation.\n" + exit 1 +fi + +# SELECT XCODE VERSION USED FOR BUILDING +XCODE_FOR_FFMPEG_KIT=source ~/.xcode.for.ffmpeg.kit.sh +if [[ -f ${XCODE_FOR_FFMPEG_KIT} ]]; then + source "${XCODE_FOR_FFMPEG_KIT}" 1>>"${BASEDIR}"/build.log 2>&1 +fi + +DETECTED_IOS_SDK_VERSION="$(xcrun --sdk iphoneos --show-sdk-version)" + +echo -e "INFO: Using SDK ${DETECTED_IOS_SDK_VERSION} by Xcode provided at $(xcode-select -p)\n" 1>>"${BASEDIR}"/build.log 2>&1 +echo -e "\nINFO: Build options: $*\n" 1>>"${BASEDIR}"/build.log 2>&1 + +if [[ -n ${FFMPEG_KIT_LTS_BUILD} ]] && [[ "${DETECTED_IOS_SDK_VERSION}" != "${IOS_MIN_VERSION}" ]]; then + echo -e "\n(*) LTS packages should be built using SDK ${IOS_MIN_VERSION} but current configuration uses SDK ${DETECTED_IOS_SDK_VERSION}\n" + + if [[ -z ${BUILD_FORCE} ]]; then + exit 1 + fi +fi + +GPL_ENABLED="no" +DISPLAY_HELP="" +BUILD_TYPE_ID="" +BUILD_LTS="" +BUILD_FULL="" +FFMPEG_KIT_XCF_BUILD="" +BUILD_FORCE="" +BUILD_VERSION=$(git describe --tags 2>>"${BASEDIR}"/build.log) + +while [ ! $# -eq 0 ]; do + case $1 in + -h | --help) + DISPLAY_HELP="1" + ;; + -v | --version) + display_version + exit 0 + ;; + --skip-*) + SKIP_LIBRARY=$(echo "$1" | sed -e 's/^--[A-Za-z]*-//g') + + skip_library "${SKIP_LIBRARY}" + ;; + --no-output-redirection) + no_output_redirection + ;; + --no-workspace-cleanup-*) + NO_WORKSPACE_CLEANUP_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-[A-Za-z]*-[A-Za-z]*-//g') + + no_workspace_cleanup_library "${NO_WORKSPACE_CLEANUP_LIBRARY}" + ;; + -d | --debug) + enable_debug + ;; + -s | --speed) + optimize_for_speed + ;; + -l | --lts) + BUILD_LTS="1" + ;; + -x | --xcframework) + FFMPEG_KIT_XCF_BUILD="1" + ;; + -f | --force) + BUILD_FORCE="1" + ;; + --reconf-*) + CONF_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + reconf_library "${CONF_LIBRARY}" + ;; + --rebuild-*) + BUILD_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + rebuild_library "${BUILD_LIBRARY}" + ;; + --redownload-*) + DOWNLOAD_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + redownload_library "${DOWNLOAD_LIBRARY}" + ;; + --full) + BUILD_FULL="1" + ;; + --enable-gpl) + GPL_ENABLED="yes" + ;; + --enable-*) + ENABLED_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + enable_library "${ENABLED_LIBRARY}" + ;; + --disable-*) + DISABLED_ARCH=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + disable_arch "${DISABLED_ARCH}" + ;; + *) + print_unknown_option "$1" + ;; + esac + shift +done + +if [[ -z ${BUILD_VERSION} ]]; then + echo -e "\nerror: Can not run git commands in this folder. See build.log.\n" + exit 1 +fi + +# DETECT BUILD TYPE +if [[ -n ${BUILD_LTS} ]]; then + enable_lts_build + BUILD_TYPE_ID+="LTS " +fi + +# HELP DISPLAYED AFTER SETTING LTS FLAG +if [[ -n ${DISPLAY_HELP} ]]; then + display_help + exit 0 +fi + +# PROCESS FULL FLAG +if [[ -n ${BUILD_FULL} ]]; then + for library in {0..60}; do + if [ ${GPL_ENABLED} == "yes" ]; then + enable_library "$(get_library_name $library)" + else + if [[ $library -ne $LIBRARY_X264 ]] && [[ $library -ne $LIBRARY_XVIDCORE ]] && [[ $library -ne $LIBRARY_X265 ]] && [[ $library -ne $LIBRARY_LIBVIDSTAB ]] && [[ $library -ne $LIBRARY_RUBBERBAND ]]; then + enable_library "$(get_library_name $library)" + fi + fi + done +fi + +# DISABLE 32-bit architectures on newer IOS versions +if [[ ${DETECTED_IOS_SDK_VERSION} == 11* ]] || [[ ${DETECTED_IOS_SDK_VERSION} == 12* ]] || [[ ${DETECTED_IOS_SDK_VERSION} == 13* ]]; then + if [[ -z ${BUILD_FORCE} ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_ARMV7}]} -eq 1 ]]; then + echo -e "INFO: Disabled armv7 architecture which is not supported on SDK ${DETECTED_IOS_SDK_VERSION}\n" 1>>"${BASEDIR}"/build.log 2>&1 + disable_arch "armv7" + fi + if [[ -z ${BUILD_FORCE} ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_ARMV7S}]} -eq 1 ]]; then + echo -e "INFO: Disabled armv7s architecture which is not supported on SDK ${DETECTED_IOS_SDK_VERSION}\n" 1>>"${BASEDIR}"/build.log 2>&1 + disable_arch "armv7s" + fi + if [[ -z ${BUILD_FORCE} ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_I386}]} -eq 1 ]]; then + echo -e "INFO: Disabled i386 architecture which is not supported on SDK ${DETECTED_IOS_SDK_VERSION}\n" 1>>"${BASEDIR}"/build.log 2>&1 + disable_arch "i386" + fi + +# DISABLE arm64e architecture on older IOS versions +elif [[ ${DETECTED_IOS_SDK_VERSION} != 10* ]]; then + if [[ -z ${BUILD_FORCE} ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_ARM64E}]} -eq 1 ]]; then + echo -e "INFO: Disabled arm64e architecture which is not supported on SDK ${DETECTED_IOS_SDK_VERSION}\n" 1>>"${BASEDIR}"/build.log 2>&1 + disable_arch "arm64e" + fi +fi + +# DISABLE x86-64-mac-catalyst architecture on IOS versions lower than 13 +if [[ ${DETECTED_IOS_SDK_VERSION} != 13* ]] && [[ -z ${BUILD_FORCE} ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_X86_64_MAC_CATALYST}]} -eq 1 ]]; then + echo -e "INFO: Disabled x86-64-mac-catalyst architecture which is not supported on SDK ${DETECTED_IOS_SDK_VERSION}\n" 1>>"${BASEDIR}"/build.log 2>&1 + disable_arch "x86-64-mac-catalyst" +fi + +# DISABLE x86-64-mac-catalyst when x86-64 is enabled in xcf bundles +if [[ -z ${FFMPEG_KIT_XCF_BUILD} ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_X86_64}]} -eq 1 ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_X86_64_MAC_CATALYST}]} -eq 1 ]]; then + echo -e "INFO: Disabled x86-64-mac-catalyst architecture which can not co-exist with x86-64 in a framework bundle / universal fat library.\n" 1>>"${BASEDIR}"/build.log 2>&1 + disable_arch "x86-64-mac-catalyst" +fi + +# DISABLE arm64e when arm64 is enabled in xcf bundles +if [[ -n ${FFMPEG_KIT_XCF_BUILD} ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_ARM64E}]} -eq 1 ]] && [[ ${ENABLED_ARCHITECTURES[${ARCH_ARM64}]} -eq 1 ]]; then + echo -e "INFO: Disabled arm64e architecture which can not co-exist with arm64 in an xcframework bundle.\n" 1>>"${BASEDIR}"/build.log 2>&1 + disable_arch "arm64e" +fi + +echo -e "\nBuilding ffmpeg-kit ${BUILD_TYPE_ID}static library for iOS\n" +echo -e -n "INFO: Building ffmpeg-kit ${BUILD_VERSION} ${BUILD_TYPE_ID}for iOS: " 1>>"${BASEDIR}"/build.log 2>&1 +echo -e "$(date)" 1>>"${BASEDIR}"/build.log 2>&1 + +# PRINT BUILD SUMMARY +print_enabled_architectures +print_enabled_libraries +print_reconfigure_requested_libraries +print_rebuild_requested_libraries +print_redownload_requested_libraries + +# CHECK GPL FLAG AND DOWNLOAD LIBRARIES +for gpl_library in {$LIBRARY_X264,$LIBRARY_XVIDCORE,$LIBRARY_X265,$LIBRARY_LIBVIDSTAB,$LIBRARY_RUBBERBAND}; do + if [[ ${ENABLED_LIBRARIES[$gpl_library]} -eq 1 ]]; then + library_name=$(get_library_name ${gpl_library}) + + if [ ${GPL_ENABLED} != "yes" ]; then + echo -e "\n(*) Invalid configuration detected. GPL library ${library_name} enabled without --enable-gpl flag.\n" + echo -e "\n(*) Invalid configuration detected. GPL library ${library_name} enabled without --enable-gpl flag.\n" 1>>"${BASEDIR}"/build.log 2>&1 + exit 1 + else + DOWNLOAD_RESULT=$(download_gpl_library_source "${library_name}") + if [[ ${DOWNLOAD_RESULT} -ne 0 ]]; then + echo -e "\n(*) Failed to download GPL library ${library_name} source. Please check build.log file for details. If the problem persists refer to offline building instructions.\n" + echo -e "\n(*) Failed to download GPL library ${library_name} source.\n" 1>>"${BASEDIR}"/build.log 2>&1 + exit 1 + fi + fi + fi +done + +TARGET_ARCH_LIST=() + +# BUILD ALL ENABLED ARCHITECTURES +for run_arch in {0..10}; do + if [[ ${ENABLED_ARCHITECTURES[$run_arch]} -eq 1 ]]; then + export ARCH=$(get_arch_name $run_arch) + export TARGET_SDK=$(get_target_sdk) + export SDK_PATH=$(get_sdk_path) + export SDK_NAME=$(get_sdk_name) + + export LIPO="$(xcrun --sdk "$(get_sdk_name)" -f lipo)" + + . "${BASEDIR}"/scripts/main-ios.sh "${ENABLED_LIBRARIES[@]}" + case ${ARCH} in + x86-64) + TARGET_ARCH="x86_64" + ;; + x86-64-mac-catalyst) + TARGET_ARCH="x86_64-mac-catalyst" + ;; + *) + TARGET_ARCH="${ARCH}" + ;; + esac + TARGET_ARCH_LIST+=("${TARGET_ARCH}") + + # CLEAR FLAGS + for library in {0..60}; do + library_name=$(get_library_name ${library}) + unset "$(echo "OK_${library_name}" | sed "s/\-/\_/g")" + unset "$(echo "DEPENDENCY_REBUILT_${library_name}" | sed "s/\-/\_/g")" + done + fi +done + +FFMPEG_LIBS="libavcodec libavdevice libavfilter libavformat libavutil libswresample libswscale" + +BUILD_LIBRARY_EXTENSION="a" + +if [[ -n ${TARGET_ARCH_LIST[0]} ]]; then + + # BUILDING PACKAGES + if [[ -n ${FFMPEG_KIT_XCF_BUILD} ]]; then + echo -e -n "\n\nCreating xcframeworks under prebuilt: " + + rm -rf "${BASEDIR}/prebuilt/ios-xcframework" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + mkdir -p "${BASEDIR}/prebuilt/ios-xcframework" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + else + echo -e -n "\n\nCreating frameworks and universal libraries under prebuilt: " + + rm -rf "${BASEDIR}/prebuilt/ios-universal" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + mkdir -p "${BASEDIR}/prebuilt/ios-universal" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + rm -rf "${BASEDIR}/prebuilt/ios-framework" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + mkdir -p "${BASEDIR}/prebuilt/ios-framework" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + fi + + # 1. EXTERNAL LIBRARIES + for library in {0..6} {8..37} {39..44}; do + if [[ ${ENABLED_LIBRARIES[$library]} -eq 1 ]]; then + + library_name=$(get_library_name ${library}) + package_config_file_name=$(get_package_config_file_name ${library}) + library_version=$(get_external_library_version "${package_config_file_name}") + if [[ -z ${library_version} ]]; then + echo -e "Failed to detect version for ${library_name} from ${package_config_file_name}.pc\n" 1>>"${BASEDIR}"/build.log 2>&1 + echo -e "failed\n" + exit 1 + fi + + echo -e "Creating external library package for ${library_name}\n" 1>>"${BASEDIR}"/build.log 2>&1 + + if [[ ${LIBRARY_LIBTHEORA} == "$library" ]]; then + + LIBRARY_CREATED=$(create_external_library_package $library "libtheora" "libtheora.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_external_library_package $library "libtheoraenc" "libtheoraenc.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_external_library_package $library "libtheoradec" "libtheoradec.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + elif [[ ${LIBRARY_LIBVORBIS} == "$library" ]]; then + + LIBRARY_CREATED=$(create_external_library_package $library "libvorbisfile" "libvorbisfile.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_external_library_package $library "libvorbisenc" "libvorbisenc.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_external_library_package $library "libvorbis" "libvorbis.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + elif [[ ${LIBRARY_LIBWEBP} == "$library" ]]; then + + LIBRARY_CREATED=$(create_external_library_package $library "libwebpmux" "libwebpmux.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_external_library_package $library "libwebpdemux" "libwebpdemux.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_external_library_package $library "libwebp" "libwebp.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + elif [[ ${LIBRARY_OPENCOREAMR} == "$library" ]]; then + + LIBRARY_CREATED=$(create_external_library_package $library "libopencore-amrnb" "libopencore-amrnb.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + elif [[ ${LIBRARY_NETTLE} == "$library" ]]; then + + LIBRARY_CREATED=$(create_external_library_package $library "libnettle" "libnettle.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_external_library_package $library "libhogweed" "libhogweed.a" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + else + + library_name=$(get_library_name $((library))) + static_archive_name=$(get_static_archive_name $((library))) + LIBRARY_CREATED=$(create_external_library_package $library "$library_name" "$static_archive_name" "${library_version}") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + fi + + fi + done + + # 2. FFMPEG & FFMPEG KIT + if [[ -n ${FFMPEG_KIT_XCF_BUILD} ]]; then + + # FFMPEG + for FFMPEG_LIB in ${FFMPEG_LIBS}; do + + XCFRAMEWORK_PATH=${BASEDIR}/prebuilt/ios-xcframework/${FFMPEG_LIB}.xcframework + mkdir -p "${XCFRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + echo -e "Creating package for ${FFMPEG_LIB}\n" 1>>"${BASEDIR}"/build.log 2>&1 + + BUILD_COMMAND="xcodebuild -create-xcframework " + + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + + if [[ ${TARGET_ARCH} != "arm64e" ]]; then + + FFMPEG_LIB_UPPERCASE=$(echo "${FFMPEG_LIB}" | tr '[a-z]' '[A-Z]') + FFMPEG_LIB_CAPITALCASE=$(to_capital_case "${FFMPEG_LIB}") + + FFMPEG_LIB_MAJOR=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MAJOR" "${BASEDIR}/prebuilt/ios-${TARGET_ARCH}/ffmpeg/include/${FFMPEG_LIB}/version.h" | sed -e "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MAJOR//g;s/\ //g") + FFMPEG_LIB_MINOR=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MINOR" "${BASEDIR}/prebuilt/ios-${TARGET_ARCH}/ffmpeg/include/${FFMPEG_LIB}/version.h" | sed -e "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MINOR//g;s/\ //g") + FFMPEG_LIB_MICRO=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MICRO" "${BASEDIR}/prebuilt/ios-${TARGET_ARCH}/ffmpeg/include/${FFMPEG_LIB}/version.h" | sed "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MICRO//g;s/\ //g") + + FFMPEG_LIB_VERSION="${FFMPEG_LIB_MAJOR}.${FFMPEG_LIB_MINOR}.${FFMPEG_LIB_MICRO}" + + FFMPEG_LIB_FRAMEWORK_PATH=${BASEDIR}/prebuilt/ios-xcframework/.tmp/ios-${TARGET_ARCH}/${FFMPEG_LIB}.framework + + rm -rf "${FFMPEG_LIB_FRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_LIB_FRAMEWORK_PATH}/Headers" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + cp -r "${BASEDIR}"/prebuilt/ios-${TARGET_ARCH}/ffmpeg/include/${FFMPEG_LIB}/* ${FFMPEG_LIB_FRAMEWORK_PATH}/Headers 1>>"${BASEDIR}"/build.log 2>&1 + cp "${BASEDIR}/prebuilt/ios-${TARGET_ARCH}/ffmpeg/lib/${FFMPEG_LIB}.${BUILD_LIBRARY_EXTENSION}" "${FFMPEG_LIB_FRAMEWORK_PATH}/${FFMPEG_LIB}" 1>>"${BASEDIR}"/build.log 2>&1 + + # COPY THE LICENSES + if [ ${GPL_ENABLED} == "yes" ]; then + + # GPLv3.0 + cp "${BASEDIR}/LICENSE.GPLv3" "${FFMPEG_LIB_FRAMEWORK_PATH}/LICENSE" 1>>"${BASEDIR}"/build.log 2>&1 + else + + # LGPLv3.0 + cp "${BASEDIR}/LICENSE.LGPLv3" "${FFMPEG_LIB_FRAMEWORK_PATH}/LICENSE" 1>>"${BASEDIR}"/build.log 2>&1 + fi + + build_info_plist "${FFMPEG_LIB_FRAMEWORK_PATH}/Info.plist" "${FFMPEG_LIB}" "com.arthenica.ffmpegkit.${FFMPEG_LIB_CAPITALCASE}" "${FFMPEG_LIB_VERSION}" "${FFMPEG_LIB_VERSION}" + + BUILD_COMMAND+=" -framework ${FFMPEG_LIB_FRAMEWORK_PATH}" + fi + + done + + BUILD_COMMAND+=" -output ${XCFRAMEWORK_PATH}" + + COMMAND_OUTPUT=$(${BUILD_COMMAND} 2>&1) + + echo "${COMMAND_OUTPUT}" 1>>"${BASEDIR}"/build.log 2>&1 + + echo "" 1>>"${BASEDIR}"/build.log 2>&1 + + if [[ ${COMMAND_OUTPUT} == *"is empty in library"* ]]; then + echo -e "failed\n" + exit 1 + fi + + echo -e "Created ${FFMPEG_LIB} xcframework successfully.\n" 1>>"${BASEDIR}"/build.log 2>&1 + + done + + # FFMPEG KIT + XCFRAMEWORK_PATH=${BASEDIR}/prebuilt/ios-xcframework/ffmpegkit.xcframework + mkdir -p "${XCFRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + BUILD_COMMAND="xcodebuild -create-xcframework " + + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + + if [[ ${TARGET_ARCH} != "arm64e" ]]; then + + FFMPEG_KIT_FRAMEWORK_PATH="${BASEDIR}/prebuilt/ios-xcframework/.tmp/ios-${TARGET_ARCH}/ffmpegkit.framework" + + rm -rf "${FFMPEG_KIT_FRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_KIT_FRAMEWORK_PATH}/Headers" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + mkdir -p "${FFMPEG_KIT_FRAMEWORK_PATH}/Modules" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + build_modulemap "${FFMPEG_KIT_FRAMEWORK_PATH}/Modules/module.modulemap" + + cp -r "${BASEDIR}"/prebuilt/ios-"${TARGET_ARCH}"/ffmpeg-kit/include/* "${FFMPEG_KIT_FRAMEWORK_PATH}"/Headers 1>>"${BASEDIR}"/build.log 2>&1 + cp "${BASEDIR}/prebuilt/ios-${TARGET_ARCH}/ffmpeg-kit/lib/libffmpegkit.${BUILD_LIBRARY_EXTENSION}" "${FFMPEG_KIT_FRAMEWORK_PATH}/ffmpegkit" 1>>"${BASEDIR}"/build.log 2>&1 + + # COPY THE LICENSES + if [ ${GPL_ENABLED} == "yes" ]; then + cp "${BASEDIR}/LICENSE.GPLv3" "${FFMPEG_KIT_FRAMEWORK_PATH}/LICENSE" 1>>"${BASEDIR}"/build.log 2>&1 + else + cp "${BASEDIR}/LICENSE.LGPLv3" "${FFMPEG_KIT_FRAMEWORK_PATH}/LICENSE" 1>>"${BASEDIR}"/build.log 2>&1 + fi + + BUILD_COMMAND+=" -framework ${FFMPEG_KIT_FRAMEWORK_PATH}" + + fi + done; + + BUILD_COMMAND+=" -output ${XCFRAMEWORK_PATH}" + + COMMAND_OUTPUT=$(${BUILD_COMMAND} 2>&1) + + echo "${COMMAND_OUTPUT}" 1>>"${BASEDIR}"/build.log 2>&1 + + echo "" 1>>"${BASEDIR}"/build.log 2>&1 + + if [[ ${COMMAND_OUTPUT} == *"is empty in library"* ]]; then + echo -e "failed\n" + exit 1 + fi + + echo -e "Created ffmpegkit xcframework successfully.\n" 1>>"${BASEDIR}"/build.log 2>&1 + + echo -e "ok\n" + + else + + FFMPEG_UNIVERSAL="${BASEDIR}/prebuilt/ios-universal/ffmpeg-universal" + mkdir -p "${FFMPEG_UNIVERSAL}/include" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + mkdir -p "${FFMPEG_UNIVERSAL}/lib" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + cp -r "${BASEDIR}"/prebuilt/ios-"${TARGET_ARCH_LIST[0]}"/ffmpeg/include/* ${FFMPEG_UNIVERSAL}/include 1>>"${BASEDIR}"/build.log 2>&1 + cp "${BASEDIR}"/prebuilt/ios-"${TARGET_ARCH_LIST[0]}"/ffmpeg/include/config.h "${FFMPEG_UNIVERSAL}/include" 1>>"${BASEDIR}"/build.log 2>&1 + + for FFMPEG_LIB in ${FFMPEG_LIBS}; do + LIPO_COMMAND="${LIPO} -create" + + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + LIPO_COMMAND+=" "${BASEDIR}"/prebuilt/ios-${TARGET_ARCH}/ffmpeg/lib/${FFMPEG_LIB}.${BUILD_LIBRARY_EXTENSION}" + done + + LIPO_COMMAND+=" -output ${FFMPEG_UNIVERSAL}/lib/${FFMPEG_LIB}.${BUILD_LIBRARY_EXTENSION}" + + ${LIPO_COMMAND} 1>>"${BASEDIR}"/build.log 2>&1 + + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + FFMPEG_LIB_UPPERCASE=$(echo "${FFMPEG_LIB}" | tr '[a-z]' '[A-Z]') + FFMPEG_LIB_CAPITALCASE=$(to_capital_case "${FFMPEG_LIB}") + + FFMPEG_LIB_MAJOR=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MAJOR" "${FFMPEG_UNIVERSAL}/include/${FFMPEG_LIB}/version.h" | sed -e "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MAJOR//g;s/\ //g") + FFMPEG_LIB_MINOR=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MINOR" "${FFMPEG_UNIVERSAL}/include/${FFMPEG_LIB}/version.h" | sed -e "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MINOR//g;s/\ //g") + FFMPEG_LIB_MICRO=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MICRO" "${FFMPEG_UNIVERSAL}/include/${FFMPEG_LIB}/version.h" | sed "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MICRO//g;s/\ //g") + + FFMPEG_LIB_VERSION="${FFMPEG_LIB_MAJOR}.${FFMPEG_LIB_MINOR}.${FFMPEG_LIB_MICRO}" + + FFMPEG_LIB_FRAMEWORK_PATH="${BASEDIR}/prebuilt/ios-framework/${FFMPEG_LIB}.framework" + + rm -rf "${FFMPEG_LIB_FRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_LIB_FRAMEWORK_PATH}/Headers" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + cp -r ${FFMPEG_UNIVERSAL}/include/${FFMPEG_LIB}/* ${FFMPEG_LIB_FRAMEWORK_PATH}/Headers 1>>"${BASEDIR}"/build.log 2>&1 + cp "${FFMPEG_UNIVERSAL}/lib/${FFMPEG_LIB}.${BUILD_LIBRARY_EXTENSION}" "${FFMPEG_LIB_FRAMEWORK_PATH}/${FFMPEG_LIB}" 1>>"${BASEDIR}"/build.log 2>&1 + + # COPY THE LICENSES + if [ ${GPL_ENABLED} == "yes" ]; then + + # GPLv3.0 + cp "${BASEDIR}/LICENSE.GPLv3" "${FFMPEG_LIB_FRAMEWORK_PATH}/LICENSE" 1>>"${BASEDIR}"/build.log 2>&1 + else + + # LGPLv3.0 + cp "${BASEDIR}/LICENSE.LGPLv3" "${FFMPEG_LIB_FRAMEWORK_PATH}/LICENSE" 1>>"${BASEDIR}"/build.log 2>&1 + fi + + build_info_plist "${FFMPEG_LIB_FRAMEWORK_PATH}/Info.plist" "${FFMPEG_LIB}" "com.arthenica.ffmpegkit.${FFMPEG_LIB_CAPITALCASE}" "${FFMPEG_LIB_VERSION}" "${FFMPEG_LIB_VERSION}" + + echo -e "Created ${FFMPEG_LIB} framework successfully.\n" 1>>"${BASEDIR}"/build.log 2>&1 + done + + # COPY THE LICENSES + if [ ${GPL_ENABLED} == "yes" ]; then + cp "${BASEDIR}"/LICENSE.GPLv3 "${FFMPEG_UNIVERSAL}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + else + cp "${BASEDIR}"/LICENSE.LGPLv3 "${FFMPEG_UNIVERSAL}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + fi + + # 3. FFMPEG KIT + FFMPEG_KIT_VERSION=$(get_ffmpeg_kit_version) + FFMPEG_KIT_UNIVERSAL="${BASEDIR}/prebuilt/ios-universal/ffmpeg-kit-universal" + FFMPEG_KIT_FRAMEWORK_PATH="${BASEDIR}/prebuilt/ios-framework/ffmpegkit.framework" + mkdir -p "${FFMPEG_KIT_UNIVERSAL}/include" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + mkdir -p "${FFMPEG_KIT_UNIVERSAL}/lib" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + rm -rf "${FFMPEG_KIT_FRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_KIT_FRAMEWORK_PATH}/Headers" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + mkdir -p "${FFMPEG_KIT_FRAMEWORK_PATH}/Modules" 1>>"${BASEDIR}"/build.log 2>&1 || exit 1 + + LIPO_COMMAND="${LIPO} -create" + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + LIPO_COMMAND+=" ${BASEDIR}/prebuilt/ios-${TARGET_ARCH}/ffmpeg-kit/lib/libffmpegkit.${BUILD_LIBRARY_EXTENSION}" + done + LIPO_COMMAND+=" -output ${FFMPEG_KIT_UNIVERSAL}/lib/libffmpegkit.${BUILD_LIBRARY_EXTENSION}" + + ${LIPO_COMMAND} 1>>"${BASEDIR}"/build.log 2>&1 + + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + cp -r "${BASEDIR}"/prebuilt/ios-"${TARGET_ARCH_LIST[0]}"/ffmpeg-kit/include/* "${FFMPEG_KIT_UNIVERSAL}"/include 1>>"${BASEDIR}"/build.log 2>&1 + cp -r "${FFMPEG_KIT_UNIVERSAL}"/include/* "${FFMPEG_KIT_FRAMEWORK_PATH}"/Headers 1>>"${BASEDIR}"/build.log 2>&1 + cp "${FFMPEG_KIT_UNIVERSAL}/lib/libffmpegkit.${BUILD_LIBRARY_EXTENSION}" "${FFMPEG_KIT_FRAMEWORK_PATH}/ffmpegkit" 1>>"${BASEDIR}"/build.log 2>&1 + + # COPY THE LICENSES + if [ ${GPL_ENABLED} == "yes" ]; then + cp "${BASEDIR}"/LICENSE.GPLv3 "${FFMPEG_KIT_UNIVERSAL}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + cp "${BASEDIR}"/LICENSE.GPLv3 "${FFMPEG_KIT_FRAMEWORK_PATH}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + else + cp "${BASEDIR}"/LICENSE.LGPLv3 "${FFMPEG_KIT_UNIVERSAL}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + cp "${BASEDIR}"/LICENSE.LGPLv3 "${FFMPEG_KIT_FRAMEWORK_PATH}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + fi + + build_info_plist "${FFMPEG_KIT_FRAMEWORK_PATH}/Info.plist" "ffmpegkit" "com.arthenica.ffmpegkit.FFmpegKit" "${FFMPEG_KIT_VERSION}" "${FFMPEG_KIT_VERSION}" + build_modulemap "${FFMPEG_KIT_FRAMEWORK_PATH}/Modules/module.modulemap" + + echo -e "Created ffmpegkit.framework and universal library successfully.\n" 1>>"${BASEDIR}"/build.log 2>&1 + + echo -e "ok\n" + fi +fi diff --git a/scripts/common-android.sh b/scripts/common-android.sh new file mode 100755 index 0000000..df6b376 --- /dev/null +++ b/scripts/common-android.sh @@ -0,0 +1,864 @@ +#!/bin/bash + +source "${BASEDIR}/scripts/common-arch.sh" + +get_clang_target_host() { + case ${ARCH} in + arm-v7a | arm-v7a-neon) + echo "armv7a-linux-androideabi${API}" + ;; + arm64-v8a) + echo "aarch64-linux-android${API}" + ;; + x86) + echo "i686-linux-android${API}" + ;; + x86-64) + echo "x86_64-linux-android${API}" + ;; + esac +} + +get_toolchain() { + HOST_OS=$(uname -s) + case ${HOST_OS} in + Darwin) HOST_OS=darwin;; + Linux) HOST_OS=linux;; + FreeBsd) HOST_OS=freebsd;; + CYGWIN*|*_NT-*) HOST_OS=cygwin;; + esac + + HOST_ARCH=$(uname -m) + case ${HOST_ARCH} in + i?86) HOST_ARCH=x86;; + x86_64|amd64) HOST_ARCH=x86_64;; + esac + + echo "${HOST_OS}-${HOST_ARCH}" +} + +get_cmake_target_processor() { + case ${ARCH} in + arm-v7a | arm-v7a-neon) + echo "arm" + ;; + arm64-v8a) + echo "aarch64" + ;; + x86) + echo "x86" + ;; + x86-64) + echo "x86_64" + ;; + esac +} + +get_target_build() { + case ${ARCH} in + arm-v7a) + echo "arm" + ;; + arm-v7a-neon) + if [[ ! -z ${MOBILE_FFMPEG_LTS_BUILD} ]]; then + echo "arm/neon" + else + echo "arm" + fi + ;; + arm64-v8a) + echo "arm64" + ;; + x86) + echo "x86" + ;; + x86-64) + echo "x86_64" + ;; + esac +} + +get_toolchain_arch() { + case ${ARCH} in + arm-v7a | arm-v7a-neon) + echo "arm" + ;; + arm64-v8a) + echo "arm64" + ;; + x86) + echo "x86" + ;; + x86-64) + echo "x86_64" + ;; + esac +} + +get_android_arch() { + case $1 in + 0 | 1) + echo "armeabi-v7a" + ;; + 2) + echo "arm64-v8a" + ;; + 3) + echo "x86" + ;; + 4) + echo "x86_64" + ;; + esac +} + +get_common_includes() { + echo "" +} + +get_common_cflags() { + if [[ ! -z ${MOBILE_FFMPEG_LTS_BUILD} ]]; then + local LTS_BUILD__FLAG="-DMOBILE_FFMPEG_LTS " + fi + + echo "-fno-integrated-as -fstrict-aliasing -fPIC -DANDROID ${LTS_BUILD__FLAG}-D__ANDROID__ -D__ANDROID_API__=${API}" +} + +get_arch_specific_cflags() { + case ${ARCH} in + arm-v7a) + echo "-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -DMOBILE_FFMPEG_ARM_V7A" + ;; + arm-v7a-neon) + echo "-march=armv7-a -mfpu=neon -mfloat-abi=softfp -DMOBILE_FFMPEG_ARM_V7A_NEON" + ;; + arm64-v8a) + echo "-march=armv8-a -DMOBILE_FFMPEG_ARM64_V8A" + ;; + x86) + echo "-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32 -DMOBILE_FFMPEG_X86" + ;; + x86-64) + echo "-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -DMOBILE_FFMPEG_X86_64" + ;; + esac +} + +get_size_optimization_cflags() { + if [[ -z ${NO_LINK_TIME_OPTIMIZATION} ]]; then + local LINK_TIME_OPTIMIZATION_FLAGS="-flto" + else + local LINK_TIME_OPTIMIZATION_FLAGS="" + fi + + local ARCH_OPTIMIZATION="" + case ${ARCH} in + arm-v7a | arm-v7a-neon) + case $1 in + ffmpeg) + ARCH_OPTIMIZATION="${LINK_TIME_OPTIMIZATION_FLAGS} -O2 -ffunction-sections -fdata-sections" + ;; + *) + ARCH_OPTIMIZATION="-Os -ffunction-sections -fdata-sections" + ;; + esac + ;; + arm64-v8a) + case $1 in + ffmpeg) + ARCH_OPTIMIZATION="${LINK_TIME_OPTIMIZATION_FLAGS} -fuse-ld=gold -O2 -ffunction-sections -fdata-sections" + ;; + *) + ARCH_OPTIMIZATION="-Os -ffunction-sections -fdata-sections" + ;; + esac + ;; + x86 | x86-64) + case $1 in + ffmpeg) + ARCH_OPTIMIZATION="${LINK_TIME_OPTIMIZATION_FLAGS} -Os -ffunction-sections -fdata-sections" + ;; + *) + ARCH_OPTIMIZATION="-Os -ffunction-sections -fdata-sections" + ;; + esac + ;; + esac + + local LIB_OPTIMIZATION="" + + echo "${ARCH_OPTIMIZATION} ${LIB_OPTIMIZATION}" +} + +get_app_specific_cflags() { + local APP_FLAGS="" + case $1 in + xvidcore) + APP_FLAGS="" + ;; + ffmpeg) + APP_FLAGS="-Wno-unused-function -DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD" + ;; + kvazaar) + APP_FLAGS="-std=gnu99 -Wno-unused-function" + ;; + rubberband) + APP_FLAGS="-std=c99 -Wno-unused-function" + ;; + shine) + APP_FLAGS="-Wno-unused-function" + ;; + soxr | snappy | libwebp) + APP_FLAGS="-std=gnu99 -Wno-unused-function -DPIC" + ;; + *) + APP_FLAGS="-std=c99 -Wno-unused-function" + ;; + esac + + echo "${APP_FLAGS}" +} + +get_cflags() { + local ARCH_FLAGS=$(get_arch_specific_cflags) + local APP_FLAGS=$(get_app_specific_cflags $1) + local COMMON_FLAGS=$(get_common_cflags) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS=$(get_size_optimization_cflags $1) + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + local COMMON_INCLUDES=$(get_common_includes) + + echo "${ARCH_FLAGS} ${APP_FLAGS} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS} ${COMMON_INCLUDES}" +} + +get_cxxflags() { + if [[ -z ${NO_LINK_TIME_OPTIMIZATION} ]]; then + local LINK_TIME_OPTIMIZATION_FLAGS="-flto" + else + local LINK_TIME_OPTIMIZATION_FLAGS="" + fi + + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS="-Os -ffunction-sections -fdata-sections" + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + + case $1 in + gnutls) + echo "-std=c++11 -fno-rtti ${OPTIMIZATION_FLAGS}" + ;; + ffmpeg) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + echo "-std=c++11 -fno-exceptions -fno-rtti ${LINK_TIME_OPTIMIZATION_FLAGS} -O2 -ffunction-sections -fdata-sections" + else + echo "-std=c++11 -fno-exceptions -fno-rtti ${MOBILE_FFMPEG_DEBUG}" + fi + ;; + opencore-amr) + echo "${OPTIMIZATION_FLAGS}" + ;; + x265) + echo "-std=c++11 -fno-exceptions ${OPTIMIZATION_FLAGS}" + ;; + rubberband) + echo "-std=c++11 ${OPTIMIZATION_FLAGS}" + ;; + *) + echo "-std=c++11 -fno-exceptions -fno-rtti ${OPTIMIZATION_FLAGS}" + ;; + esac +} + +get_common_linked_libraries() { + local COMMON_LIBRARY_PATHS="-L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${TOOLCHAIN}/${BUILD_HOST}/lib -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${TOOLCHAIN}/sysroot/usr/lib/${BUILD_HOST}/${API} -L${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${TOOLCHAIN}/lib" + + case $1 in + ffmpeg) + if [[ -z ${MOBILE_FFMPEG_LTS_BUILD} ]]; then + echo "-lc -lm -ldl -llog -lcamera2ndk -lmediandk ${COMMON_LIBRARY_PATHS}" + else + echo "-lc -lm -ldl -llog ${COMMON_LIBRARY_PATHS}" + fi + ;; + libvpx) + echo "-lc -lm ${COMMON_LIBRARY_PATHS}" + ;; + tesseract | x265) + echo "-lc -lm -ldl -llog -lc++_shared ${COMMON_LIBRARY_PATHS}" + ;; + *) + echo "-lc -lm -ldl -llog ${COMMON_LIBRARY_PATHS}" + ;; + esac +} + +get_size_optimization_ldflags() { + if [[ -z ${NO_LINK_TIME_OPTIMIZATION} ]]; then + local LINK_TIME_OPTIMIZATION_FLAGS="-flto" + else + local LINK_TIME_OPTIMIZATION_FLAGS="" + fi + + case ${ARCH} in + arm64-v8a) + case $1 in + ffmpeg) + echo "-Wl,--gc-sections ${LINK_TIME_OPTIMIZATION_FLAGS} -fuse-ld=gold -O2 -ffunction-sections -fdata-sections -finline-functions" + ;; + *) + echo "-Wl,--gc-sections -Os -ffunction-sections -fdata-sections" + ;; + esac + ;; + *) + case $1 in + ffmpeg) + echo "-Wl,--gc-sections,--icf=safe ${LINK_TIME_OPTIMIZATION_FLAGS} -O2 -ffunction-sections -fdata-sections -finline-functions" + ;; + *) + echo "-Wl,--gc-sections,--icf=safe -Os -ffunction-sections -fdata-sections" + ;; + esac + ;; + esac +} + +get_arch_specific_ldflags() { + case ${ARCH} in + arm-v7a) + echo "-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp -Wl,--fix-cortex-a8" + ;; + arm-v7a-neon) + echo "-march=armv7-a -mfpu=neon -mfloat-abi=softfp -Wl,--fix-cortex-a8" + ;; + arm64-v8a) + echo "-march=armv8-a" + ;; + x86) + echo "-march=i686" + ;; + x86-64) + echo "-march=x86-64" + ;; + esac +} + +get_ldflags() { + local ARCH_FLAGS=$(get_arch_specific_ldflags) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS="$(get_size_optimization_ldflags $1)" + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + local COMMON_LINKED_LIBS=$(get_common_linked_libraries $1) + + echo "${ARCH_FLAGS} ${OPTIMIZATION_FLAGS} ${COMMON_LINKED_LIBS} -Wl,--hash-style=both -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libunwind.a" +} + +create_chromaprint_package_config() { + local CHROMAPRINT_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libchromaprint.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/chromaprint +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: chromaprint +Description: Audio fingerprint library +URL: http://acoustid.org/chromaprint +Version: ${CHROMAPRINT_VERSION} +Libs: -L\${libdir} -lchromaprint +Cflags: -I\${includedir} +EOF +} + +create_fontconfig_package_config() { + local FONTCONFIG_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/fontconfig.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/fontconfig +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include +sysconfdir=\${prefix}/etc +localstatedir=\${prefix}/var +PACKAGE=fontconfig +confdir=\${sysconfdir}/fonts +cachedir=\${localstatedir}/cache/\${PACKAGE} + +Name: Fontconfig +Description: Font configuration and customization library +Version: ${FONTCONFIG_VERSION} +Requires: freetype2 >= 21.0.15, uuid, expat >= 2.2.0, libiconv +Requires.private: +Libs: -L\${libdir} -lfontconfig +Libs.private: +Cflags: -I\${includedir} +EOF +} + +create_freetype_package_config() { + local FREETYPE_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/freetype2.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/freetype +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: FreeType 2 +URL: https://freetype.org +Description: A free, high-quality, and portable font engine. +Version: ${FREETYPE_VERSION} +Requires: libpng +Requires.private: zlib +Libs: -L\${libdir} -lfreetype +Libs.private: +Cflags: -I\${includedir}/freetype2 +EOF +} + +create_giflib_package_config() { + local GIFLIB_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/giflib.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/giflib +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: giflib +Description: gif library +Version: ${GIFLIB_VERSION} + +Requires: +Libs: -L\${libdir} -lgif +Cflags: -I\${includedir} +EOF +} + +create_gmp_package_config() { + local GMP_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/gmp.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/gmp +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: gmp +Description: gnu mp library +Version: ${GMP_VERSION} + +Requires: +Libs: -L\${libdir} -lgmp +Cflags: -I\${includedir} +EOF +} + +create_gnutls_package_config() { + local GNUTLS_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/gnutls.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/gnutls +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: gnutls +Description: GNU TLS Implementation + +Version: ${GNUTLS_VERSION} +Requires: nettle, hogweed, zlib +Cflags: -I\${includedir} +Libs: -L\${libdir} -lgnutls +Libs.private: -lgmp +EOF +} + +create_libaom_package_config() { + local AOM_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/aom.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/libaom +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: aom +Description: AV1 codec library v${AOM_VERSION}. +Version: ${AOM_VERSION} + +Requires: +Libs: -L\${libdir} -laom -lm +Cflags: -I\${includedir} +EOF +} + +create_libiconv_package_config() { + local LIB_ICONV_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libiconv.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/libiconv +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libiconv +Description: Character set conversion library +Version: ${LIB_ICONV_VERSION} + +Requires: +Libs: -L\${libdir} -liconv -lcharset +Cflags: -I\${includedir} +EOF +} + +create_libmp3lame_package_config() { + local LAME_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libmp3lame.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/lame +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libmp3lame +Description: lame mp3 encoder library +Version: ${LAME_VERSION} + +Requires: +Libs: -L\${libdir} -lmp3lame +Cflags: -I\${includedir} +EOF +} + +create_libvorbis_package_config() { + local LIBVORBIS_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/vorbis.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbis +Description: vorbis is the primary Ogg Vorbis library +Version: ${LIBVORBIS_VERSION} + +Requires: ogg +Libs: -L\${libdir} -lvorbis -lm +Cflags: -I\${includedir} +EOF + +cat > "${INSTALL_PKG_CONFIG_DIR}/vorbisenc.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbisenc +Description: vorbisenc is a library that provides a convenient API for setting up an encoding environment using libvorbis +Version: ${LIBVORBIS_VERSION} + +Requires: vorbis +Conflicts: +Libs: -L\${libdir} -lvorbisenc +Cflags: -I\${includedir} +EOF + +cat > "${INSTALL_PKG_CONFIG_DIR}/vorbisfile.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbisfile +Description: vorbisfile is a library that provides a convenient high-level API for decoding and basic manipulation of all Vorbis I audio streams +Version: ${LIBVORBIS_VERSION} + +Requires: vorbis +Conflicts: +Libs: -L\${libdir} -lvorbisfile +Cflags: -I\${includedir} +EOF +} + +create_libxml2_package_config() { + local LIBXML2_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libxml-2.0.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/libxml2 +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include +modules=1 + +Name: libXML +Version: ${LIBXML2_VERSION} +Description: libXML library version2. +Requires: libiconv +Libs: -L\${libdir} -lxml2 +Libs.private: -lz -lm +Cflags: -I\${includedir} -I\${includedir}/libxml2 +EOF +} + +create_snappy_package_config() { + local SNAPPY_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/snappy.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/snappy +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: snappy +Description: a fast compressor/decompressor +Version: ${SNAPPY_VERSION} + +Requires: +Libs: -L\${libdir} -lz -lc++ +Cflags: -I\${includedir} +EOF +} + +create_soxr_package_config() { + local SOXR_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/soxr.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/soxr +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: soxr +Description: High quality, one-dimensional sample-rate conversion library +Version: ${SOXR_VERSION} + +Requires: +Libs: -L\${libdir} -lsoxr +Cflags: -I\${includedir} +EOF +} + +create_tesseract_package_config() { + local TESSERACT_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/tesseract.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/tesseract +exec_prefix=\${prefix} +bindir=\${exec_prefix}/bin +datarootdir=\${prefix}/share +datadir=\${datarootdir} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: tesseract +Description: An OCR Engine that was developed at HP Labs between 1985 and 1995... and now at Google. +URL: https://github.com/tesseract-ocr/tesseract +Version: ${TESSERACT_VERSION} + +Requires: lept, libjpeg, libpng, giflib, zlib, libwebp, libtiff-4 +Libs: -L\${libdir} -ltesseract -lc++_shared +Cflags: -I\${includedir} +EOF +} + +create_uuid_package_config() { + local UUID_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/uuid.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/libuuid +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: uuid +Description: Universally unique id library +Version: ${UUID_VERSION} +Requires: +Cflags: -I\${includedir} +Libs: -L\${libdir} -luuid +EOF +} + +create_x265_package_config() { + local X265_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/x265.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/x265 +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: x265 +Description: H.265/HEVC video encoder +Version: ${X265_VERSION} + +Requires: +Libs: -L\${libdir} -lx265 +Libs.private: -lm -lgcc -lgcc -ldl -lgcc -lgcc -ldl -lc++_shared +Cflags: -I\${includedir} +EOF +} + +create_xvidcore_package_config() { + local XVIDCORE_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/xvidcore.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/xvidcore +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: xvidcore +Description: the main MPEG-4 de-/encoding library +Version: ${XVIDCORE_VERSION} + +Requires: +Libs: -L\${libdir} +Cflags: -I\${includedir} +EOF +} + +create_zlib_system_package_config() { + ZLIB_VERSION=$(grep '#define ZLIB_VERSION' ${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${TOOLCHAIN}/sysroot/usr/include/zlib.h | grep -Eo '\".*\"' | sed -e 's/\"//g') + + cat > "${INSTALL_PKG_CONFIG_DIR}/zlib.pc" << EOF +prefix=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${TOOLCHAIN}/sysroot/usr +exec_prefix=\${prefix} +libdir=${ANDROID_NDK_ROOT}/platforms/android-${API}/arch-${TOOLCHAIN_ARCH}/usr/lib +includedir=\${prefix}/include + +Name: zlib +Description: zlib compression library +Version: ${ZLIB_VERSION} + +Requires: +Libs: -L\${libdir} -lz +Cflags: -I\${includedir} +EOF +} + +create_cpufeatures_package_config() { + cat > "${INSTALL_PKG_CONFIG_DIR}/cpu-features.pc" << EOF +prefix=${BASEDIR}/prebuilt/android-$(get_target_build)/cpu-features +exec_prefix=\${prefix}/bin +libdir=\${prefix}/lib +includedir=\${prefix}/include/ndk_compat + +Name: cpufeatures +URL: https://github.com/google/cpu_features +Description: cpu_features Android compatibility library +Version: 1.${API} + +Requires: +Libs: -L\${libdir} -lndk_compat +Cflags: -I\${includedir} +EOF +} + +android_ndk_abi() { # to be used with CMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake + case ${ARCH} in + arm-v7a | arm-v7a-neon) + echo "armeabi-v7a" + ;; + arm64-v8a) + echo "arm64-v8a" + ;; + x86) + echo "x86" + ;; + x86-64) + echo "x86_64" + ;; + esac +} + +android_build_dir() { + echo ${BASEDIR}/android/build/${LIB_NAME}/$(get_target_build) +} + +android_ndk_cmake() { + local cmake=$(find ${ANDROID_HOME}/cmake -path \*/bin/cmake -type f -print -quit) + if [[ -z ${cmake} ]]; then + cmake=$(which cmake) + fi + if [[ -z ${cmake} ]]; then + cmake="missing_cmake" + fi + + echo ${cmake} \ + -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake \ + -H${BASEDIR}/src/${LIB_NAME} \ + -B$(android_build_dir) \ + -DANDROID_ABI=$(android_ndk_abi) \ + -DANDROID_PLATFORM=android-${API} \ + -DCMAKE_INSTALL_PREFIX=${BASEDIR}/prebuilt/android-$(get_target_build)/${LIB_NAME} +} + +set_toolchain_clang_paths() { + export PATH=$PATH:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${TOOLCHAIN}/bin + + BUILD_HOST=$(get_build_host) + + export AR=${BUILD_HOST}-ar + export CC=$(get_clang_target_host)-clang + export CXX=$(get_clang_target_host)-clang++ + + if [ "$1" == "x264" ]; then + export AS=${CC} + else + export AS=${BUILD_HOST}-as + fi + + case ${ARCH} in + arm64-v8a) + export ac_cv_c_bigendian=no + ;; + esac + + export LD=${BUILD_HOST}-ld + export RANLIB=${BUILD_HOST}-ranlib + export STRIP=${BUILD_HOST}-strip + + export INSTALL_PKG_CONFIG_DIR="${BASEDIR}/prebuilt/android-$(get_target_build)/pkgconfig" + export ZLIB_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/zlib.pc" + + if [ ! -d ${INSTALL_PKG_CONFIG_DIR} ]; then + mkdir -p ${INSTALL_PKG_CONFIG_DIR} + fi + + if [ ! -f ${ZLIB_PACKAGE_CONFIG_PATH} ]; then + create_zlib_system_package_config + fi + + prepare_inline_sed +} + +build_android_lts_support() { + + # CLEAN OLD BUILD + rm -f ${BASEDIR}/android/app/src/main/cpp/android_lts_support.o 1>>${BASEDIR}/build.log 2>&1 + rm -f ${BASEDIR}/android/app/src/main/cpp/android_lts_support.a 1>>${BASEDIR}/build.log 2>&1 + + echo -e "INFO: Building android-lts-support objects for ${ARCH}\n" 1>>${BASEDIR}/build.log 2>&1 + + # PREPARING PATHS + LIB_NAME="android-lts-support" + set_toolchain_clang_paths ${LIB_NAME} + + # PREPARING FLAGS + BUILD_HOST=$(get_build_host) + CFLAGS=$(get_cflags ${LIB_NAME}) + LDFLAGS=$(get_ldflags ${LIB_NAME}) + + # THEN BUILD FOR THIS ABI + $(get_clang_target_host)-clang ${CFLAGS} -Wno-unused-command-line-argument -c ${BASEDIR}/android/app/src/main/cpp/android_lts_support.c -o ${BASEDIR}/android/app/src/main/cpp/android_lts_support.o ${LDFLAGS} 1>>${BASEDIR}/build.log 2>&1 + ${BUILD_HOST}-ar rcs ${BASEDIR}/android/app/src/main/cpp/libandroidltssupport.a ${BASEDIR}/android/app/src/main/cpp/android_lts_support.o 1>>${BASEDIR}/build.log 2>&1 +} diff --git a/scripts/common-arch.sh b/scripts/common-arch.sh new file mode 100755 index 0000000..8ee1cb0 --- /dev/null +++ b/scripts/common-arch.sh @@ -0,0 +1,1452 @@ +#!/bin/bash + +# DIRECTORY DEFINITIONS +export FFMPEG_KIT_TMPDIR="${BASEDIR}/.tmp" + +# ARCH INDEXES +ARCH_ARM_V7A=0 # android +ARCH_ARM_V7A_NEON=1 # android +ARCH_ARMV7=2 # ios +ARCH_ARMV7S=3 # ios +ARCH_ARM64_V8A=4 # android +ARCH_ARM64=5 # ios, tvos +ARCH_ARM64E=6 # ios +ARCH_I386=7 # ios +ARCH_X86=8 # android +ARCH_X86_64=9 # android, ios, tvos +ARCH_X86_64_MAC_CATALYST=10 # ios + +# LIBRARY INDEXES +LIBRARY_FONTCONFIG=0 +LIBRARY_FREETYPE=1 +LIBRARY_FRIBIDI=2 +LIBRARY_GMP=3 +LIBRARY_GNUTLS=4 +LIBRARY_LAME=5 +LIBRARY_LIBASS=6 +LIBRARY_LIBICONV=7 +LIBRARY_LIBTHEORA=8 +LIBRARY_LIBVORBIS=9 +LIBRARY_LIBVPX=10 +LIBRARY_LIBWEBP=11 +LIBRARY_LIBXML2=12 +LIBRARY_OPENCOREAMR=13 +LIBRARY_SHINE=14 +LIBRARY_SPEEX=15 +LIBRARY_WAVPACK=16 +LIBRARY_KVAZAAR=17 +LIBRARY_X264=18 +LIBRARY_XVIDCORE=19 +LIBRARY_X265=20 +LIBRARY_LIBVIDSTAB=21 +LIBRARY_RUBBERBAND=22 +LIBRARY_LIBILBC=23 +LIBRARY_OPUS=24 +LIBRARY_SNAPPY=25 +LIBRARY_SOXR=26 +LIBRARY_LIBAOM=27 +LIBRARY_CHROMAPRINT=28 +LIBRARY_TWOLAME=29 +LIBRARY_SDL=30 +LIBRARY_TESSERACT=31 +LIBRARY_OPENH264=32 +LIBRARY_VO_AMRWBENC=33 +LIBRARY_GIFLIB=34 +LIBRARY_JPEG=35 +LIBRARY_LIBOGG=36 +LIBRARY_LIBPNG=37 +LIBRARY_LIBUUID=38 +LIBRARY_NETTLE=39 +LIBRARY_TIFF=40 +LIBRARY_EXPAT=41 +LIBRARY_SNDFILE=42 +LIBRARY_LEPTONICA=43 +LIBRARY_LIBSAMPLERATE=44 +LIBRARY_CPU_FEATURES=45 +LIBRARY_ANDROID_ZLIB=46 +LIBRARY_ANDROID_MEDIA_CODEC=47 +LIBRARY_IOS_ZLIB=48 +LIBRARY_IOS_AUDIOTOOLBOX=49 +LIBRARY_IOS_BZIP2=50 +LIBRARY_IOS_VIDEOTOOLBOX=51 +LIBRARY_IOS_AVFOUNDATION=52 +LIBRARY_IOS_LIBICONV=53 +LIBRARY_IOS_LIBUUID=54 +LIBRARY_TVOS_ZLIB=55 +LIBRARY_TVOS_AUDIOTOOLBOX=56 +LIBRARY_TVOS_BZIP2=57 +LIBRARY_TVOS_VIDEOTOOLBOX=58 +LIBRARY_TVOS_LIBICONV=59 +LIBRARY_TVOS_LIBUUID=60 + +get_library_name() { + case $1 in + 0) echo "fontconfig" ;; + 1) echo "freetype" ;; + 2) echo "fribidi" ;; + 3) echo "gmp" ;; + 4) echo "gnutls" ;; + 5) echo "lame" ;; + 6) echo "libass" ;; + 7) echo "libiconv" ;; + 8) echo "libtheora" ;; + 9) echo "libvorbis" ;; + 10) echo "libvpx" ;; + 11) echo "libwebp" ;; + 12) echo "libxml2" ;; + 13) echo "opencore-amr" ;; + 14) echo "shine" ;; + 15) echo "speex" ;; + 16) echo "wavpack" ;; + 17) echo "kvazaar" ;; + 18) echo "x264" ;; + 19) echo "xvidcore" ;; + 20) echo "x265" ;; + 21) echo "libvidstab" ;; + 22) echo "rubberband" ;; + 23) echo "libilbc" ;; + 24) echo "opus" ;; + 25) echo "snappy" ;; + 26) echo "soxr" ;; + 27) echo "libaom" ;; + 28) echo "chromaprint" ;; + 29) echo "twolame" ;; + 30) echo "sdl" ;; + 31) echo "tesseract" ;; + 32) echo "openh264" ;; + 33) echo "vo-amrwbenc" ;; + 34) echo "giflib" ;; + 35) echo "jpeg" ;; + 36) echo "libogg" ;; + 37) echo "libpng" ;; + 38) echo "libuuid" ;; + 39) echo "nettle" ;; + 40) echo "tiff" ;; + 41) echo "expat" ;; + 42) echo "libsndfile" ;; + 43) echo "leptonica" ;; + 44) echo "libsamplerate" ;; + 45) echo "cpu-features" ;; + 46) echo "android-zlib" ;; + 47) echo "android-media-codec" ;; + 48) echo "ios-zlib" ;; + 49) echo "ios-audiotoolbox" ;; + 50) echo "ios-bzip2" ;; + 51) echo "ios-videotoolbox" ;; + 52) echo "ios-avfoundation" ;; + 53) echo "ios-libiconv" ;; + 54) echo "ios-libuuid" ;; + 55) echo "tvos-zlib" ;; + 56) echo "tvos-audiotoolbox" ;; + 57) echo "tvos-bzip2" ;; + 58) echo "tvos-videotoolbox" ;; + 59) echo "tvos-libiconv" ;; + 60) echo "tvos-libuuid" ;; + esac +} + +# +# 1. +# +is_library_supported_on_platform() { + case $1 in + 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20) + echo "1" + ;; + 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40) + echo "1" + ;; + 41 | 42 | 43 | 44) + echo "1" + ;; + + # ANDROID + 7 | 38 | 45 | 46 | 47) + if [[ ${FFMPEG_KIT_BUILD_TYPE} == "android" ]]; then + echo "1" + else + echo "0" + fi + ;; + + # IOS + 48 | 49 | 50 | 51 | 52 | 53 | 54) + if [[ ${FFMPEG_KIT_BUILD_TYPE} == "ios" ]]; then + echo "1" + else + echo "0" + fi + ;; + + # TVOS + 55 | 56 | 57 | 58 | 59 | 60) + if [[ ${FFMPEG_KIT_BUILD_TYPE} == "tvos" ]]; then + echo "1" + else + echo "0" + fi + ;; + *) + echo "0" + ;; + esac +} + +# +# 1. +# +is_arch_supported_on_platform() { + case $1 in + ARCH_X86_64) + echo "1" + ;; + + # ANDROID + ARCH_ARM_V7A | ARCH_ARM_V7A_NEON | ARCH_ARM64_V8A | ARCH_X86) + if [[ ${FFMPEG_KIT_BUILD_TYPE} == "android" ]]; then + echo "1" + else + echo "0" + fi + ;; + + # IOS + ARCH_ARMV7 | ARCH_ARMV7S | ARCH_ARM64E | ARCH_I386 | ARCH_X86_64_MAC_CATALYST) + if [[ ${FFMPEG_KIT_BUILD_TYPE} == "ios" ]]; then + echo "1" + else + echo "0" + fi + ;; + + # IOS OR TVOS + ARCH_ARM64) + if [[ ${FFMPEG_KIT_BUILD_TYPE} == "ios" ]] || [[ ${FFMPEG_KIT_BUILD_TYPE} == "tvos" ]]; then + echo "1" + else + echo "0" + fi + ;; + *) + echo "0" + ;; + esac +} + +get_arch_name() { + case $1 in + 0) echo "arm-v7a" ;; # android + 1) echo "arm-v7a-neon" ;; # android + 2) echo "armv7" ;; # ios + 3) echo "armv7s" ;; # ios + 4) echo "arm64-v8a" ;; # android + 5) echo "arm64" ;; # ios, tvos + 6) echo "arm64e" ;; # ios + 7) echo "i386" ;; # ios + 8) echo "x86" ;; # android + 9) echo "x86-64" ;; # android, ios, tvos + 10) echo "x86-64-mac-catalyst" ;; # ios + esac +} + +get_package_config_file_name() { + case $1 in + 1) echo "freetype2" ;; + 5) echo "libmp3lame" ;; + 8) echo "theora" ;; + 9) echo "vorbis" ;; + 10) echo "vpx" ;; + 12) echo "libxml-2.0" ;; + 13) echo "opencore-amrnb" ;; + 21) echo "vidstab" ;; + 27) echo "aom" ;; + 28) echo "libchromaprint" ;; + 30) echo "sdl2" ;; + 35) echo "libjpeg" ;; + 36) echo "ogg" ;; + 40) echo "libtiff-4" ;; + 42) echo "sndfile" ;; + 43) echo "lept" ;; + 44) echo "samplerate" ;; + 54 | 60) echo "uuid" ;; + *) echo "$(get_library_name "$1")" ;; + esac +} + +get_static_archive_name() { + case $1 in + 5) echo "libmp3lame.a" ;; + 6) echo "libass.a" ;; + 10) echo "libvpx.a" ;; + 12) echo "libxml2.a" ;; + 21) echo "libvidstab.a" ;; + 23) echo "libilbc.a" ;; + 27) echo "libaom.a" ;; + 29) echo "libtwolame.a" ;; + 30) echo "libSDL2.a" ;; + 31) echo "libtesseract.a" ;; + 34) echo "libgif.a" ;; + 36) echo "libogg.a" ;; + 37) echo "libpng.a" ;; + 42) echo "libsndfile.a" ;; + 43) echo "liblept.a" ;; + 44) echo "libsamplerate.a" ;; + *) echo lib"$(get_library_name "$1")".a ;; + esac +} + +get_build_host() { + case ${ARCH} in + arm-v7a | arm-v7a-neon) + echo "arm-linux-androideabi" + ;; + armv7 | armv7s | arm64e | i386 | x86-64-mac-catalyst) + echo "$(get_target_arch)-ios-darwin" + ;; + arm64-v8a) + echo "aarch64-linux-android" + ;; + arm64) + if [[ ${FFMPEG_KIT_BUILD_TYPE} == "ios" ]]; then + echo "$(get_target_arch)-ios-darwin" + elif [[ ${FFMPEG_KIT_BUILD_TYPE} == "tvos" ]]; then + echo "$(get_target_arch)-tvos-darwin" + fi + ;; + x86) + echo "i686-linux-android" + ;; + x86-64) + if [[ ${FFMPEG_KIT_BUILD_TYPE} == "android" ]]; then + echo "x86_64-linux-android" + elif [[ ${FFMPEG_KIT_BUILD_TYPE} == "ios" ]]; then + echo "$(get_target_arch)-ios-darwin" + elif [[ ${FFMPEG_KIT_BUILD_TYPE} == "tvos" ]]; then + echo "$(get_target_arch)-tvos-darwin" + fi + ;; + esac +} + +skip_library() { + SKIP_VARIABLE=$(echo "SKIP_$1" | sed "s/\-/\_/g") + + export ${SKIP_VARIABLE}=1 +} + +no_output_redirection() { + export NO_OUTPUT_REDIRECTION=1 +} + +no_workspace_cleanup_library() { + NO_WORKSPACE_CLEANUP_VARIABLE=$(echo "NO_WORKSPACE_CLEANUP_$1" | sed "s/\-/\_/g") + + export ${NO_WORKSPACE_CLEANUP_VARIABLE}=1 +} + +no_link_time_optimization() { + export NO_LINK_TIME_OPTIMIZATION=1 +} + +enable_debug() { + export FFMPEG_KIT_DEBUG="-g" + + BUILD_TYPE_ID+="debug " +} + +optimize_for_speed() { + export FFMPEG_KIT_OPTIMIZED_FOR_SPEED="1" +} + +print_unknown_option() { + echo -e "Unknown option \"$1\".\nSee $0 --help for available options." + exit 1 +} + +print_unknown_library() { + echo -e "Unknown library \"$1\".\nSee $0 --help for available libraries." + exit 1 +} + +print_unknown_arch() { + echo -e "Unknown architecture \"$1\".\nSee $0 --help for available architectures." + exit 1 +} + +display_version() { + COMMAND=$(echo $0 | sed -e 's/\.\///g') + + echo -e "\ +$COMMAND v$(get_ffmpeg_kit_version)\n +Copyright (c) 2020 Taner Sener\n +License LGPLv3.0: GNU LGPL version 3 or later\n\ +\n\ +This is free software: you can redistribute it and/or modify it under the terms of the \ +GNU Lesser General Public License as published by the Free Software Foundation, \ +either version 3 of the License, or (at your option) any later version." +} + +display_help_options() { + echo -e "Options:" + echo -e " -h, --help\t\t\tdisplay this help and exit" + echo -e " -v, --version\t\t\tdisplay version information and exit" + echo -e " -d, --debug\t\t\tbuild with debug information" + echo -e " -s, --speed\t\t\toptimize for speed instead of size" + echo -e " -l, --lts\t\t\tbuild lts packages to support API 16+ devices" + echo -e " -f, --force\t\t\tignore warnings" + if [ -n "$1" ]; then + echo -e "$1" + fi + echo -e "" +} + +display_help_licensing() { + echo -e "Licensing options:" + echo -e " --enable-gpl\t\t\tallow use of GPL libraries, created libs will be licensed under GPLv3.0 [no]\n" +} + +display_help_common_libraries() { + echo -e " --enable-chromaprint\t\tbuild with chromaprint [no]" + echo -e " --enable-fontconfig\t\tbuild with fontconfig [no]" + echo -e " --enable-freetype\t\tbuild with freetype [no]" + echo -e " --enable-fribidi\t\tbuild with fribidi [no]" + echo -e " --enable-gmp\t\t\tbuild with gmp [no]" + echo -e " --enable-gnutls\t\tbuild with gnutls [no]" + echo -e " --enable-kvazaar\t\tbuild with kvazaar [no]" + echo -e " --enable-lame\t\t\tbuild with lame [no]" + echo -e " --enable-libaom\t\tbuild with libaom [no]" + echo -e " --enable-libass\t\tbuild with libass [no]" + echo -e " --enable-libiconv\t\tbuild with libiconv [no]" + echo -e " --enable-libilbc\t\tbuild with libilbc [no]" + echo -e " --enable-libtheora\t\tbuild with libtheora [no]" + echo -e " --enable-libvorbis\t\tbuild with libvorbis [no]" + echo -e " --enable-libvpx\t\tbuild with libvpx [no]" + echo -e " --enable-libwebp\t\tbuild with libwebp [no]" + echo -e " --enable-libxml2\t\tbuild with libxml2 [no]" + echo -e " --enable-opencore-amr\t\tbuild with opencore-amr [no]" + echo -e " --enable-openh264\t\tbuild with openh264 [no]" + echo -e " --enable-opus\t\t\tbuild with opus [no]" + echo -e " --enable-sdl\t\t\tbuild with sdl [no]" + echo -e " --enable-shine\t\tbuild with shine [no]" + echo -e " --enable-snappy\t\tbuild with snappy [no]" + echo -e " --enable-soxr\t\t\tbuild with soxr [no]" + echo -e " --enable-speex\t\tbuild with speex [no]" + echo -e " --enable-tesseract\t\tbuild with tesseract [no]" + echo -e " --enable-twolame\t\tbuild with twolame [no]" + echo -e " --enable-vo-amrwbenc\t\tbuild with vo-amrwbenc [no]" + echo -e " --enable-wavpack\t\tbuild with wavpack [no]\n" +} + +display_help_gpl_libraries() { + echo -e "GPL libraries:" + echo -e " --enable-libvidstab\t\tbuild with libvidstab [no]" + echo -e " --enable-rubberband\t\tbuild with rubber band [no]" + echo -e " --enable-x264\t\t\tbuild with x264 [no]" + echo -e " --enable-x265\t\t\tbuild with x265 [no]" + echo -e " --enable-xvidcore\t\tbuild with xvidcore [no]\n" +} + +display_help_advanced_options() { + echo -e "Advanced options:" + echo -e " --reconf-LIBRARY\t\trun autoreconf before building LIBRARY [no]" + echo -e " --redownload-LIBRARY\t\tdownload LIBRARY even if it is detected as already downloaded [no]" + echo -e " --rebuild-LIBRARY\t\tbuild LIBRARY even if it is detected as already built [no]\n" +} + +# +# 1. +# +reconf_library() { + local RECONF_VARIABLE=$(echo "RECONF_$1" | sed "s/\-/\_/g") + local library_supported=0 + + for library in {0..60}; do + library_name=$(get_library_name ${library}) + local library_supported_on_platform=$(is_library_supported_on_platform ${library}) + + if [[ $1 != "ffmpeg" ]] && [[ ${library_name} == $1 ]] && [[ ${library_supported_on_platform} -eq 1 ]]; then + export ${RECONF_VARIABLE}=1 + RECONF_LIBRARIES+=($1) + library_supported=1 + fi + done + + if [[ ${library_supported} -eq 0 ]]; then + echo -e "INFO: --reconf flag detected for library $1 is not supported.\n" 1>>${BASEDIR}/build.log 2>&1 + fi +} + +# +# 1. +# +rebuild_library() { + local REBUILD_VARIABLE=$(echo "REBUILD_$1" | sed "s/\-/\_/g") + local library_supported=0 + + for library in {0..45}; do + library_name=$(get_library_name ${library}) + local library_supported_on_platform=$(is_library_supported_on_platform ${library}) + + if [[ $1 != "ffmpeg" ]] && [[ ${library_name} == $1 ]] && [[ ${library_supported_on_platform} -eq 1 ]]; then + export ${REBUILD_VARIABLE}=1 + REBUILD_LIBRARIES+=($1) + library_supported=1 + fi + done + + if [[ ${library_supported} -eq 0 ]]; then + echo -e "INFO: --rebuild flag detected for library $1 is not supported.\n" 1>>${BASEDIR}/build.log 2>&1 + fi +} + +# +# 1. +# +redownload_library() { + local REDOWNLOAD_VARIABLE=$(echo "REDOWNLOAD_$1" | sed "s/\-/\_/g") + local library_supported=0 + + for library in {0..45}; do + library_name=$(get_library_name ${library}) + local library_supported_on_platform=$(is_library_supported_on_platform ${library}) + + if [[ ${library_name} == $1 ]] && [[ ${library_supported_on_platform} -eq 1 ]]; then + export ${REDOWNLOAD_VARIABLE}=1 + REDOWNLOAD_LIBRARIES+=($1) + library_supported=1 + fi + done + + if [[ "ffmpeg" == $1 ]]; then + export ${REDOWNLOAD_VARIABLE}=1 + REDOWNLOAD_LIBRARIES+=($1) + library_supported=1 + fi + + if [[ ${library_supported} -eq 0 ]]; then + echo -e "INFO: --redownload flag detected for library $1 is not supported.\n" 1>>${BASEDIR}/build.log 2>&1 + fi +} + +enable_library() { + local library_supported_on_platform=$(is_library_supported_on_platform $1) + if [[ $library_supported_on_platform == "1" ]]; then + set_library $1 1 + else + print_unknown_library $1 + fi +} + +set_library() { + case $1 in + android-zlib) + ENABLED_LIBRARIES[LIBRARY_ANDROID_ZLIB]=$2 + ;; + android-media-codec) + ENABLED_LIBRARIES[LIBRARY_ANDROID_MEDIA_CODEC]=$2 + ;; + ios-zlib) + ENABLED_LIBRARIES[LIBRARY_IOS_ZLIB]=$2 + ;; + ios-audiotoolbox) + ENABLED_LIBRARIES[LIBRARY_IOS_AUDIOTOOLBOX]=$2 + ;; + ios-bzip2) + ENABLED_LIBRARIES[LIBRARY_IOS_BZIP2]=$2 + ;; + ios-videotoolbox) + ENABLED_LIBRARIES[LIBRARY_IOS_VIDEOTOOLBOX]=$2 + ;; + ios-avfoundation) + ENABLED_LIBRARIES[LIBRARY_IOS_AVFOUNDATION]=$2 + ;; + ios-libiconv) + ENABLED_LIBRARIES[LIBRARY_IOS_LIBICONV]=$2 + ;; + ios-libuuid) + ENABLED_LIBRARIES[LIBRARY_IOS_LIBUUID]=$2 + ;; + tvos-zlib) + ENABLED_LIBRARIES[LIBRARY_TVOS_ZLIB]=$2 + ;; + tvos-audiotoolbox) + ENABLED_LIBRARIES[LIBRARY_TVOS_AUDIOTOOLBOX]=$2 + ;; + tvos-bzip2) + ENABLED_LIBRARIES[LIBRARY_TVOS_BZIP2]=$2 + ;; + tvos-videotoolbox) + ENABLED_LIBRARIES[LIBRARY_TVOS_VIDEOTOOLBOX]=$2 + ;; + tvos-libiconv) + ENABLED_LIBRARIES[LIBRARY_TVOS_LIBICONV]=$2 + ;; + tvos-libuuid) + ENABLED_LIBRARIES[LIBRARY_TVOS_LIBUUID]=$2 + ;; + chromaprint) + ENABLED_LIBRARIES[LIBRARY_CHROMAPRINT]=$2 + ;; + fontconfig) + ENABLED_LIBRARIES[LIBRARY_FONTCONFIG]=$2 + ENABLED_LIBRARIES[LIBRARY_LIBUUID]=$2 + ENABLED_LIBRARIES[LIBRARY_EXPAT]=$2 + ENABLED_LIBRARIES[LIBRARY_LIBICONV]=$2 + set_library "freetype" $2 + ;; + freetype) + ENABLED_LIBRARIES[LIBRARY_FREETYPE]=$2 + ENABLED_LIBRARIES[LIBRARY_ZLIB]=$2 + set_library "libpng" $2 + ;; + fribidi) + ENABLED_LIBRARIES[LIBRARY_FRIBIDI]=$2 + ;; + gmp) + ENABLED_LIBRARIES[LIBRARY_GMP]=$2 + ;; + gnutls) + ENABLED_LIBRARIES[LIBRARY_GNUTLS]=$2 + ENABLED_LIBRARIES[LIBRARY_ZLIB]=$2 + set_library "nettle" $2 + set_library "gmp" $2 + set_library "libiconv" $2 + ;; + kvazaar) + ENABLED_LIBRARIES[LIBRARY_KVAZAAR]=$2 + ;; + lame) + ENABLED_LIBRARIES[LIBRARY_LAME]=$2 + set_library "libiconv" $2 + ;; + libaom) + ENABLED_LIBRARIES[LIBRARY_LIBAOM]=$2 + ;; + libass) + ENABLED_LIBRARIES[LIBRARY_LIBASS]=$2 + ENABLED_LIBRARIES[LIBRARY_LIBUUID]=$2 + ENABLED_LIBRARIES[LIBRARY_EXPAT]=$2 + set_library "freetype" $2 + set_library "fribidi" $2 + set_library "fontconfig" $2 + set_library "libiconv" $2 + ;; + libiconv) + ENABLED_LIBRARIES[LIBRARY_LIBICONV]=$2 + ;; + libilbc) + ENABLED_LIBRARIES[LIBRARY_LIBILBC]=$2 + ;; + libpng) + ENABLED_LIBRARIES[LIBRARY_LIBPNG]=$2 + ENABLED_LIBRARIES[LIBRARY_ZLIB]=$2 + ;; + libtheora) + ENABLED_LIBRARIES[LIBRARY_LIBTHEORA]=$2 + ENABLED_LIBRARIES[LIBRARY_LIBOGG]=$2 + set_library "libvorbis" $2 + ;; + libvidstab) + ENABLED_LIBRARIES[LIBRARY_LIBVIDSTAB]=$2 + ;; + libvorbis) + ENABLED_LIBRARIES[LIBRARY_LIBVORBIS]=$2 + ENABLED_LIBRARIES[LIBRARY_LIBOGG]=$2 + ;; + libvpx) + ENABLED_LIBRARIES[LIBRARY_LIBVPX]=$2 + ;; + libwebp) + ENABLED_LIBRARIES[LIBRARY_LIBWEBP]=$2 + ENABLED_LIBRARIES[LIBRARY_GIFLIB]=$2 + ENABLED_LIBRARIES[LIBRARY_JPEG]=$2 + set_library "tiff" $2 + set_library "libpng" $2 + ;; + libxml2) + ENABLED_LIBRARIES[LIBRARY_LIBXML2]=$2 + set_library "libiconv" $2 + ;; + opencore-amr) + ENABLED_LIBRARIES[LIBRARY_OPENCOREAMR]=$2 + ;; + openh264) + ENABLED_LIBRARIES[LIBRARY_OPENH264]=$2 + ;; + opus) + ENABLED_LIBRARIES[LIBRARY_OPUS]=$2 + ;; + rubberband) + ENABLED_LIBRARIES[LIBRARY_RUBBERBAND]=$2 + ENABLED_LIBRARIES[LIBRARY_SNDFILE]=$2 + ENABLED_LIBRARIES[LIBRARY_LIBSAMPLERATE]=$2 + ;; + sdl) + ENABLED_LIBRARIES[LIBRARY_SDL]=$2 + ;; + shine) + ENABLED_LIBRARIES[LIBRARY_SHINE]=$2 + ;; + snappy) + ENABLED_LIBRARIES[LIBRARY_SNAPPY]=$2 + ENABLED_LIBRARIES[LIBRARY_ZLIB]=$2 + ;; + soxr) + ENABLED_LIBRARIES[LIBRARY_SOXR]=$2 + ;; + speex) + ENABLED_LIBRARIES[LIBRARY_SPEEX]=$2 + ;; + tesseract) + ENABLED_LIBRARIES[LIBRARY_TESSERACT]=$2 + ENABLED_LIBRARIES[LIBRARY_LEPTONICA]=$2 + ENABLED_LIBRARIES[LIBRARY_LIBWEBP]=$2 + ENABLED_LIBRARIES[LIBRARY_GIFLIB]=$2 + ENABLED_LIBRARIES[LIBRARY_JPEG]=$2 + ENABLED_LIBRARIES[LIBRARY_ZLIB]=$2 + set_library "tiff" $2 + set_library "libpng" $2 + ;; + twolame) + ENABLED_LIBRARIES[LIBRARY_TWOLAME]=$2 + ENABLED_LIBRARIES[LIBRARY_SNDFILE]=$2 + ;; + vo-amrwbenc) + ENABLED_LIBRARIES[LIBRARY_VO_AMRWBENC]=$2 + ;; + wavpack) + ENABLED_LIBRARIES[LIBRARY_WAVPACK]=$2 + ;; + x264) + ENABLED_LIBRARIES[LIBRARY_X264]=$2 + ;; + x265) + ENABLED_LIBRARIES[LIBRARY_X265]=$2 + ;; + xvidcore) + ENABLED_LIBRARIES[LIBRARY_XVIDCORE]=$2 + ;; + expat | giflib | jpeg | leptonica | libogg | libsamplerate | libsndfile | libuuid) + # THESE LIBRARIES ARE NOT ENABLED DIRECTLY + ;; + nettle) + ENABLED_LIBRARIES[LIBRARY_NETTLE]=$2 + set_library "gmp" $2 + ;; + tiff) + ENABLED_LIBRARIES[LIBRARY_TIFF]=$2 + ENABLED_LIBRARIES[LIBRARY_JPEG]=$2 + ;; + *) + print_unknown_library $1 + ;; + esac +} + +disable_arch() { + local arch_supported_on_platform=$(is_arch_supported_on_platform $1) + if [[ $arch_supported_on_platform == "1" ]]; then + set_arch $1 0 + else + print_unknown_arch $1 + fi +} + +set_arch() { + case $1 in + arm-v7a) + ENABLED_ARCHITECTURES[ARCH_ARM_V7A]=$2 + ;; + arm-v7a-neon) + ENABLED_ARCHITECTURES[ARCH_ARM_V7A_NEON]=$2 + ;; + armv7) + ENABLED_ARCHITECTURES[ARCH_ARMV7]=$2 + ;; + armv7s) + ENABLED_ARCHITECTURES[ARCH_ARMV7S]=$2 + ;; + arm64-v8a) + ENABLED_ARCHITECTURES[ARCH_ARM64_V8A]=$2 + ;; + arm64) + ENABLED_ARCHITECTURES[ARCH_ARM64]=$2 + ;; + arm64e) + ENABLED_ARCHITECTURES[ARCH_ARM64E]=$2 + ;; + i386) + ENABLED_ARCHITECTURES[ARCH_I386]=$2 + ;; + x86) + ENABLED_ARCHITECTURES[ARCH_X86]=$2 + ;; + x86-64) + ENABLED_ARCHITECTURES[ARCH_X86_64]=$2 + ;; + x86-64-mac-catalyst) + ENABLED_ARCHITECTURES[ARCH_X86_64_MAC_CATALYST]=$2 + ;; + *) + print_unknown_arch $1 + ;; + esac +} + +print_enabled_architectures() { + echo -n "Architectures: " + + let enabled=0 + for print_arch in {0..10}; do + if [[ ${ENABLED_ARCHITECTURES[$print_arch]} -eq 1 ]]; then + if [[ ${enabled} -ge 1 ]]; then + echo -n ", " + fi + echo -n $(get_arch_name $print_arch) + enabled=$((${enabled} + 1)) + fi + done + + if [ ${enabled} -gt 0 ]; then + echo "" + else + echo "none" + fi +} + +print_enabled_libraries() { + echo -n "Libraries: " + + let enabled=0 + + for library in {48..60} {0..33}; do + if [[ ${ENABLED_LIBRARIES[$library]} -eq 1 ]]; then + if [[ ${enabled} -ge 1 ]]; then + echo -n ", " + fi + echo -n $(get_library_name $library) + enabled=$((${enabled} + 1)) + fi + done + + if [ ${enabled} -gt 0 ]; then + echo "" + else + echo "none" + fi +} + +print_reconfigure_requested_libraries() { + local counter=0 + + for RECONF_LIBRARY in "${RECONF_LIBRARIES[@]}"; do + if [[ ${counter} -eq 0 ]]; then + echo -n "Reconfigure: " + else + echo -n ", " + fi + + echo -n ${RECONF_LIBRARY} + + counter=$((${counter} + 1)) + done + + if [[ ${counter} -gt 0 ]]; then + echo "" + fi +} + +print_rebuild_requested_libraries() { + local counter=0 + + for REBUILD_LIBRARY in "${REBUILD_LIBRARIES[@]}"; do + if [[ ${counter} -eq 0 ]]; then + echo -n "Rebuild: " + else + echo -n ", " + fi + + echo -n ${REBUILD_LIBRARY} + + counter=$((${counter} + 1)) + done + + if [[ ${counter} -gt 0 ]]; then + echo "" + fi +} + +print_redownload_requested_libraries() { + local counter=0 + + for REDOWNLOAD_LIBRARY in "${REDOWNLOAD_LIBRARIES[@]}"; do + if [[ ${counter} -eq 0 ]]; then + echo -n "Redownload: " + else + echo -n ", " + fi + + echo -n ${REDOWNLOAD_LIBRARY} + + counter=$((${counter} + 1)) + done + + if [[ ${counter} -gt 0 ]]; then + echo "" + fi +} + +build_modulemap() { + local FILE_PATH="$1" + + cat >"${FILE_PATH}" <${FILE_PATH} < + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${FRAMEWORK_NAME} + CFBundleIdentifier + ${FRAMEWORK_ID} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${FRAMEWORK_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + ${FRAMEWORK_SHORT_VERSION} + CFBundleVersion + ${FRAMEWORK_VERSION} + CFBundleSignature + ???? + MinimumOSVersion + $6 + CFBundleSupportedPlatforms + + $7 + + NSPrincipalClass + + + +EOF +} + +# 1 - library name +# 2 - static library name +# 3 - library version +create_static_framework() { + local FRAMEWORK_PATH=${BASEDIR}/prebuilt/ios-framework/$1.framework + + mkdir -p "${FRAMEWORK_PATH}" 1>>"${BASEDIR}/build.log" 2>&1 || exit 1 + + local CAPITAL_CASE_LIBRARY_NAME=$(to_capital_case "$1") + + build_info_plist "${FRAMEWORK_PATH}/Info.plist" "${FFMPEG_LIB}" "com.arthenica.ffmpegkit.${CAPITAL_CASE_LIBRARY_NAME}" "$3" "$3" + + cp "${BASEDIR}/prebuilt/ios-universal/$1-universal/lib/$2" "${FRAMEWORK_PATH}/$1" 1>>"${BASEDIR}/build.log" 2>&1 + + echo "$?" +} + +# 1 - library index +get_external_library_license_path() { + case $1 in + 1) echo "${BASEDIR}/src/$(get_library_name "$1")/docs/LICENSE.TXT" ;; + 3) echo "${BASEDIR}/src/$(get_library_name "$1")/COPYING.LESSERv3" ;; + 25) echo "${BASEDIR}/src/$(get_library_name "$1")/COPYING.LGPL" ;; + 27) echo "${BASEDIR}/src/$(get_library_name "$1")/LICENSE.md" ;; + 29) echo "${BASEDIR}/src/$(get_library_name "$1")/COPYING.txt" ;; + 34) echo "${BASEDIR}/src/$(get_library_name "$1")/LICENSE.md " ;; + 37) echo "${BASEDIR}/src/$(get_library_name "$1")/COPYING.LESSERv3" ;; + 38) echo "${BASEDIR}/src/$(get_library_name "$1")/COPYRIGHT" ;; + 41) echo "${BASEDIR}/src/$(get_library_name "$1")/leptonica-license.txt" ;; + 4 | 9 | 12 | 18 | 20 | 26 | 31 | 36) echo "${BASEDIR}/src/$(get_library_name "$1")/LICENSE" ;; + *) echo "${BASEDIR}/src/$(get_library_name "$1")/COPYING" ;; + esac +} + +# +# 1. +# +autoreconf_library() { + echo -e "\nDEBUG: Running full autoreconf for $1\n" 1>>${BASEDIR}/build.log 2>&1 + + # FORCE INSTALL + (autoreconf --force --install) + + local EXTRACT_RC=$? + if [ ${EXTRACT_RC} -eq 0 ]; then + return + fi + + echo -e "\nDEBUG: Full autoreconf failed. Running full autoreconf with include for $1\n" 1>>${BASEDIR}/build.log 2>&1 + + # FORCE INSTALL WITH m4 + (autoreconf --force --install -I m4) + + EXTRACT_RC=$? + if [ ${EXTRACT_RC} -eq 0 ]; then + return + fi + + echo -e "\nDEBUG: Full autoreconf with include failed. Running autoreconf without force for $1\n" 1>>${BASEDIR}/build.log 2>&1 + + # INSTALL WITHOUT FORCE + (autoreconf --install) + + EXTRACT_RC=$? + if [ ${EXTRACT_RC} -eq 0 ]; then + return + fi + + echo -e "\nDEBUG: Autoreconf without force failed. Running autoreconf without force with include for $1\n" 1>>${BASEDIR}/build.log 2>&1 + + # INSTALL WITHOUT FORCE WITH m4 + (autoreconf --install -I m4) + + EXTRACT_RC=$? + if [ ${EXTRACT_RC} -eq 0 ]; then + return + fi + + echo -e "\nDEBUG: Autoreconf without force with include failed. Running default autoreconf for $1\n" 1>>${BASEDIR}/build.log 2>&1 + + # INSTALL DEFAULT + (autoreconf) + + EXTRACT_RC=$? + if [ ${EXTRACT_RC} -eq 0 ]; then + return + fi + + echo -e "\nDEBUG: Default autoreconf failed. Running default autoreconf with include for $1\n" 1>>${BASEDIR}/build.log 2>&1 + + # INSTALL DEFAULT WITH m4 + (autoreconf -I m4) + + EXTRACT_RC=$? + if [ ${EXTRACT_RC} -eq 0 ]; then + return + fi +} + +# +# 1. +# 2. +# 3. +# +clone_git_repository_with_commit_id() { + local RC + + (mkdir -p $2 1>>${BASEDIR}/build.log 2>&1) + + RC=$? + + if [ ${RC} -ne 0 ]; then + echo -e "\nDEBUG: Failed to create local directory $2\n" 1>>${BASEDIR}/build.log 2>&1 + rm -rf $2 1>>${BASEDIR}/build.log 2>&1 + echo ${RC} + return + fi + + (git clone $1 $2 --depth 1 1>>${BASEDIR}/build.log 2>&1) + + RC=$? + + if [ ${RC} -ne 0 ]; then + echo -e "\nDEBUG: Failed to clone $1\n" 1>>${BASEDIR}/build.log 2>&1 + rm -rf $2 1>>${BASEDIR}/build.log 2>&1 + echo ${RC} + return + fi + + cd $2 1>>${BASEDIR}/build.log 2>&1 + + RC=$? + + if [ ${RC} -ne 0 ]; then + echo -e "\nDEBUG: Failed to cd into $2\n" 1>>${BASEDIR}/build.log 2>&1 + rm -rf $2 1>>${BASEDIR}/build.log 2>&1 + echo ${RC} + return + fi + + (git fetch --depth 1 origin $3 1>>${BASEDIR}/build.log 2>&1) + + RC=$? + + if [ ${RC} -ne 0 ]; then + echo -e "\nDEBUG: Failed to fetch commit id $3 from $1\n" 1>>${BASEDIR}/build.log 2>&1 + rm -rf $2 1>>${BASEDIR}/build.log 2>&1 + echo ${RC} + return + fi + + (git checkout $3 1>>${BASEDIR}/build.log 2>&1) + + RC=$? + + if [ ${RC} -ne 0 ]; then + echo -e "\nDEBUG: Failed to checkout commit id $3 from $1\n" 1>>${BASEDIR}/build.log 2>&1 + echo ${RC} + return + fi + + echo ${RC} +} + +# +# 1. +# 2. +# 3. +# +clone_git_repository_with_tag() { + local RC + + (mkdir -p $3 1>>${BASEDIR}/build.log 2>&1) + + RC=$? + + if [ ${RC} -ne 0 ]; then + echo -e "\nDEBUG: Failed to create local directory $3\n" 1>>${BASEDIR}/build.log 2>&1 + rm -rf $3 1>>${BASEDIR}/build.log 2>&1 + echo ${RC} + return + fi + + (git clone --depth 1 --branch $2 $1 $3 1>>${BASEDIR}/build.log 2>&1) + + RC=$? + + if [ ${RC} -ne 0 ]; then + echo -e "\nDEBUG: Failed to clone $1 -> $2\n" 1>>${BASEDIR}/build.log 2>&1 + rm -rf $3 1>>${BASEDIR}/build.log 2>&1 + echo ${RC} + return + fi + + echo ${RC} +} + +# +# 1. +# 2. +# 3. +# +download() { + if [ ! -d "${FFMPEG_KIT_TMPDIR}" ]; then + mkdir -p "${FFMPEG_KIT_TMPDIR}" + fi + + (curl --fail --location $1 -o ${FFMPEG_KIT_TMPDIR}/$2 1>>${BASEDIR}/build.log 2>&1) + + local RC=$? + + if [ ${RC} -eq 0 ]; then + echo -e "\nDEBUG: Downloaded $1 to ${FFMPEG_KIT_TMPDIR}/$2\n" 1>>${BASEDIR}/build.log 2>&1 + else + rm -f ${FFMPEG_KIT_TMPDIR}/$2 1>>${BASEDIR}/build.log 2>&1 + + echo -e -n "\nINFO: Failed to download $1 to ${FFMPEG_KIT_TMPDIR}/$2, rc=${RC}. " 1>>${BASEDIR}/build.log 2>&1 + + if [ "$3" == "exit" ]; then + echo -e "DEBUG: Build will now exit.\n" 1>>${BASEDIR}/build.log 2>&1 + exit 1 + else + echo -e "DEBUG: Build will continue.\n" 1>>${BASEDIR}/build.log 2>&1 + fi + fi + + echo ${RC} +} + +download_library_source() { + local LIB_REPO_URL="" + local LIB_NAME="$1" + local LIB_LOCAL_PATH=${BASEDIR}/src/${LIB_NAME} + local SOURCE_ID="" + local LIBRARY_RC="" + local DOWNLOAD_RC="" + local SOURCE_TYPE="" + + echo -e "\nDEBUG: Downloading library source: $1\n" 1>>${BASEDIR}/build.log 2>&1 + + case $1 in + cpu-features) + LIB_REPO_URL="https://github.com/tanersener/cpu_features" + SOURCE_ID="v0.4.1.1" # TAG + SOURCE_TYPE="TAG" + ;; + ffmpeg) + LIB_REPO_URL="https://github.com/tanersener/FFmpeg" + SOURCE_ID="d222da435e63a2665b85c0305ad2cf8a07b1af6d" # COMMIT -> v4.4-dev-416 + SOURCE_TYPE="COMMIT" + ;; + esac + + LIBRARY_RC=$(library_is_downloaded "${LIB_NAME}") + + if [ ${LIBRARY_RC} -eq 0 ]; then + echo -e "INFO: $1 already downloaded. Source folder found at ${LIB_LOCAL_PATH}\n" 1>>${BASEDIR}/build.log 2>&1 + echo 0 + return + fi + + if [ ${SOURCE_TYPE} == "TAG" ]; then + DOWNLOAD_RC=$(clone_git_repository_with_tag "${LIB_REPO_URL}" "${SOURCE_ID}" "${LIB_LOCAL_PATH}") + else + DOWNLOAD_RC=$(clone_git_repository_with_commit_id "${LIB_REPO_URL}" "${LIB_LOCAL_PATH}" "${SOURCE_ID}") + fi + + if [ ${DOWNLOAD_RC} -ne 0 ]; then + echo -e "INFO: Downloading library $1 failed. Can not get library from ${LIB_REPO_URL}\n" 1>>${BASEDIR}/build.log 2>&1 + echo ${DOWNLOAD_RC} + else + echo -e "DEBUG: $1 library downloaded\n" 1>>${BASEDIR}/build.log 2>&1 + fi +} + +download_gpl_library_source() { + local GPL_LIB_URL="" + local GPL_LIB_FILE="" + local GPL_LIB_ORIG_DIR="" + local GPL_LIB_DEST_DIR="$1" + local GPL_LIB_SOURCE_PATH="${BASEDIR}/src/${GPL_LIB_DEST_DIR}" + local LIBRARY_RC="" + local DOWNLOAD_RC="" + + echo -e "\nDEBUG: Downloading GPL library source: $1\n" 1>>${BASEDIR}/build.log 2>&1 + + case $1 in + libvidstab) + GPL_LIB_URL="https://github.com/georgmartius/vid.stab/archive/v1.1.0.tar.gz" + GPL_LIB_FILE="v1.1.0.tar.gz" + GPL_LIB_ORIG_DIR="vid.stab-1.1.0" + ;; + x264) + GPL_LIB_URL="https://code.videolan.org/videolan/x264/-/archive/cde9a93319bea766a92e306d69059c76de970190/x264-cde9a93319bea766a92e306d69059c76de970190.tar.bz2" + GPL_LIB_FILE="x264-cde9a93319bea766a92e306d69059c76de970190.tar.bz2" + GPL_LIB_ORIG_DIR="x264-cde9a93319bea766a92e306d69059c76de970190" + ;; + x265) + GPL_LIB_URL="https://bitbucket.org/multicoreware/x265/downloads/x265_3.4.tar.gz" + GPL_LIB_FILE="x265_3.4.tar.gz" + GPL_LIB_ORIG_DIR="x265_3.4" + ;; + xvidcore) + GPL_LIB_URL="https://downloads.xvid.com/downloads/xvidcore-1.3.7.tar.gz" + GPL_LIB_FILE="xvidcore-1.3.7.tar.gz" + GPL_LIB_ORIG_DIR="xvidcore" + ;; + rubberband) + GPL_LIB_URL="https://breakfastquay.com/files/releases/rubberband-1.8.2.tar.bz2" + GPL_LIB_FILE="rubberband-1.8.2.tar.bz2" + GPL_LIB_ORIG_DIR="rubberband-1.8.2" + ;; + esac + + LIBRARY_RC=$(library_is_downloaded "${GPL_LIB_DEST_DIR}") + + if [ ${LIBRARY_RC} -eq 0 ]; then + echo -e "INFO: $1 already downloaded. Source folder found at ${GPL_LIB_SOURCE_PATH}\n" 1>>${BASEDIR}/build.log 2>&1 + echo 0 + return + fi + + local GPL_LIB_PACKAGE_PATH="${FFMPEG_KIT_TMPDIR}/${GPL_LIB_FILE}" + + echo -e "DEBUG: $1 source not found. Checking if library package ${GPL_LIB_FILE} is downloaded at ${GPL_LIB_PACKAGE_PATH} \n" 1>>${BASEDIR}/build.log 2>&1 + + if [ ! -f "${GPL_LIB_PACKAGE_PATH}" ]; then + echo -e "DEBUG: $1 library package not found. Downloading from ${GPL_LIB_URL}\n" 1>>${BASEDIR}/build.log 2>&1 + + DOWNLOAD_RC=$(download "${GPL_LIB_URL}" "${GPL_LIB_FILE}") + + if [ ${DOWNLOAD_RC} -ne 0 ]; then + echo -e "INFO: Downloading GPL library $1 failed. Can not get library package from ${GPL_LIB_URL}\n" 1>>${BASEDIR}/build.log 2>&1 + echo ${DOWNLOAD_RC} + return + else + echo -e "DEBUG: $1 library package downloaded\n" 1>>${BASEDIR}/build.log 2>&1 + fi + else + echo -e "DEBUG: $1 library package already downloaded\n" 1>>${BASEDIR}/build.log 2>&1 + fi + + local EXTRACT_COMMAND="" + + if [[ ${GPL_LIB_FILE} == *bz2 ]]; then + EXTRACT_COMMAND="tar jxf ${GPL_LIB_PACKAGE_PATH} --directory ${FFMPEG_KIT_TMPDIR}" + else + EXTRACT_COMMAND="tar zxf ${GPL_LIB_PACKAGE_PATH} --directory ${FFMPEG_KIT_TMPDIR}" + fi + + echo -e "DEBUG: Extracting library package ${GPL_LIB_FILE} inside ${FFMPEG_KIT_TMPDIR}\n" 1>>${BASEDIR}/build.log 2>&1 + + ${EXTRACT_COMMAND} 1>>${BASEDIR}/build.log 2>&1 + + local EXTRACT_RC=$? + + if [ ${EXTRACT_RC} -ne 0 ]; then + echo -e "\nINFO: Downloading GPL library $1 failed. Extract for library package ${GPL_LIB_FILE} completed with rc=${EXTRACT_RC}. Deleting failed files.\n" 1>>${BASEDIR}/build.log 2>&1 + rm -f ${GPL_LIB_PACKAGE_PATH} 1>>${BASEDIR}/build.log 2>&1 + rm -rf ${FFMPEG_KIT_TMPDIR}/${GPL_LIB_ORIG_DIR} 1>>${BASEDIR}/build.log 2>&1 + echo ${EXTRACT_RC} + return + fi + + echo -e "DEBUG: Extract completed. Copying library source to ${GPL_LIB_SOURCE_PATH}\n" 1>>${BASEDIR}/build.log 2>&1 + + COPY_COMMAND="cp -r ${FFMPEG_KIT_TMPDIR}/${GPL_LIB_ORIG_DIR} ${GPL_LIB_SOURCE_PATH}" + + ${COPY_COMMAND} 1>>${BASEDIR}/build.log 2>&1 + + local COPY_RC=$? + + if [ ${COPY_RC} -eq 0 ]; then + echo -e "DEBUG: Downloading GPL library source $1 completed successfully\n" 1>>${BASEDIR}/build.log 2>&1 + else + echo -e "\nINFO: Downloading GPL library $1 failed. Copying library source to ${GPL_LIB_SOURCE_PATH} completed with rc=${COPY_RC}\n" 1>>${BASEDIR}/build.log 2>&1 + rm -rf ${GPL_LIB_SOURCE_PATH} 1>>${BASEDIR}/build.log 2>&1 + echo ${COPY_RC} + return + fi +} + +get_cpu_count() { + if [ "$(uname)" == "Darwin" ]; then + echo $(sysctl -n hw.physicalcpu) + else + echo $(nproc) + fi +} + +# +# 1. +# +library_is_downloaded() { + local LOCAL_PATH + local LIB_NAME=$1 + local FILE_COUNT + local REDOWNLOAD_VARIABLE + REDOWNLOAD_VARIABLE=$(echo "REDOWNLOAD_$1" | sed "s/\-/\_/g") + + LOCAL_PATH=${BASEDIR}/src/${LIB_NAME} + + echo -e "DEBUG: Checking if ${LIB_NAME} is already downloaded at ${LOCAL_PATH}\n" 1>>${BASEDIR}/build.log 2>&1 + + if [ ! -d ${LOCAL_PATH} ]; then + echo -e "DEBUG: ${LOCAL_PATH} directory not found\n" 1>>${BASEDIR}/build.log 2>&1 + echo 1 + return + fi + + FILE_COUNT=$(ls -l ${LOCAL_PATH} | wc -l) + + if [[ ${FILE_COUNT} -eq 0 ]]; then + echo -e "DEBUG: No files found under ${LOCAL_PATH}\n" 1>>${BASEDIR}/build.log 2>&1 + echo 1 + return + fi + + if [[ ${REDOWNLOAD_VARIABLE} -eq 1 ]]; then + echo -e "INFO: ${LIB_NAME} library already downloaded but re-download requested\n" 1>>${BASEDIR}/build.log 2>&1 + rm -rf ${LOCAL_PATH} 1>>${BASEDIR}/build.log 2>&1 + echo 1 + else + echo -e "INFO: ${LIB_NAME} library already downloaded\n" 1>>${BASEDIR}/build.log 2>&1 + echo 0 + fi +} + +library_is_installed() { + local INSTALL_PATH=$1 + local LIB_NAME=$2 + local HEADER_COUNT + local LIB_COUNT + + echo -e "DEBUG: Checking if ${LIB_NAME} is already built and installed at ${INSTALL_PATH}/${LIB_NAME}\n" 1>>${BASEDIR}/build.log 2>&1 + + if [ ! -d ${INSTALL_PATH}/${LIB_NAME} ]; then + echo -e "DEBUG: ${INSTALL_PATH}/${LIB_NAME} directory not found\n" 1>>${BASEDIR}/build.log 2>&1 + echo 1 + return + fi + + if [ ! -d ${INSTALL_PATH}/${LIB_NAME}/lib ]; then + echo -e "DEBUG: ${INSTALL_PATH}/${LIB_NAME}/lib directory not found\n" 1>>${BASEDIR}/build.log 2>&1 + echo 1 + return + fi + + if [ ! -d ${INSTALL_PATH}/${LIB_NAME}/include ]; then + echo -e "DEBUG: ${INSTALL_PATH}/${LIB_NAME}/include directory not found\n" 1>>${BASEDIR}/build.log 2>&1 + echo 1 + return + fi + + HEADER_COUNT=$(ls -l ${INSTALL_PATH}/${LIB_NAME}/include | wc -l) + LIB_COUNT=$(ls -l ${INSTALL_PATH}/${LIB_NAME}/lib | wc -l) + + if [[ ${HEADER_COUNT} -eq 0 ]]; then + echo -e "DEBUG: No headers found under ${INSTALL_PATH}/${LIB_NAME}/include\n" 1>>${BASEDIR}/build.log 2>&1 + echo 1 + return + fi + + if [[ ${LIB_COUNT} -eq 0 ]]; then + echo -e "DEBUG: No libraries found under ${INSTALL_PATH}/${LIB_NAME}/lib\n" 1>>${BASEDIR}/build.log 2>&1 + echo 1 + return + fi + + echo -e "INFO: ${LIB_NAME} library is already built and installed\n" 1>>${BASEDIR}/build.log 2>&1 + + echo 0 +} + +prepare_inline_sed() { + if [ "$(uname)" == "Darwin" ]; then + export SED_INLINE="sed -i .tmp" + else + export SED_INLINE="sed -i" + fi +} + +to_capital_case() { + echo "$(echo ${1:0:1} | tr '[a-z]' '[A-Z]')${1:1}" +} diff --git a/scripts/common-ios.sh b/scripts/common-ios.sh new file mode 100755 index 0000000..225363f --- /dev/null +++ b/scripts/common-ios.sh @@ -0,0 +1,821 @@ +#!/bin/bash + +source "${BASEDIR}/scripts/common-arch.sh" + +get_target_host() { + case ${ARCH} in + x86-64-mac-catalyst) + echo "x86_64-apple-ios13.0-macabi" + ;; + *) + echo "$(get_target_arch)-ios-darwin" + ;; + esac +} + +get_target_build_directory() { + case ${ARCH} in + x86-64) + echo "ios-x86_64" + ;; + x86-64-mac-catalyst) + echo "ios-x86_64-mac-catalyst" + ;; + *) + echo "ios-${ARCH}" + ;; + esac +} + +get_target_arch() { + case ${ARCH} in + arm64 | arm64e) + echo "aarch64" + ;; + x86-64 | x86-64-mac-catalyst) + echo "x86_64" + ;; + *) + echo "${ARCH}" + ;; + esac +} + +get_target_sdk() { + echo "$(get_target_arch)-apple-ios${IOS_MIN_VERSION}" +} + +get_sdk_name() { + case ${ARCH} in + armv7 | armv7s | arm64 | arm64e) + echo "iphoneos" + ;; + i386 | x86-64) + echo "iphonesimulator" + ;; + x86-64-mac-catalyst) + echo "macosx" + ;; + esac +} + +get_sdk_path() { + echo "$(xcrun --sdk $(get_sdk_name) --show-sdk-path)" +} + +get_min_version_cflags() { + case ${ARCH} in + armv7 | armv7s | arm64 | arm64e) + echo "-miphoneos-version-min=${IOS_MIN_VERSION}" + ;; + i386 | x86-64) + echo "-mios-simulator-version-min=${IOS_MIN_VERSION}" + ;; + x86-64-mac-catalyst) + echo "-miphoneos-version-min=13.0" + ;; + esac +} + +get_common_includes() { + echo "-I${SDK_PATH}/usr/include" +} + +get_common_cflags() { + if [[ ! -z ${MOBILE_FFMPEG_LTS_BUILD} ]]; then + local LTS_BUILD_FLAG="-DMOBILE_FFMPEG_LTS " + fi + + local BUILD_DATE="-DMOBILE_FFMPEG_BUILD_DATE=$(date +%Y%m%d 2>>${BASEDIR}/build.log)" + + case ${ARCH} in + i386 | x86-64) + echo "-fstrict-aliasing -DIOS ${LTS_BUILD_FLAG}${BUILD_DATE} -isysroot ${SDK_PATH}" + ;; + x86-64-mac-catalyst) + echo "-fstrict-aliasing -fembed-bitcode ${LTS_BUILD_FLAG}${BUILD_DATE} -isysroot ${SDK_PATH}" + ;; + *) + echo "-fstrict-aliasing -fembed-bitcode -DIOS ${LTS_BUILD_FLAG}${BUILD_DATE} -isysroot ${SDK_PATH}" + ;; + esac +} + +get_arch_specific_cflags() { + case ${ARCH} in + armv7) + echo "-arch armv7 -target $(get_target_host) -march=armv7 -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -DMOBILE_FFMPEG_ARMV7" + ;; + armv7s) + echo "-arch armv7s -target $(get_target_host) -march=armv7s -mcpu=generic -mfpu=neon -mfloat-abi=softfp -DMOBILE_FFMPEG_ARMV7S" + ;; + arm64) + echo "-arch arm64 -target $(get_target_host) -march=armv8-a+crc+crypto -mcpu=generic -DMOBILE_FFMPEG_ARM64" + ;; + arm64e) + echo "-arch arm64e -target $(get_target_host) -march=armv8.3-a+crc+crypto -mcpu=generic -DMOBILE_FFMPEG_ARM64E" + ;; + i386) + echo "-arch i386 -target $(get_target_host) -march=i386 -mtune=intel -mssse3 -mfpmath=sse -m32 -DMOBILE_FFMPEG_I386" + ;; + x86-64) + echo "-arch x86_64 -target $(get_target_host) -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -DMOBILE_FFMPEG_X86_64" + ;; + x86-64-mac-catalyst) + echo "-arch x86_64 -target $(get_target_host) -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -DMOBILE_FFMPEG_X86_64_MAC_CATALYST -isysroot ${SDK_PATH} -isystem ${SDK_PATH}/System/iOSSupport/usr/include -iframework ${SDK_PATH}/System/iOSSupport/System/Library/Frameworks" + ;; + esac +} + +get_size_optimization_cflags() { + + local ARCH_OPTIMIZATION="" + case ${ARCH} in + armv7 | armv7s | arm64 | arm64e | x86-64-mac-catalyst) + ARCH_OPTIMIZATION="-Oz -Wno-ignored-optimization-argument" + ;; + i386 | x86-64) + ARCH_OPTIMIZATION="-O2 -Wno-ignored-optimization-argument" + ;; + esac + + echo "${ARCH_OPTIMIZATION}" +} + +get_size_optimization_asm_cflags() { + + local ARCH_OPTIMIZATION="" + case $1 in + jpeg | ffmpeg) + case ${ARCH} in + armv7 | armv7s | arm64 | arm64e | x86-64-mac-catalyst) + ARCH_OPTIMIZATION="-Oz" + ;; + i386 | x86-64) + ARCH_OPTIMIZATION="-O2" + ;; + esac + ;; + *) + ARCH_OPTIMIZATION=$(get_size_optimization_cflags $1) + ;; + esac + + echo "${ARCH_OPTIMIZATION}" +} + +get_app_specific_cflags() { + + local APP_FLAGS="" + case $1 in + fontconfig) + case ${ARCH} in + armv7 | armv7s | arm64 | arm64e) + APP_FLAGS="-std=c99 -Wno-unused-function -D__IPHONE_OS_MIN_REQUIRED -D__IPHONE_VERSION_MIN_REQUIRED=30000" + ;; + *) + APP_FLAGS="-std=c99 -Wno-unused-function" + ;; + esac + ;; + ffmpeg) + APP_FLAGS="-Wno-unused-function -Wno-deprecated-declarations" + ;; + jpeg) + APP_FLAGS="-Wno-nullability-completeness" + ;; + kvazaar) + APP_FLAGS="-std=gnu99 -Wno-unused-function" + ;; + leptonica) + APP_FLAGS="-std=c99 -Wno-unused-function -DOS_IOS" + ;; + libwebp | xvidcore) + APP_FLAGS="-fno-common -DPIC" + ;; + mobile-ffmpeg) + APP_FLAGS="-std=c99 -Wno-unused-function -Wall -Wno-deprecated-declarations -Wno-pointer-sign -Wno-switch -Wno-unused-result -Wno-unused-variable -DPIC -fobjc-arc" + ;; + sdl2) + APP_FLAGS="-DPIC -Wno-unused-function -D__IPHONEOS__" + ;; + shine) + APP_FLAGS="-Wno-unused-function" + ;; + soxr | snappy) + APP_FLAGS="-std=gnu99 -Wno-unused-function -DPIC" + ;; + openh264 | x265) + APP_FLAGS="-Wno-unused-function" + ;; + *) + APP_FLAGS="-std=c99 -Wno-unused-function" + ;; + esac + + echo "${APP_FLAGS}" +} + +get_cflags() { + local ARCH_FLAGS=$(get_arch_specific_cflags) + local APP_FLAGS=$(get_app_specific_cflags $1) + local COMMON_FLAGS=$(get_common_cflags) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS=$(get_size_optimization_cflags $1) + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + local MIN_VERSION_FLAGS=$(get_min_version_cflags $1) + local COMMON_INCLUDES=$(get_common_includes) + + echo "${ARCH_FLAGS} ${APP_FLAGS} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS} ${MIN_VERSION_FLAGS} ${COMMON_INCLUDES}" +} + +get_asmflags() { + local ARCH_FLAGS=$(get_arch_specific_cflags) + local APP_FLAGS=$(get_app_specific_cflags $1) + local COMMON_FLAGS=$(get_common_cflags) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS=$(get_size_optimization_asm_cflags $1) + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + local MIN_VERSION_FLAGS=$(get_min_version_cflags $1) + local COMMON_INCLUDES=$(get_common_includes) + + echo "${ARCH_FLAGS} ${APP_FLAGS} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS} ${MIN_VERSION_FLAGS} ${COMMON_INCLUDES}" +} + +get_cxxflags() { + local COMMON_CFLAGS="$(get_common_cflags $1) $(get_common_includes $1) $(get_arch_specific_cflags) $(get_min_version_cflags $1)" + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS="-Oz" + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + + local BITCODE_FLAGS="" + case ${ARCH} in + armv7 | armv7s | arm64 | arm64e | x86-64-mac-catalyst) + local BITCODE_FLAGS="-fembed-bitcode" + ;; + esac + + case $1 in + x265) + echo "-std=c++11 -fno-exceptions ${BITCODE_FLAGS} ${COMMON_CFLAGS}" + ;; + gnutls) + echo "-std=c++11 -fno-rtti ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + libwebp | xvidcore) + echo "-std=c++11 -fno-exceptions -fno-rtti ${BITCODE_FLAGS} -fno-common -DPIC ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + libaom) + echo "-std=c++11 -fno-exceptions ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + opencore-amr) + echo "-fno-rtti ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + rubberband) + echo "-fno-rtti ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + *) + echo "-std=c++11 -fno-exceptions -fno-rtti ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + esac +} + +get_common_linked_libraries() { + echo "-L${SDK_PATH}/usr/lib -lc++" +} + +get_common_ldflags() { + echo "-isysroot ${SDK_PATH}" +} + +get_size_optimization_ldflags() { + case ${ARCH} in + armv7 | armv7s | arm64 | arm64e | x86-64-mac-catalyst) + case $1 in + ffmpeg | mobile-ffmpeg) + echo "-Oz -dead_strip" + ;; + *) + echo "-Oz -dead_strip" + ;; + esac + ;; + *) + case $1 in + ffmpeg) + echo "-O2" + ;; + *) + echo "-O2" + ;; + esac + ;; + esac +} + +get_arch_specific_ldflags() { + case ${ARCH} in + armv7) + echo "-arch armv7 -march=armv7 -mfpu=neon -mfloat-abi=softfp -fembed-bitcode -target $(get_target_host)" + ;; + armv7s) + echo "-arch armv7s -march=armv7s -mfpu=neon -mfloat-abi=softfp -fembed-bitcode -target $(get_target_host)" + ;; + arm64) + echo "-arch arm64 -march=armv8-a+crc+crypto -fembed-bitcode -target $(get_target_host)" + ;; + arm64e) + echo "-arch arm64e -march=armv8.3-a+crc+crypto -fembed-bitcode -target $(get_target_host)" + ;; + i386) + echo "-arch i386 -march=i386 -target $(get_target_host)" + ;; + x86-64) + echo "-arch x86_64 -march=x86-64 -target $(get_target_host)" + ;; + x86-64-mac-catalyst) + echo "-arch x86_64 -march=x86-64 -target $(get_target_host) -isysroot ${SDK_PATH} -L${SDK_PATH}/System/iOSSupport/usr/lib -iframework ${SDK_PATH}/System/iOSSupport/System/Library/Frameworks" + ;; + esac +} + +get_ldflags() { + local ARCH_FLAGS=$(get_arch_specific_ldflags) + local LINKED_LIBRARIES=$(get_common_linked_libraries) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS="$(get_size_optimization_ldflags $1)" + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + local COMMON_FLAGS=$(get_common_ldflags) + + case $1 in + mobile-ffmpeg) + case ${ARCH} in + armv7 | armv7s | arm64 | arm64e | x86-64-mac-catalyst) + echo "${ARCH_FLAGS} ${LINKED_LIBRARIES} ${COMMON_FLAGS} -fembed-bitcode -Wc,-fembed-bitcode ${OPTIMIZATION_FLAGS}" + ;; + *) + echo "${ARCH_FLAGS} ${LINKED_LIBRARIES} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS}" + ;; + esac + ;; + *) + echo "${ARCH_FLAGS} ${LINKED_LIBRARIES} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS}" + ;; + esac +} + +create_fontconfig_package_config() { + local FONTCONFIG_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/fontconfig.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/fontconfig +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include +sysconfdir=\${prefix}/etc +localstatedir=\${prefix}/var +PACKAGE=fontconfig +confdir=\${sysconfdir}/fonts +cachedir=\${localstatedir}/cache/\${PACKAGE} + +Name: Fontconfig +Description: Font configuration and customization library +Version: ${FONTCONFIG_VERSION} +Requires: freetype2 >= 21.0.15, uuid, expat >= 2.2.0, libiconv +Requires.private: +Libs: -L\${libdir} -lfontconfig +Libs.private: +Cflags: -I\${includedir} +EOF +} + +create_freetype_package_config() { + local FREETYPE_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/freetype2.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/freetype +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: FreeType 2 +URL: https://freetype.org +Description: A free, high-quality, and portable font engine. +Version: ${FREETYPE_VERSION} +Requires: libpng +Requires.private: +Libs: -L\${libdir} -lfreetype +Libs.private: +Cflags: -I\${includedir}/freetype2 +EOF +} + +create_giflib_package_config() { + local GIFLIB_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/giflib.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/giflib +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: giflib +Description: gif library +Version: ${GIFLIB_VERSION} + +Requires: +Libs: -L\${libdir} -lgif +Cflags: -I\${includedir} +EOF +} + +create_gmp_package_config() { + local GMP_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/gmp.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/gmp +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: gmp +Description: gnu mp library +Version: ${GMP_VERSION} + +Requires: +Libs: -L\${libdir} -lgmp +Cflags: -I\${includedir} +EOF +} + +create_gnutls_package_config() { + local GNUTLS_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/gnutls.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/gnutls +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: gnutls +Description: GNU TLS Implementation + +Version: ${GNUTLS_VERSION} +Requires: nettle, hogweed +Cflags: -I\${includedir} +Libs: -L\${libdir} -lgnutls +Libs.private: -lgmp +EOF +} + +create_libmp3lame_package_config() { + local LAME_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libmp3lame.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/lame +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libmp3lame +Description: lame mp3 encoder library +Version: ${LAME_VERSION} + +Requires: +Libs: -L\${libdir} -lmp3lame +Cflags: -I\${includedir} +EOF +} + +create_libiconv_system_package_config() { + local LIB_ICONV_VERSION=$(grep '_LIBICONV_VERSION' ${SDK_PATH}/usr/include/iconv.h | grep -Eo '0x.*' | grep -Eo '.* ') + + cat > "${INSTALL_PKG_CONFIG_DIR}/libiconv.pc" << EOF +prefix=${SDK_PATH}/usr +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libiconv +Description: Character set conversion library +Version: ${LIB_ICONV_VERSION} + +Requires: +Libs: -L\${libdir} -liconv -lcharset +Cflags: -I\${includedir} +EOF +} + +create_libpng_package_config() { + local LIBPNG_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libpng.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libpng +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libpng +Description: Loads and saves PNG files +Version: ${LIBPNG_VERSION} +Requires: +Cflags: -I\${includedir} +Libs: -L\${libdir} -lpng +EOF +} + +create_libvorbis_package_config() { + local LIBVORBIS_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/vorbis.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbis +Description: vorbis is the primary Ogg Vorbis library +Version: ${LIBVORBIS_VERSION} + +Requires: ogg +Libs: -L\${libdir} -lvorbis -lm +Cflags: -I\${includedir} +EOF + +cat > "${INSTALL_PKG_CONFIG_DIR}/vorbisenc.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbisenc +Description: vorbisenc is a library that provides a convenient API for setting up an encoding environment using libvorbis +Version: ${LIBVORBIS_VERSION} + +Requires: vorbis +Conflicts: +Libs: -L\${libdir} -lvorbisenc +Cflags: -I\${includedir} +EOF + +cat > "${INSTALL_PKG_CONFIG_DIR}/vorbisfile.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbisfile +Description: vorbisfile is a library that provides a convenient high-level API for decoding and basic manipulation of all Vorbis I audio streams +Version: ${LIBVORBIS_VERSION} + +Requires: vorbis +Conflicts: +Libs: -L\${libdir} -lvorbisfile +Cflags: -I\${includedir} +EOF +} + +create_libxml2_package_config() { + local LIBXML2_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libxml-2.0.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libxml2 +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include +modules=1 + +Name: libXML +Version: ${LIBXML2_VERSION} +Description: libXML library version2. +Requires: libiconv +Libs: -L\${libdir} -lxml2 +Libs.private: -lz -lm +Cflags: -I\${includedir} -I\${includedir}/libxml2 +EOF +} + +create_snappy_package_config() { + local SNAPPY_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/snappy.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/snappy +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: snappy +Description: a fast compressor/decompressor +Version: ${SNAPPY_VERSION} + +Requires: +Libs: -L\${libdir} -lz -lc++ +Cflags: -I\${includedir} +EOF +} + +create_soxr_package_config() { + local SOXR_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/soxr.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/soxr +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: soxr +Description: High quality, one-dimensional sample-rate conversion library +Version: ${SOXR_VERSION} + +Requires: +Libs: -L\${libdir} -lsoxr +Cflags: -I\${includedir} +EOF +} + +create_tesseract_package_config() { + local TESSERACT_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/tesseract.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/tesseract +exec_prefix=\${prefix} +bindir=\${exec_prefix}/bin +datarootdir=\${prefix}/share +datadir=\${datarootdir} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: tesseract +Description: An OCR Engine that was developed at HP Labs between 1985 and 1995... and now at Google. +URL: https://github.com/tesseract-ocr/tesseract +Version: ${TESSERACT_VERSION} + +Requires: lept +Libs: -L\${libdir} -ltesseract +Cflags: -I\${includedir} +EOF +} + +create_libuuid_system_package_config() { + local UUID_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/uuid.pc" << EOF +prefix=${SDK_PATH} +exec_prefix=\${prefix} +libdir=\${exec_prefix}/usr/lib +includedir=\${prefix}/include + +Name: uuid +Description: Universally unique id library +Version: ${UUID_VERSION} +Requires: +Cflags: -I\${includedir} +Libs: -L\${libdir} +EOF +} + +create_xvidcore_package_config() { + local XVIDCORE_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/xvidcore.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/xvidcore +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: xvidcore +Description: the main MPEG-4 de-/encoding library +Version: ${XVIDCORE_VERSION} + +Requires: +Libs: -L\${libdir} +Cflags: -I\${includedir} +EOF +} + +create_zlib_system_package_config() { + ZLIB_VERSION=$(grep '#define ZLIB_VERSION' ${SDK_PATH}/usr/include/zlib.h | grep -Eo '\".*\"' | sed -e 's/\"//g') + + cat > "${INSTALL_PKG_CONFIG_DIR}/zlib.pc" << EOF +prefix=${SDK_PATH}/usr +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: zlib +Description: zlib compression library +Version: ${ZLIB_VERSION} + +Requires: +Libs: -L\${libdir} -lz +Cflags: -I\${includedir} +EOF +} + +create_bzip2_system_package_config() { + BZIP2_VERSION=$(grep -Eo 'version.*of' ${SDK_PATH}/usr/include/bzlib.h | sed -e 's/of//;s/version//g;s/\ //g') + + cat > "${INSTALL_PKG_CONFIG_DIR}/bzip2.pc" << EOF +prefix=${SDK_PATH}/usr +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: bzip2 +Description: library for lossless, block-sorting data compression +Version: ${BZIP2_VERSION} + +Requires: +Libs: -L\${libdir} -lbz2 +Cflags: -I\${includedir} +EOF +} + +set_toolchain_clang_paths() { + if [ ! -f "${MOBILE_FFMPEG_TMPDIR}/gas-preprocessor.pl" ]; then + DOWNLOAD_RESULT=$(download "https://github.com/libav/gas-preprocessor/raw/master/gas-preprocessor.pl" "gas-preprocessor.pl" "exit") + if [[ ${DOWNLOAD_RESULT} -ne 0 ]]; then + exit 1 + fi + (chmod +x ${MOBILE_FFMPEG_TMPDIR}/gas-preprocessor.pl 1>>${BASEDIR}/build.log 2>&1) || exit 1 + + # patch gas-preprocessor.pl against the following warning + # Unescaped left brace in regex is deprecated here (and will be fatal in Perl 5.32), passed through in regex; marked by <-- HERE in m/(?:ld|st)\d\s+({ <-- HERE \s*v(\d+)\.(\d[bhsdBHSD])\s*-\s*v(\d+)\.(\d[bhsdBHSD])\s*})/ at /Users/taner/Projects/mobile-ffmpeg/.tmp/gas-preprocessor.pl line 1065. + sed -i .tmp "s/s\+({/s\+(\\\\{/g;s/s\*})/s\*\\\\})/g" ${MOBILE_FFMPEG_TMPDIR}/gas-preprocessor.pl + fi + + LOCAL_GAS_PREPROCESSOR="${MOBILE_FFMPEG_TMPDIR}/gas-preprocessor.pl" + if [ "$1" == "x264" ]; then + LOCAL_GAS_PREPROCESSOR="${BASEDIR}/src/x264/tools/gas-preprocessor.pl" + fi + + export AR="$(xcrun --sdk $(get_sdk_name) -f ar)" + export CC="clang" + export OBJC="$(xcrun --sdk $(get_sdk_name) -f clang)" + export CXX="clang++" + + LOCAL_ASMFLAGS="$(get_asmflags $1)" + case ${ARCH} in + armv7 | armv7s) + if [ "$1" == "x265" ]; then + export AS="${LOCAL_GAS_PREPROCESSOR}" + export AS_ARGUMENTS="-arch arm" + export ASM_FLAGS="${LOCAL_ASMFLAGS}" + else + export AS="${LOCAL_GAS_PREPROCESSOR} -arch arm -- ${CC} ${LOCAL_ASMFLAGS}" + fi + ;; + arm64 | arm64e) + if [ "$1" == "x265" ]; then + export AS="${LOCAL_GAS_PREPROCESSOR}" + export AS_ARGUMENTS="-arch aarch64" + export ASM_FLAGS="${LOCAL_ASMFLAGS}" + else + export AS="${LOCAL_GAS_PREPROCESSOR} -arch aarch64 -- ${CC} ${LOCAL_ASMFLAGS}" + fi + ;; + *) + export AS="${CC} ${LOCAL_ASMFLAGS}" + ;; + esac + + export LD="$(xcrun --sdk $(get_sdk_name) -f ld)" + export RANLIB="$(xcrun --sdk $(get_sdk_name) -f ranlib)" + export STRIP="$(xcrun --sdk $(get_sdk_name) -f strip)" + + export INSTALL_PKG_CONFIG_DIR="${BASEDIR}/prebuilt/$(get_target_build_directory)/pkgconfig" + export ZLIB_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/zlib.pc" + export BZIP2_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/bzip2.pc" + export LIB_ICONV_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/libiconv.pc" + export LIB_UUID_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/uuid.pc" + + if [ ! -d ${INSTALL_PKG_CONFIG_DIR} ]; then + mkdir -p ${INSTALL_PKG_CONFIG_DIR} + fi + + if [ ! -f ${ZLIB_PACKAGE_CONFIG_PATH} ]; then + create_zlib_system_package_config + fi + + if [ ! -f ${LIB_ICONV_PACKAGE_CONFIG_PATH} ]; then + create_libiconv_system_package_config + fi + + if [ ! -f ${BZIP2_PACKAGE_CONFIG_PATH} ]; then + create_bzip2_system_package_config + fi + + if [ ! -f ${LIB_UUID_PACKAGE_CONFIG_PATH} ]; then + create_libuuid_system_package_config + fi + + prepare_inline_sed +} diff --git a/scripts/common-tvos.sh b/scripts/common-tvos.sh new file mode 100755 index 0000000..49980dd --- /dev/null +++ b/scripts/common-tvos.sh @@ -0,0 +1,781 @@ +#!/bin/bash + +source "${BASEDIR}/scripts/common-arch.sh" + +get_target_build_directory() { + case ${ARCH} in + x86-64) + echo "tvos-x86_64-apple-darwin" + ;; + *) + echo "tvos-${ARCH}-apple-darwin" + ;; + esac +} + +get_target_arch() { + case ${ARCH} in + arm64) + echo "aarch64" + ;; + x86-64) + echo "x86_64" + ;; + *) + echo "${ARCH}" + ;; + esac +} + +get_target_sdk() { + echo "$(get_target_arch)-apple-tvos${TVOS_MIN_VERSION}" +} + +get_sdk_name() { + case ${ARCH} in + arm64) + echo "appletvos" + ;; + x86-64) + echo "appletvsimulator" + ;; + esac +} + +get_sdk_path() { + echo "$(xcrun --sdk $(get_sdk_name) --show-sdk-path)" +} + +get_min_version_cflags() { + case ${ARCH} in + arm64) + echo "-mappletvos-version-min=${TVOS_MIN_VERSION}" + ;; + x86-64) + echo "-mappletvsimulator-version-min=${TVOS_MIN_VERSION}" + ;; + esac +} + +get_common_includes() { + echo "-I${SDK_PATH}/usr/include" +} + +get_common_cflags() { + if [[ ! -z ${MOBILE_FFMPEG_LTS_BUILD} ]]; then + local LTS_BUILD_FLAG="-DMOBILE_FFMPEG_LTS " + fi + + local BUILD_DATE="-DMOBILE_FFMPEG_BUILD_DATE=$(date +%Y%m%d 2>>${BASEDIR}/build.log)" + + case ${ARCH} in + i386 | x86-64) + echo "-fstrict-aliasing -DTVOS ${LTS_BUILD_FLAG}${BUILD_DATE} -isysroot ${SDK_PATH}" + ;; + *) + echo "-fstrict-aliasing -fembed-bitcode -DTVOS ${LTS_BUILD_FLAG}${BUILD_DATE} -isysroot ${SDK_PATH}" + ;; + esac +} + +get_arch_specific_cflags() { + case ${ARCH} in + arm64) + echo "-arch arm64 -target $(get_build_host) -march=armv8-a+crc+crypto -mcpu=generic -DMOBILE_FFMPEG_ARM64" + ;; + x86-64) + echo "-arch x86_64 -target $(get_build_host) -march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel -DMOBILE_FFMPEG_X86_64" + ;; + esac +} + +get_size_optimization_cflags() { + + local ARCH_OPTIMIZATION="" + case ${ARCH} in + arm64) + case $1 in + x264 | x265) + ARCH_OPTIMIZATION="-Oz -Wno-ignored-optimization-argument" + ;; + ffmpeg | mobile-ffmpeg) + ARCH_OPTIMIZATION="-Oz -Wno-ignored-optimization-argument" + ;; + *) + ARCH_OPTIMIZATION="-Oz -Wno-ignored-optimization-argument" + ;; + esac + ;; + x86-64) + case $1 in + x264 | ffmpeg) + ARCH_OPTIMIZATION="-O2 -Wno-ignored-optimization-argument" + ;; + x265) + ARCH_OPTIMIZATION="-O2 -Wno-ignored-optimization-argument" + ;; + *) + ARCH_OPTIMIZATION="-O2 -Wno-ignored-optimization-argument" + ;; + esac + ;; + esac + + echo "${ARCH_OPTIMIZATION}" +} + +get_size_optimization_asm_cflags() { + + local ARCH_OPTIMIZATION="" + case $1 in + jpeg | ffmpeg) + case ${ARCH} in + arm64) + ARCH_OPTIMIZATION="-Oz" + ;; + x86-64) + ARCH_OPTIMIZATION="-O2" + ;; + esac + ;; + *) + ARCH_OPTIMIZATION=$(get_size_optimization_cflags $1) + ;; + esac + + echo "${ARCH_OPTIMIZATION}" +} + +get_app_specific_cflags() { + + local APP_FLAGS="" + case $1 in + fontconfig) + case ${ARCH} in + arm64) + APP_FLAGS="-std=c99 -Wno-unused-function -D__IPHONE_OS_MIN_REQUIRED -D__IPHONE_VERSION_MIN_REQUIRED=30000" + ;; + *) + APP_FLAGS="-std=c99 -Wno-unused-function" + ;; + esac + ;; + ffmpeg) + APP_FLAGS="-Wno-unused-function -Wno-deprecated-declarations" + ;; + jpeg) + APP_FLAGS="-Wno-nullability-completeness" + ;; + kvazaar) + APP_FLAGS="-std=gnu99 -Wno-unused-function" + ;; + leptonica) + APP_FLAGS="-std=c99 -Wno-unused-function -DOS_IOS" + ;; + libwebp | xvidcore) + APP_FLAGS="-fno-common -DPIC" + ;; + mobile-ffmpeg) + APP_FLAGS="-std=c99 -Wno-unused-function -Wall -Wno-deprecated-declarations -Wno-pointer-sign -Wno-switch -Wno-unused-result -Wno-unused-variable -DPIC -fobjc-arc" + ;; + sdl2) + APP_FLAGS="-DPIC -Wno-unused-function -D__TVOS__" + ;; + shine) + APP_FLAGS="-Wno-unused-function" + ;; + soxr | snappy) + APP_FLAGS="-std=gnu99 -Wno-unused-function -DPIC" + ;; + openh264 | x265) + APP_FLAGS="-Wno-unused-function" + ;; + *) + APP_FLAGS="-std=c99 -Wno-unused-function" + ;; + esac + + echo "${APP_FLAGS}" +} + +get_cflags() { + local ARCH_FLAGS=$(get_arch_specific_cflags) + local APP_FLAGS=$(get_app_specific_cflags $1) + local COMMON_FLAGS=$(get_common_cflags) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS=$(get_size_optimization_cflags $1) + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + local MIN_VERSION_FLAGS=$(get_min_version_cflags $1) + local COMMON_INCLUDES=$(get_common_includes) + + echo "${ARCH_FLAGS} ${APP_FLAGS} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS} ${MIN_VERSION_FLAGS} ${COMMON_INCLUDES}" +} + +get_asmflags() { + local ARCH_FLAGS=$(get_arch_specific_cflags) + local APP_FLAGS=$(get_app_specific_cflags $1) + local COMMON_FLAGS=$(get_common_cflags) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS=$(get_size_optimization_asm_cflags $1) + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + local MIN_VERSION_FLAGS=$(get_min_version_cflags $1) + local COMMON_INCLUDES=$(get_common_includes) + + echo "${ARCH_FLAGS} ${APP_FLAGS} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS} ${MIN_VERSION_FLAGS} ${COMMON_INCLUDES}" +} + +get_cxxflags() { + local COMMON_CFLAGS="$(get_common_cflags $1) $(get_common_includes $1) $(get_arch_specific_cflags) $(get_min_version_cflags $1)" + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS="-Oz" + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + + local BITCODE_FLAGS="" + case ${ARCH} in + arm64) + local BITCODE_FLAGS="-fembed-bitcode" + ;; + esac + + case $1 in + x265) + echo "-std=c++11 -fno-exceptions ${BITCODE_FLAGS} ${COMMON_CFLAGS}" + ;; + gnutls) + echo "-std=c++11 -fno-rtti ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + libwebp | xvidcore) + echo "-std=c++11 -fno-exceptions -fno-rtti ${BITCODE_FLAGS} -fno-common -DPIC ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + libaom) + echo "-std=c++11 -fno-exceptions ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + opencore-amr) + echo "-fno-rtti ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + rubberband) + echo "-fno-rtti ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + *) + echo "-std=c++11 -fno-exceptions -fno-rtti ${BITCODE_FLAGS} ${COMMON_CFLAGS} ${OPTIMIZATION_FLAGS}" + ;; + esac +} + +get_common_linked_libraries() { + echo "-L${SDK_PATH}/usr/lib -lc++" +} + +get_common_ldflags() { + echo "-isysroot ${SDK_PATH}" +} + +get_size_optimization_ldflags() { + case ${ARCH} in + arm64) + case $1 in + ffmpeg | mobile-ffmpeg) + echo "-Oz -dead_strip" + ;; + *) + echo "-Oz -dead_strip" + ;; + esac + ;; + *) + case $1 in + ffmpeg) + echo "-O2" + ;; + *) + echo "-O2" + ;; + esac + ;; + esac +} + +get_arch_specific_ldflags() { + case ${ARCH} in + arm64) + echo "-arch arm64 -march=armv8-a+crc+crypto -fembed-bitcode" + ;; + x86-64) + echo "-arch x86_64 -march=x86-64" + ;; + esac +} + +get_ldflags() { + local ARCH_FLAGS=$(get_arch_specific_ldflags) + local LINKED_LIBRARIES=$(get_common_linked_libraries) + if [[ -z ${MOBILE_FFMPEG_DEBUG} ]]; then + local OPTIMIZATION_FLAGS="$(get_size_optimization_ldflags $1)" + else + local OPTIMIZATION_FLAGS="${MOBILE_FFMPEG_DEBUG}" + fi + local COMMON_FLAGS=$(get_common_ldflags) + + case $1 in + mobile-ffmpeg) + case ${ARCH} in + arm64) + echo "${ARCH_FLAGS} ${LINKED_LIBRARIES} ${COMMON_FLAGS} -fembed-bitcode -Wc,-fembed-bitcode ${OPTIMIZATION_FLAGS}" + ;; + *) + echo "${ARCH_FLAGS} ${LINKED_LIBRARIES} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS}" + ;; + esac + ;; + *) + echo "${ARCH_FLAGS} ${LINKED_LIBRARIES} ${COMMON_FLAGS} ${OPTIMIZATION_FLAGS}" + ;; + esac +} + +create_fontconfig_package_config() { + local FONTCONFIG_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/fontconfig.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/fontconfig +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include +sysconfdir=\${prefix}/etc +localstatedir=\${prefix}/var +PACKAGE=fontconfig +confdir=\${sysconfdir}/fonts +cachedir=\${localstatedir}/cache/\${PACKAGE} + +Name: Fontconfig +Description: Font configuration and customization library +Version: ${FONTCONFIG_VERSION} +Requires: freetype2 >= 21.0.15, uuid, expat >= 2.2.0, libiconv +Requires.private: +Libs: -L\${libdir} -lfontconfig +Libs.private: +Cflags: -I\${includedir} +EOF +} + +create_freetype_package_config() { + local FREETYPE_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/freetype2.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/freetype +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: FreeType 2 +URL: https://freetype.org +Description: A free, high-quality, and portable font engine. +Version: ${FREETYPE_VERSION} +Requires: libpng +Requires.private: +Libs: -L\${libdir} -lfreetype +Libs.private: +Cflags: -I\${includedir}/freetype2 +EOF +} + +create_giflib_package_config() { + local GIFLIB_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/giflib.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/giflib +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: giflib +Description: gif library +Version: ${GIFLIB_VERSION} + +Requires: +Libs: -L\${libdir} -lgif +Cflags: -I\${includedir} +EOF +} + +create_gmp_package_config() { + local GMP_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/gmp.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/gmp +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: gmp +Description: gnu mp library +Version: ${GMP_VERSION} + +Requires: +Libs: -L\${libdir} -lgmp +Cflags: -I\${includedir} +EOF +} + +create_gnutls_package_config() { + local GNUTLS_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/gnutls.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/gnutls +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: gnutls +Description: GNU TLS Implementation + +Version: ${GNUTLS_VERSION} +Requires: nettle, hogweed +Cflags: -I\${includedir} +Libs: -L\${libdir} -lgnutls +Libs.private: -lgmp +EOF +} + +create_libmp3lame_package_config() { + local LAME_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libmp3lame.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/lame +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libmp3lame +Description: lame mp3 encoder library +Version: ${LAME_VERSION} + +Requires: +Libs: -L\${libdir} -lmp3lame +Cflags: -I\${includedir} +EOF +} + +create_libiconv_system_package_config() { + local LIB_ICONV_VERSION=$(grep '_LIBICONV_VERSION' ${SDK_PATH}/usr/include/iconv.h | grep -Eo '0x.*' | grep -Eo '.* ') + + cat > "${INSTALL_PKG_CONFIG_DIR}/libiconv.pc" << EOF +prefix=${SDK_PATH}/usr +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libiconv +Description: Character set conversion library +Version: ${LIB_ICONV_VERSION} + +Requires: +Libs: -L\${libdir} -liconv -lcharset +Cflags: -I\${includedir} +EOF +} + +create_libpng_package_config() { + local LIBPNG_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libpng.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libpng +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: libpng +Description: Loads and saves PNG files +Version: ${LIBPNG_VERSION} +Requires: +Cflags: -I\${includedir} +Libs: -L\${libdir} -lpng +EOF +} + +create_libvorbis_package_config() { + local LIBVORBIS_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/vorbis.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbis +Description: vorbis is the primary Ogg Vorbis library +Version: ${LIBVORBIS_VERSION} + +Requires: ogg +Libs: -L\${libdir} -lvorbis -lm +Cflags: -I\${includedir} +EOF + +cat > "${INSTALL_PKG_CONFIG_DIR}/vorbisenc.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbisenc +Description: vorbisenc is a library that provides a convenient API for setting up an encoding environment using libvorbis +Version: ${LIBVORBIS_VERSION} + +Requires: vorbis +Conflicts: +Libs: -L\${libdir} -lvorbisenc +Cflags: -I\${includedir} +EOF + +cat > "${INSTALL_PKG_CONFIG_DIR}/vorbisfile.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libvorbis +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: vorbisfile +Description: vorbisfile is a library that provides a convenient high-level API for decoding and basic manipulation of all Vorbis I audio streams +Version: ${LIBVORBIS_VERSION} + +Requires: vorbis +Conflicts: +Libs: -L\${libdir} -lvorbisfile +Cflags: -I\${includedir} +EOF +} + +create_libxml2_package_config() { + local LIBXML2_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/libxml-2.0.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/libxml2 +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include +modules=1 + +Name: libXML +Version: ${LIBXML2_VERSION} +Description: libXML library version2. +Requires: libiconv +Libs: -L\${libdir} -lxml2 +Libs.private: -lz -lm +Cflags: -I\${includedir} -I\${includedir}/libxml2 +EOF +} + +create_snappy_package_config() { + local SNAPPY_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/snappy.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/snappy +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: snappy +Description: a fast compressor/decompressor +Version: ${SNAPPY_VERSION} + +Requires: +Libs: -L\${libdir} -lz -lc++ +Cflags: -I\${includedir} +EOF +} + +create_soxr_package_config() { + local SOXR_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/soxr.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/soxr +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: soxr +Description: High quality, one-dimensional sample-rate conversion library +Version: ${SOXR_VERSION} + +Requires: +Libs: -L\${libdir} -lsoxr +Cflags: -I\${includedir} +EOF +} + +create_tesseract_package_config() { + local TESSERACT_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/tesseract.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/tesseract +exec_prefix=\${prefix} +bindir=\${exec_prefix}/bin +datarootdir=\${prefix}/share +datadir=\${datarootdir} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: tesseract +Description: An OCR Engine that was developed at HP Labs between 1985 and 1995... and now at Google. +URL: https://github.com/tesseract-ocr/tesseract +Version: ${TESSERACT_VERSION} + +Requires: lept +Libs: -L\${libdir} -ltesseract +Cflags: -I\${includedir} +EOF +} + +create_libuuid_system_package_config() { + local UUID_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/uuid.pc" << EOF +prefix=${SDK_PATH} +exec_prefix=\${prefix} +libdir=\${exec_prefix}/usr/lib +includedir=\${prefix}/include + +Name: uuid +Description: Universally unique id library +Version: ${UUID_VERSION} +Requires: +Cflags: -I\${includedir} +Libs: -L\${libdir} +EOF +} + +create_xvidcore_package_config() { + local XVIDCORE_VERSION="$1" + + cat > "${INSTALL_PKG_CONFIG_DIR}/xvidcore.pc" << EOF +prefix=${BASEDIR}/prebuilt/$(get_target_build_directory)/xvidcore +exec_prefix=\${prefix} +libdir=\${prefix}/lib +includedir=\${prefix}/include + +Name: xvidcore +Description: the main MPEG-4 de-/encoding library +Version: ${XVIDCORE_VERSION} + +Requires: +Libs: -L\${libdir} +Cflags: -I\${includedir} +EOF +} + +create_zlib_system_package_config() { + ZLIB_VERSION=$(grep '#define ZLIB_VERSION' ${SDK_PATH}/usr/include/zlib.h | grep -Eo '\".*\"' | sed -e 's/\"//g') + + cat > "${INSTALL_PKG_CONFIG_DIR}/zlib.pc" << EOF +prefix=${SDK_PATH}/usr +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: zlib +Description: zlib compression library +Version: ${ZLIB_VERSION} + +Requires: +Libs: -L\${libdir} -lz +Cflags: -I\${includedir} +EOF +} + +create_bzip2_system_package_config() { + BZIP2_VERSION=$(grep -Eo 'version.*of' ${SDK_PATH}/usr/include/bzlib.h | sed -e 's/of//;s/version//g;s/\ //g') + + cat > "${INSTALL_PKG_CONFIG_DIR}/bzip2.pc" << EOF +prefix=${SDK_PATH}/usr +exec_prefix=\${prefix} +libdir=\${exec_prefix}/lib +includedir=\${prefix}/include + +Name: bzip2 +Description: library for lossless, block-sorting data compression +Version: ${BZIP2_VERSION} + +Requires: +Libs: -L\${libdir} -lbz2 +Cflags: -I\${includedir} +EOF +} + +set_toolchain_clang_paths() { + if [ ! -f "${MOBILE_FFMPEG_TMPDIR}/gas-preprocessor.pl" ]; then + DOWNLOAD_RESULT=$(download "https://github.com/libav/gas-preprocessor/raw/master/gas-preprocessor.pl" "gas-preprocessor.pl" "exit") + if [[ ${DOWNLOAD_RESULT} -ne 0 ]]; then + exit 1 + fi + (chmod +x ${MOBILE_FFMPEG_TMPDIR}/gas-preprocessor.pl 1>>${BASEDIR}/build.log 2>&1) || exit 1 + + # patch gas-preprocessor.pl against the following warning + # Unescaped left brace in regex is deprecated here (and will be fatal in Perl 5.32), passed through in regex; marked by <-- HERE in m/(?:ld|st)\d\s+({ <-- HERE \s*v(\d+)\.(\d[bhsdBHSD])\s*-\s*v(\d+)\.(\d[bhsdBHSD])\s*})/ at /Users/taner/Projects/mobile-ffmpeg/.tmp/gas-preprocessor.pl line 1065. + sed -i .tmp "s/s\+({/s\+(\\\\{/g;s/s\*})/s\*\\\\})/g" ${MOBILE_FFMPEG_TMPDIR}/gas-preprocessor.pl + fi + + LOCAL_GAS_PREPROCESSOR="${MOBILE_FFMPEG_TMPDIR}/gas-preprocessor.pl" + if [ "$1" == "x264" ]; then + LOCAL_GAS_PREPROCESSOR="${BASEDIR}/src/x264/tools/gas-preprocessor.pl" + fi + + BUILD_HOST=$(get_build_host) + + export AR="$(xcrun --sdk $(get_sdk_name) -f ar)" + export CC="clang" + export OBJC="$(xcrun --sdk $(get_sdk_name) -f clang)" + export CXX="clang++" + + LOCAL_ASMFLAGS="$(get_asmflags $1)" + case ${ARCH} in + arm64) + if [ "$1" == "x265" ]; then + export AS="${LOCAL_GAS_PREPROCESSOR}" + export AS_ARGUMENTS="-arch aarch64" + export ASM_FLAGS="${LOCAL_ASMFLAGS}" + else + export AS="${LOCAL_GAS_PREPROCESSOR} -arch aarch64 -- ${CC} ${LOCAL_ASMFLAGS}" + fi + ;; + *) + export AS="${CC} ${LOCAL_ASMFLAGS}" + ;; + esac + + export LD="$(xcrun --sdk $(get_sdk_name) -f ld)" + export RANLIB="$(xcrun --sdk $(get_sdk_name) -f ranlib)" + export STRIP="$(xcrun --sdk $(get_sdk_name) -f strip)" + + export INSTALL_PKG_CONFIG_DIR="${BASEDIR}/prebuilt/$(get_target_build_directory)/pkgconfig" + export ZLIB_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/zlib.pc" + export BZIP2_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/bzip2.pc" + export LIB_ICONV_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/libiconv.pc" + export LIB_UUID_PACKAGE_CONFIG_PATH="${INSTALL_PKG_CONFIG_DIR}/uuid.pc" + + if [ ! -d ${INSTALL_PKG_CONFIG_DIR} ]; then + mkdir -p ${INSTALL_PKG_CONFIG_DIR} + fi + + if [ ! -f ${ZLIB_PACKAGE_CONFIG_PATH} ]; then + create_zlib_system_package_config + fi + + if [ ! -f ${LIB_ICONV_PACKAGE_CONFIG_PATH} ]; then + create_libiconv_system_package_config + fi + + if [ ! -f ${BZIP2_PACKAGE_CONFIG_PATH} ]; then + create_bzip2_system_package_config + fi + + if [ ! -f ${LIB_UUID_PACKAGE_CONFIG_PATH} ]; then + create_libuuid_system_package_config + fi + + prepare_inline_sed +} diff --git a/scripts/main-android.sh b/scripts/main-android.sh new file mode 100755 index 0000000..2436f68 --- /dev/null +++ b/scripts/main-android.sh @@ -0,0 +1,290 @@ +#!/bin/bash + +if [[ -z ${ANDROID_NDK_ROOT} ]]; then + echo -e "(*) ANDROID_NDK_ROOT not defined\n" + exit 1 +fi + +if [[ -z ${ARCH} ]]; then + echo -e "(*) ARCH not defined\n" + exit 1 +fi + +if [[ -z ${API} ]]; then + echo -e "(*) API not defined\n" + exit 1 +fi + +if [[ -z ${BASEDIR} ]]; then + echo -e "(*) BASEDIR not defined\n" + exit 1 +fi + +check_if_dependency_rebuilt() { + case $1 in + expat) + set_dependency_rebuilt_flag "fontconfig" + set_dependency_rebuilt_flag "libass" + ;; + fontconfig) + set_dependency_rebuilt_flag "libass" + ;; + freetype) + set_dependency_rebuilt_flag "fontconfig" + set_dependency_rebuilt_flag "libass" + ;; + fribidi) + set_dependency_rebuilt_flag "libass" + ;; + giflib) + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + gmp) + set_dependency_rebuilt_flag "gnutls" + set_dependency_rebuilt_flag "nettle" + ;; + jpeg) + set_dependency_rebuilt_flag "tiff" + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + leptonica) + set_dependency_rebuilt_flag "tesseract" + ;; + libiconv) + set_dependency_rebuilt_flag "fontconfig" + set_dependency_rebuilt_flag "gnutls" + set_dependency_rebuilt_flag "lame" + set_dependency_rebuilt_flag "libass" + set_dependency_rebuilt_flag "libxml2" + ;; + libogg) + set_dependency_rebuilt_flag "libvorbis" + set_dependency_rebuilt_flag "libtheora" + ;; + libpng) + set_dependency_rebuilt_flag "freetype" + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "libass" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + libsamplerate) + set_dependency_rebuilt_flag "rubberband" + ;; + libsndfile) + set_dependency_rebuilt_flag "twolame" + set_dependency_rebuilt_flag "rubberband" + ;; + libuuid) + set_dependency_rebuilt_flag "fontconfig" + set_dependency_rebuilt_flag "libass" + ;; + libvorbis) + set_dependency_rebuilt_flag "libtheora" + ;; + libwebp) + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + nettle) + set_dependency_rebuilt_flag "gnutls" + ;; + tiff) + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + esac +} + +set_dependency_rebuilt_flag() { + DEPENDENCY_REBUILT_VARIABLE=$(echo "DEPENDENCY_REBUILT_$1" | sed "s/\-/\_/g") + export "${DEPENDENCY_REBUILT_VARIABLE}"=1 +} + +# ENABLE COMMON FUNCTIONS +. ${BASEDIR}/scripts/android-common.sh + +echo -e "\nBuilding ${ARCH} platform on API level ${API}\n" +echo -e "\nINFO: Starting new build for ${ARCH} on API level ${API} at "$(date)"\n" 1>>${BASEDIR}/build.log 2>&1 +INSTALL_BASE="${BASEDIR}/prebuilt/android-$(get_target_build)" + +# CREATING PACKAGE CONFIG DIRECTORY +PKG_CONFIG_DIRECTORY="${INSTALL_BASE}/pkgconfig" +if [ ! -d ${PKG_CONFIG_DIRECTORY} ]; then + mkdir -p ${PKG_CONFIG_DIRECTORY} || exit 1 +fi + +# FILTERING WHICH EXTERNAL LIBRARIES WILL BE BUILT +# NOTE THAT BUILT-IN LIBRARIES ARE FORWARDED TO FFMPEG SCRIPT WITHOUT ANY PROCESSING +enabled_library_list=() +for library in {1..45} 48 +do + if [[ ${!library} -eq 1 ]]; then + ENABLED_LIBRARY=$(get_library_name $((library - 1))) + enabled_library_list+=(${ENABLED_LIBRARY}) + + echo -e "INFO: Enabled library ${ENABLED_LIBRARY}\n" 1>>${BASEDIR}/build.log 2>&1 + fi +done + +# BUILD LTS SUPPORT LIBRARY FOR API < 18 +if [[ -n ${FFMPEG_KIT_LTS_BUILD} ]] && [[ ${API} -lt 18 ]]; then + build_android_lts_support +fi + +let completed=0 +while [ ${#enabled_library_list[@]} -gt $completed ]; do + for library in "${enabled_library_list[@]}" + do + let run=0 + case $library in + fontconfig) + if [[ ! -z $OK_libuuid ]] && [[ ! -z $OK_expat ]] && [[ ! -z $OK_libiconv ]] && [[ ! -z $OK_freetype ]]; then + run=1 + fi + ;; + freetype) + if [[ ! -z $OK_libpng ]]; then + run=1 + fi + ;; + gnutls) + if [[ ! -z $OK_nettle ]] && [[ ! -z $OK_gmp ]] && [[ ! -z $OK_libiconv ]]; then + run=1 + fi + ;; + lame) + if [[ ! -z $OK_libiconv ]]; then + run=1 + fi + ;; + leptonica) + if [[ ! -z $OK_giflib ]] && [[ ! -z $OK_jpeg ]] && [[ ! -z $OK_libpng ]] && [[ ! -z $OK_tiff ]] && [[ ! -z $OK_libwebp ]]; then + run=1 + fi + ;; + libass) + if [[ ! -z $OK_libuuid ]] && [[ ! -z $OK_expat ]] && [[ ! -z $OK_libiconv ]] && [[ ! -z $OK_freetype ]] && [[ ! -z $OK_fribidi ]] && [[ ! -z $OK_fontconfig ]] && [[ ! -z $OK_libpng ]]; then + run=1 + fi + ;; + libtheora) + if [[ ! -z $OK_libvorbis ]] && [[ ! -z $OK_libogg ]]; then + run=1 + fi + ;; + libvorbis) + if [[ ! -z $OK_libogg ]]; then + run=1 + fi + ;; + libwebp) + if [[ ! -z $OK_giflib ]] && [[ ! -z $OK_jpeg ]] && [[ ! -z $OK_libpng ]] && [[ ! -z $OK_tiff ]]; then + run=1 + fi + ;; + libxml2) + if [[ ! -z $OK_libiconv ]]; then + run=1 + fi + ;; + nettle) + if [[ ! -z $OK_gmp ]]; then + run=1 + fi + ;; + rubberband) + if [[ ! -z $OK_libsndfile ]] && [[ ! -z $OK_libsamplerate ]]; then + run=1 + fi + ;; + tesseract) + if [[ ! -z $OK_leptonica ]]; then + run=1 + fi + ;; + tiff) + if [[ ! -z $OK_jpeg ]]; then + run=1 + fi + ;; + twolame) + if [[ ! -z $OK_libsndfile ]]; then + run=1 + fi + ;; + *) + run=1 + ;; + esac + + BUILD_COMPLETED_FLAG=$(echo "OK_${library}" | sed "s/\-/\_/g") + REBUILD_FLAG=$(echo "REBUILD_${library}" | sed "s/\-/\_/g") + DEPENDENCY_REBUILT_FLAG=$(echo "DEPENDENCY_REBUILT_${library}" | sed "s/\-/\_/g") + + if [ $run -eq 1 ] && [[ -z ${!BUILD_COMPLETED_FLAG} ]]; then + ENABLED_LIBRARY_PATH="${INSTALL_BASE}/${library}" + + LIBRARY_IS_INSTALLED=$(library_is_installed ${INSTALL_BASE} ${library}) + + echo -e "INFO: Flags detected for ${library}: already installed=${LIBRARY_IS_INSTALLED}, rebuild=${!REBUILD_FLAG}, dependency rebuilt=${!DEPENDENCY_REBUILT_FLAG}\n" 1>>${BASEDIR}/build.log 2>&1 + + # DECIDE TO BUILD OR NOT + if [[ ${LIBRARY_IS_INSTALLED} -ne 0 ]] || [[ ${!REBUILD_FLAG} -eq 1 ]] || [[ ${!DEPENDENCY_REBUILT_FLAG} -eq 1 ]]; then + + echo -e "----------------------------------------------------------------" 1>>${BASEDIR}/build.log 2>&1 + echo -e "\nINFO: Building $library with the following environment variables\n" 1>>${BASEDIR}/build.log 2>&1 + env 1>>${BASEDIR}/build.log 2>&1 + echo -e "----------------------------------------------------------------\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "INFO: System information\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "INFO: $(uname -a)\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "----------------------------------------------------------------\n" 1>>${BASEDIR}/build.log 2>&1 + + echo -n "${library}: " + + if [ -d ${ENABLED_LIBRARY_PATH} ]; then + rm -rf ${INSTALL_BASE}/${library} || exit 1 + fi + + SCRIPT_PATH="${BASEDIR}/build/android-${library}.sh" + + cd ${BASEDIR} + + # BUILD EACH LIBRARY ALONE FIRST + ${SCRIPT_PATH} 1>>${BASEDIR}/build.log 2>&1 + + if [ $? -eq 0 ]; then + (( completed+=1 )) + declare "$BUILD_COMPLETED_FLAG=1" + check_if_dependency_rebuilt ${library} + echo "ok" + else + echo "failed" + exit 1 + fi + else + (( completed+=1 )) + declare "$BUILD_COMPLETED_FLAG=1" + echo "${library}: already built" + fi + else + echo -e "INFO: Skipping $library, run=$run, completed=${!BUILD_COMPLETED_FLAG}\n" 1>>${BASEDIR}/build.log 2>&1 + fi + done +done + +# SKIP TO SPEED UP BUILD +if [[ ${SKIP_ffmpeg} -ne 1 ]]; then + + # BUILDING FFMPEG + . ${BASEDIR}/build/android-ffmpeg.sh "$@" +else + echo -e "\nffmpeg: skipped" +fi + +echo -e "\nINFO: Completed build for ${ARCH} on API level ${API} at "$(date)"\n" 1>>${BASEDIR}/build.log 2>&1 \ No newline at end of file diff --git a/scripts/main-ios.sh b/scripts/main-ios.sh new file mode 100755 index 0000000..4250f6f --- /dev/null +++ b/scripts/main-ios.sh @@ -0,0 +1,278 @@ +#!/bin/bash + +if [[ -z ${ARCH} ]]; then + echo -e "(*) ARCH not defined\n" + exit 1 +fi + +if [[ -z ${IOS_MIN_VERSION} ]]; then + echo -e "(*) IOS_MIN_VERSION not defined\n" + exit 1 +fi + +if [[ -z ${TARGET_SDK} ]]; then + echo -e "(*) TARGET_SDK not defined\n" + exit 1 +fi + +if [[ -z ${SDK_PATH} ]]; then + echo -e "(*) SDK_PATH not defined\n" + exit 1 +fi + +if [[ -z ${BASEDIR} ]]; then + echo -e "(*) BASEDIR not defined\n" + exit 1 +fi + +check_if_dependency_rebuilt() { + case $1 in + expat) + set_dependency_rebuilt_flag "fontconfig" + set_dependency_rebuilt_flag "libass" + ;; + fontconfig) + set_dependency_rebuilt_flag "libass" + ;; + freetype) + set_dependency_rebuilt_flag "fontconfig" + set_dependency_rebuilt_flag "libass" + ;; + fribidi) + set_dependency_rebuilt_flag "libass" + ;; + giflib) + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + gmp) + set_dependency_rebuilt_flag "gnutls" + set_dependency_rebuilt_flag "nettle" + ;; + jpeg) + set_dependency_rebuilt_flag "tiff" + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + leptonica) + set_dependency_rebuilt_flag "tesseract" + ;; + libogg) + set_dependency_rebuilt_flag "libvorbis" + set_dependency_rebuilt_flag "libtheora" + ;; + libpng) + set_dependency_rebuilt_flag "freetype" + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "libass" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + libsamplerate) + set_dependency_rebuilt_flag "rubberband" + ;; + libsndfile) + set_dependency_rebuilt_flag "twolame" + set_dependency_rebuilt_flag "rubberband" + ;; + libvorbis) + set_dependency_rebuilt_flag "libtheora" + ;; + libwebp) + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + nettle) + set_dependency_rebuilt_flag "gnutls" + ;; + tiff) + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + esac +} + +set_dependency_rebuilt_flag() { + DEPENDENCY_REBUILT_VARIABLE=$(echo "DEPENDENCY_REBUILT_$1" | sed "s/\-/\_/g") + export ${DEPENDENCY_REBUILT_VARIABLE}=1 +} + +# ENABLE COMMON FUNCTIONS +. ${BASEDIR}/build/ios-common.sh + +echo -e "\nBuilding ${ARCH} platform\n" +echo -e "\nINFO: Starting new build for ${ARCH} at "$(date)"\n" 1>>${BASEDIR}/build.log 2>&1 +INSTALL_BASE="${BASEDIR}/prebuilt/$(get_target_build_directory)" + +# CREATING PACKAGE CONFIG DIRECTORY +PKG_CONFIG_DIRECTORY="${INSTALL_BASE}/pkgconfig" +if [ ! -d ${PKG_CONFIG_DIRECTORY} ]; then + mkdir -p ${PKG_CONFIG_DIRECTORY} || exit 1 +fi + +# FILTERING WHICH EXTERNAL LIBRARIES WILL BE BUILT +# NOTE THAT BUILT-IN LIBRARIES ARE FORWARDED TO FFMPEG SCRIPT WITHOUT ANY PROCESSING +enabled_library_list=() +for library in {1..43} +do + if [[ ${!library} -eq 1 ]]; then + ENABLED_LIBRARY=$(get_library_name $((library - 1))) + enabled_library_list+=(${ENABLED_LIBRARY}) + + echo -e "INFO: Enabled library ${ENABLED_LIBRARY}\n" 1>>${BASEDIR}/build.log 2>&1 + fi +done + +let completed=0 +while [ ${#enabled_library_list[@]} -gt $completed ]; do + for library in "${enabled_library_list[@]}" + do + let run=0 + case $library in + fontconfig) + if [[ ! -z $OK_expat ]] && [[ ! -z $OK_freetype ]]; then + run=1 + fi + ;; + freetype) + if [[ ! -z $OK_libpng ]]; then + run=1 + fi + ;; + gnutls) + if [[ ! -z $OK_nettle ]] && [[ ! -z $OK_gmp ]]; then + run=1 + fi + ;; + leptonica) + if [[ ! -z $OK_giflib ]] && [[ ! -z $OK_jpeg ]] && [[ ! -z $OK_libpng ]] && [[ ! -z $OK_tiff ]] && [[ ! -z $OK_libwebp ]]; then + run=1 + fi + ;; + libass) + if [[ ! -z $OK_expat ]] && [[ ! -z $OK_freetype ]] && [[ ! -z $OK_fribidi ]] && [[ ! -z $OK_fontconfig ]] && [[ ! -z $OK_libpng ]]; then + run=1 + fi + ;; + libtheora) + if [[ ! -z $OK_libvorbis ]] && [[ ! -z $OK_libogg ]]; then + run=1 + fi + ;; + libvorbis) + if [[ ! -z $OK_libogg ]]; then + run=1 + fi + ;; + libwebp) + if [[ ! -z $OK_giflib ]] && [[ ! -z $OK_jpeg ]] && [[ ! -z $OK_libpng ]] && [[ ! -z $OK_tiff ]]; then + run=1 + fi + ;; + nettle) + if [[ ! -z $OK_gmp ]]; then + run=1 + fi + ;; + rubberband) + if [[ ! -z $OK_libsndfile ]] && [[ ! -z $OK_libsamplerate ]]; then + run=1 + fi + ;; + tesseract) + if [[ ! -z $OK_leptonica ]]; then + run=1 + fi + ;; + tiff) + if [[ ! -z $OK_jpeg ]]; then + run=1 + fi + ;; + twolame) + if [[ ! -z $OK_libsndfile ]]; then + run=1 + fi + ;; + *) + run=1 + ;; + esac + + BUILD_COMPLETED_FLAG=$(echo "OK_${library}" | sed "s/\-/\_/g") + REBUILD_FLAG=$(echo "REBUILD_${library}" | sed "s/\-/\_/g") + DEPENDENCY_REBUILT_FLAG=$(echo "DEPENDENCY_REBUILT_${library}" | sed "s/\-/\_/g") + + if [ $run -eq 1 ] && [[ -z ${!BUILD_COMPLETED_FLAG} ]]; then + ENABLED_LIBRARY_PATH="${INSTALL_BASE}/${library}" + + LIBRARY_IS_INSTALLED=$(library_is_installed ${INSTALL_BASE} ${library}) + + echo -e "INFO: Flags detected for ${library}: already installed=${LIBRARY_IS_INSTALLED}, rebuild=${!REBUILD_FLAG}, dependency rebuilt=${!DEPENDENCY_REBUILT_FLAG}\n" 1>>${BASEDIR}/build.log 2>&1 + + # DECIDE TO BUILD OR NOT + if [[ ${LIBRARY_IS_INSTALLED} -ne 0 ]] || [[ ${!REBUILD_FLAG} -eq 1 ]] || [[ ${!DEPENDENCY_REBUILT_FLAG} -eq 1 ]]; then + + echo -e "----------------------------------------------------------------" 1>>${BASEDIR}/build.log 2>&1 + echo -e "\nINFO: Building $library with the following environment variables\n" 1>>${BASEDIR}/build.log 2>&1 + env 1>>${BASEDIR}/build.log 2>&1 + echo -e "----------------------------------------------------------------\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "INFO: System information\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "INFO: $(uname -a)\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "----------------------------------------------------------------\n" 1>>${BASEDIR}/build.log 2>&1 + + echo -n "${library}: " + + if [ -d ${ENABLED_LIBRARY_PATH} ]; then + rm -rf ${INSTALL_BASE}/${library} || exit 1 + fi + + SCRIPT_PATH="${BASEDIR}/build/ios-${library}.sh" + + cd "${BASEDIR}" + + # BUILD EACH LIBRARY ALONE + ${SCRIPT_PATH} 1>>${BASEDIR}/build.log 2>&1 + + if [ $? -eq 0 ]; then + (( completed+=1 )) + declare "$BUILD_COMPLETED_FLAG=1" + check_if_dependency_rebuilt ${library} + echo "ok" + else + echo "failed" + exit 1 + fi + else + (( completed+=1 )) + declare "$BUILD_COMPLETED_FLAG=1" + echo "${library}: already built" + fi + else + echo -e "INFO: Skipping $library, run=$run, completed=${!BUILD_COMPLETED_FLAG}\n" 1>>${BASEDIR}/build.log 2>&1 + fi + done +done + +# SKIP TO SPEED UP BUILD +if [[ ${SKIP_ffmpeg} -ne 1 ]]; then + + # BUILDING FFMPEG + . ${BASEDIR}/build/ios-ffmpeg.sh "$@" || exit 1 +else + echo -e "\nffmpeg: skipped" +fi + +# SKIP TO SPEED UP BUILD +if [[ ${SKIP_ffmpeg_kit} -ne 1 ]]; then + + # BUILDING FFMPEG KIT + . ${BASEDIR}/scripts/ios-ffmpeg-kit.sh "$@" || exit 1 +else + echo -e "\nffmpeg-kit: skipped" +fi + +echo -e "\nINFO: Completed build for ${ARCH} at "$(date)"\n" 1>>${BASEDIR}/build.log 2>&1 \ No newline at end of file diff --git a/scripts/main-tvos.sh b/scripts/main-tvos.sh new file mode 100755 index 0000000..7fcb5c6 --- /dev/null +++ b/scripts/main-tvos.sh @@ -0,0 +1,278 @@ +#!/bin/bash + +if [[ -z ${ARCH} ]]; then + echo -e "(*) ARCH not defined\n" + exit 1 +fi + +if [[ -z ${TVOS_MIN_VERSION} ]]; then + echo -e "(*) TVOS_MIN_VERSION not defined\n" + exit 1 +fi + +if [[ -z ${TARGET_SDK} ]]; then + echo -e "(*) TARGET_SDK not defined\n" + exit 1 +fi + +if [[ -z ${SDK_PATH} ]]; then + echo -e "(*) SDK_PATH not defined\n" + exit 1 +fi + +if [[ -z ${BASEDIR} ]]; then + echo -e "(*) BASEDIR not defined\n" + exit 1 +fi + +check_if_dependency_rebuilt() { + case $1 in + expat) + set_dependency_rebuilt_flag "fontconfig" + set_dependency_rebuilt_flag "libass" + ;; + fontconfig) + set_dependency_rebuilt_flag "libass" + ;; + freetype) + set_dependency_rebuilt_flag "fontconfig" + set_dependency_rebuilt_flag "libass" + ;; + fribidi) + set_dependency_rebuilt_flag "libass" + ;; + giflib) + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + gmp) + set_dependency_rebuilt_flag "gnutls" + set_dependency_rebuilt_flag "nettle" + ;; + jpeg) + set_dependency_rebuilt_flag "tiff" + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + leptonica) + set_dependency_rebuilt_flag "tesseract" + ;; + libogg) + set_dependency_rebuilt_flag "libvorbis" + set_dependency_rebuilt_flag "libtheora" + ;; + libpng) + set_dependency_rebuilt_flag "freetype" + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "libass" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + libsamplerate) + set_dependency_rebuilt_flag "rubberband" + ;; + libsndfile) + set_dependency_rebuilt_flag "twolame" + set_dependency_rebuilt_flag "rubberband" + ;; + libvorbis) + set_dependency_rebuilt_flag "libtheora" + ;; + libwebp) + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + nettle) + set_dependency_rebuilt_flag "gnutls" + ;; + tiff) + set_dependency_rebuilt_flag "libwebp" + set_dependency_rebuilt_flag "leptonica" + set_dependency_rebuilt_flag "tesseract" + ;; + esac +} + +set_dependency_rebuilt_flag() { + DEPENDENCY_REBUILT_VARIABLE=$(echo "DEPENDENCY_REBUILT_$1" | sed "s/\-/\_/g") + export ${DEPENDENCY_REBUILT_VARIABLE}=1 +} + +# ENABLE COMMON FUNCTIONS +. ${BASEDIR}/build/tvos-common.sh + +echo -e "\nBuilding ${ARCH} platform\n" +echo -e "\nINFO: Starting new build for ${ARCH} at "$(date)"\n" 1>>${BASEDIR}/build.log 2>&1 +INSTALL_BASE="${BASEDIR}/prebuilt/$(get_target_build_directory)" + +# CREATING PACKAGE CONFIG DIRECTORY +PKG_CONFIG_DIRECTORY="${INSTALL_BASE}/pkgconfig" +if [ ! -d ${PKG_CONFIG_DIRECTORY} ]; then + mkdir -p ${PKG_CONFIG_DIRECTORY} || exit 1 +fi + +# FILTERING WHICH EXTERNAL LIBRARIES WILL BE BUILT +# NOTE THAT BUILT-IN LIBRARIES ARE FORWARDED TO FFMPEG SCRIPT WITHOUT ANY PROCESSING +enabled_library_list=() +for library in {1..43} +do + if [[ ${!library} -eq 1 ]]; then + ENABLED_LIBRARY=$(get_library_name $((library - 1))) + enabled_library_list+=(${ENABLED_LIBRARY}) + + echo -e "INFO: Enabled library ${ENABLED_LIBRARY}\n" 1>>${BASEDIR}/build.log 2>&1 + fi +done + +let completed=0 +while [ ${#enabled_library_list[@]} -gt $completed ]; do + for library in "${enabled_library_list[@]}" + do + let run=0 + case $library in + fontconfig) + if [[ ! -z $OK_expat ]] && [[ ! -z $OK_freetype ]]; then + run=1 + fi + ;; + freetype) + if [[ ! -z $OK_libpng ]]; then + run=1 + fi + ;; + gnutls) + if [[ ! -z $OK_nettle ]] && [[ ! -z $OK_gmp ]]; then + run=1 + fi + ;; + leptonica) + if [[ ! -z $OK_giflib ]] && [[ ! -z $OK_jpeg ]] && [[ ! -z $OK_libpng ]] && [[ ! -z $OK_tiff ]] && [[ ! -z $OK_libwebp ]]; then + run=1 + fi + ;; + libass) + if [[ ! -z $OK_expat ]] && [[ ! -z $OK_freetype ]] && [[ ! -z $OK_fribidi ]] && [[ ! -z $OK_fontconfig ]] && [[ ! -z $OK_libpng ]]; then + run=1 + fi + ;; + libtheora) + if [[ ! -z $OK_libvorbis ]] && [[ ! -z $OK_libogg ]]; then + run=1 + fi + ;; + libvorbis) + if [[ ! -z $OK_libogg ]]; then + run=1 + fi + ;; + libwebp) + if [[ ! -z $OK_giflib ]] && [[ ! -z $OK_jpeg ]] && [[ ! -z $OK_libpng ]] && [[ ! -z $OK_tiff ]]; then + run=1 + fi + ;; + nettle) + if [[ ! -z $OK_gmp ]]; then + run=1 + fi + ;; + rubberband) + if [[ ! -z $OK_libsndfile ]] && [[ ! -z $OK_libsamplerate ]]; then + run=1 + fi + ;; + tesseract) + if [[ ! -z $OK_leptonica ]]; then + run=1 + fi + ;; + tiff) + if [[ ! -z $OK_jpeg ]]; then + run=1 + fi + ;; + twolame) + if [[ ! -z $OK_libsndfile ]]; then + run=1 + fi + ;; + *) + run=1 + ;; + esac + + BUILD_COMPLETED_FLAG=$(echo "OK_${library}" | sed "s/\-/\_/g") + REBUILD_FLAG=$(echo "REBUILD_${library}" | sed "s/\-/\_/g") + DEPENDENCY_REBUILT_FLAG=$(echo "DEPENDENCY_REBUILT_${library}" | sed "s/\-/\_/g") + + if [ $run -eq 1 ] && [[ -z ${!BUILD_COMPLETED_FLAG} ]]; then + ENABLED_LIBRARY_PATH="${INSTALL_BASE}/${library}" + + LIBRARY_IS_INSTALLED=$(library_is_installed ${INSTALL_BASE} ${library}) + + echo -e "INFO: Flags detected for ${library}: already installed=${LIBRARY_IS_INSTALLED}, rebuild=${!REBUILD_FLAG}, dependency rebuilt=${!DEPENDENCY_REBUILT_FLAG}\n" 1>>${BASEDIR}/build.log 2>&1 + + # DECIDE TO BUILD OR NOT + if [[ ${LIBRARY_IS_INSTALLED} -ne 0 ]] || [[ ${!REBUILD_FLAG} -eq 1 ]] || [[ ${!DEPENDENCY_REBUILT_FLAG} -eq 1 ]]; then + + echo -e "----------------------------------------------------------------" 1>>${BASEDIR}/build.log 2>&1 + echo -e "\nINFO: Building $library with the following environment variables\n" 1>>${BASEDIR}/build.log 2>&1 + env 1>>${BASEDIR}/build.log 2>&1 + echo -e "----------------------------------------------------------------\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "INFO: System information\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "INFO: $(uname -a)\n" 1>>${BASEDIR}/build.log 2>&1 + echo -e "----------------------------------------------------------------\n" 1>>${BASEDIR}/build.log 2>&1 + + echo -n "${library}: " + + if [ -d ${ENABLED_LIBRARY_PATH} ]; then + rm -rf ${INSTALL_BASE}/${library} || exit 1 + fi + + SCRIPT_PATH="${BASEDIR}/build/ios-${library}.sh" + + cd ${BASEDIR} + + # BUILD EACH LIBRARY ALONE + ${SCRIPT_PATH} 1>>${BASEDIR}/build.log 2>&1 + + if [ $? -eq 0 ]; then + (( completed+=1 )) + declare "$BUILD_COMPLETED_FLAG=1" + check_if_dependency_rebuilt ${library} + echo "ok" + else + echo "failed" + exit 1 + fi + else + (( completed+=1 )) + declare "$BUILD_COMPLETED_FLAG=1" + echo "${library}: already built" + fi + else + echo -e "INFO: Skipping $library, run=$run, completed=${!BUILD_COMPLETED_FLAG}\n" 1>>${BASEDIR}/build.log 2>&1 + fi + done +done + +# SKIP TO SPEED UP BUILD +if [[ ${SKIP_ffmpeg} -ne 1 ]]; then + + # BUILDING FFMPEG + . ${BASEDIR}/scripts/ios-ffmpeg.sh "$@" || exit 1 +else + echo -e "\nffmpeg: skipped" +fi + +# SKIP TO SPEED UP BUILD +if [[ ${SKIP_ffmpeg_kit} -ne 1 ]]; then + + # BUILDING FFMPEG KIT + . ${BASEDIR}/scripts/ios-ffmpeg-kit.sh "$@" || exit 1 +else + echo -e "\nffmpeg-kit: skipped" +fi + +echo -e "\nINFO: Completed build for ${ARCH} at "$(date)"\n" 1>>${BASEDIR}/build.log 2>&1 \ No newline at end of file diff --git a/tvos.sh b/tvos.sh new file mode 100755 index 0000000..45b3e25 --- /dev/null +++ b/tvos.sh @@ -0,0 +1,765 @@ +#!/bin/bash + +export FFMPEG_KIT_BUILD_TYPE="tvos" +export BASEDIR="$(pwd)" + +source "${BASEDIR}"/scripts/common-${FFMPEG_KIT_BUILD_TYPE}.sh + +# ENABLE ARCH +ENABLED_ARCHITECTURES=(0 0 0 0 0 1 0 0 0 1 0) + +# ENABLE LIBRARIES +ENABLED_LIBRARIES=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) + +# USE 10.2 AS TVOS_MIN_VERSION +export TVOS_MIN_VERSION=10.2 + +export APPLE_TVOS_BUILD=1 + +RECONF_LIBRARIES=() +REBUILD_LIBRARIES=() +REDOWNLOAD_LIBRARIES=() + +get_ffmpeg_kit_version() { + local FFMPEG_KIT_VERSION=$(grep 'const FFMPEG_KIT_VERSION' "${BASEDIR}"/ios/src/FFmpegKit.m | grep -Eo '\".*\"' | sed -e 's/\"//g') + + if [[ -z ${FFMPEG_KIT_LTS_BUILD} ]]; then + echo "${FFMPEG_KIT_VERSION}" + else + echo "${FFMPEG_KIT_VERSION}.LTS" + fi +} + +display_help() { + COMMAND=$(echo "$0" | sed -e 's/\.\///g') + + echo -e "\n$COMMAND builds FFmpegKit for tvOS platform. By default two architectures (arm64 and x86-64) are built \ +without any external libraries enabled. Options can be used to disable architectures and/or enable external libraries. \ +Please note that GPL libraries (external libraries with GPL license) need --enable-gpl flag to be set explicitly. \ +When compilation ends, framework bundles and universal fat binaries are created under the prebuilt folder.\n" + echo -e "Usage: ./$COMMAND [OPTION]...\n" + echo -e "Specify environment variables as VARIABLE=VALUE to override default build options.\n" + + display_help_options + display_help_licensing + + echo -e "Architectures:" + + echo -e " --disable-arm64\t\tdo not build arm64 architecture [yes]" + echo -e " --disable-x86-64\t\tdo not build x86-64 architecture [yes]\n" + + echo -e "Libraries:" + echo -e " --full\t\t\tenables all non-GPL external libraries" + echo -e " --enable-tvos-audiotoolbox\tbuild with built-in Apple AudioToolbox support[no]" + echo -e " --enable-tvos-bzip2\t\tbuild with built-in bzip2 support[no]" + if [[ -z ${FFMPEG_KIT_LTS_BUILD} ]]; then + echo -e " --enable-tvos-videotoolbox\tbuild with built-in Apple VideoToolbox support[no]" + fi + echo -e " --enable-tvos-zlib\t\tbuild with built-in zlib [no]" + echo -e " --enable-tvos-libiconv\tbuild with built-in libiconv [no]" + + display_help_common_libraries + display_help_gpl_libraries + display_help_advanced_options +} + +enable_lts_build() { + export FFMPEG_KIT_LTS_BUILD="1" + + # XCODE 7.3 HAS TVOS SDK 9.2 + export TVOS_MIN_VERSION=9.2 + + # TVOS SDK 9.2 DOES NOT INCLUDE VIDEOTOOLBOX + ENABLED_LIBRARIES[LIBRARY_VIDEOTOOLBOX]=0 +} + +create_static_fat_library() { + local FAT_LIBRARY_PATH="${BASEDIR}"/prebuilt/tvos-universal/"$2"-universal + + mkdir -p "${FAT_LIBRARY_PATH}"/lib 1>>"${BASEDIR}"/build.log 2>&1 + + LIPO_COMMAND="${LIPO} -create" + + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + LIPO_COMMAND+=" $(find "${BASEDIR}"/prebuilt/tvos-"${TARGET_ARCH}"-apple-darwin -name $1)" + done + + LIPO_COMMAND+=" -output ${FAT_LIBRARY_PATH}/lib/$1" + + RC=$(${LIPO_COMMAND} 1>>"${BASEDIR}"/build.log 2>&1) + + echo ${RC} +} + + +get_external_library_version() { + local library_version=$(grep Version "${BASEDIR}"/prebuilt/tvos-"${TARGET_ARCH_LIST[0]}"-apple-darwin/pkgconfig/"$1".pc 2>>"${BASEDIR}"/build.log | sed 's/Version://g;s/\ //g') + + echo "${library_version}" +} + +# CHECKING IF XCODE IS INSTALLED +if ! [ -x "$(command -v xcrun)" ]; then + echo -e "\n(*) xcrun command not found. Please check your Xcode installation.\n" + exit 1 +fi + +# SELECT XCODE VERSION USED FOR BUILDING +XCODE_FOR_FFMPEG_KIT=source ~/.xcode.for.ffmpeg.kit.sh +if [[ -f ${XCODE_FOR_FFMPEG_KIT} ]]; then + source "${XCODE_FOR_FFMPEG_KIT}" 1>>"${BASEDIR}"/build.log 2>&1 +fi + +DETECTED_TVOS_SDK_VERSION="$(xcrun --sdk appletvos --show-sdk-version)" + +echo -e "INFO: Using SDK ${DETECTED_TVOS_SDK_VERSION} by Xcode provided at $(xcode-select -p)\n" 1>>"${BASEDIR}"/build.log 2>&1 +echo -e "\nINFO: Build options: $*\n" 1>>"${BASEDIR}"/build.log 2>&1 + +if [[ -n ${FFMPEG_KIT_LTS_BUILD} ]] && [[ "${DETECTED_TVOS_SDK_VERSION}" != "${TVOS_MIN_VERSION}" ]]; then + echo -e "\n(*) LTS packages should be built using SDK ${TVOS_MIN_VERSION} but current configuration uses SDK ${DETECTED_TVOS_SDK_VERSION}\n" + + if [[ -z ${BUILD_FORCE} ]]; then + exit 1 + fi +fi + +GPL_ENABLED="no" +DISPLAY_HELP="" +BUILD_LTS="" +BUILD_FULL="" +BUILD_TYPE_ID="" +BUILD_FORCE="" +BUILD_VERSION=$(git describe --tags 2>>"${BASEDIR}"/build.log) + +while [ ! $# -eq 0 ]; do + case $1 in + -h | --help) + DISPLAY_HELP="1" + ;; + -v | --version) + display_version + exit 0 + ;; + --skip-*) + SKIP_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + skip_library "${SKIP_LIBRARY}" + ;; + --no-output-redirection) + no_output_redirection + ;; + --no-workspace-cleanup-*) + NO_WORKSPACE_CLEANUP_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-[A-Za-z]*-[A-Za-z]*-//g') + + no_workspace_cleanup_library "${NO_WORKSPACE_CLEANUP_LIBRARY}" + ;; + -d | --debug) + enable_debug + ;; + -s | --speed) + optimize_for_speed + ;; + -l | --lts) + BUILD_LTS="1" + ;; + -f | --force) + BUILD_FORCE="1" + ;; + --reconf-*) + CONF_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + reconf_library "${CONF_LIBRARY}" + ;; + --rebuild-*) + BUILD_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + rebuild_library "${BUILD_LIBRARY}" + ;; + --redownload-*) + DOWNLOAD_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + redownload_library "${DOWNLOAD_LIBRARY}" + ;; + --full) + BUILD_FULL="1" + ;; + --enable-gpl) + GPL_ENABLED="yes" + ;; + --enable-*) + ENABLED_LIBRARY=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + enable_library "${ENABLED_LIBRARY}" + ;; + --disable-*) + DISABLED_ARCH=$(echo $1 | sed -e 's/^--[A-Za-z]*-//g') + + disable_arch "${DISABLED_ARCH}" + ;; + *) + print_unknown_option "$1" + ;; + esac + shift +done + +if [[ -z ${BUILD_VERSION} ]]; then + echo -e "\nerror: Can not run git commands in this folder. See build.log.\n" + exit 1 +fi + +# DETECT BUILD TYPE +if [[ -n ${BUILD_LTS} ]]; then + enable_lts_build + BUILD_TYPE_ID+="LTS " +fi + +# HELP DISPLAYED AFTER SETTING LTS FLAG +if [[ -n ${DISPLAY_HELP} ]]; then + display_help + exit 0 +fi + +# PROCESS FULL FLAG +if [[ -n ${BUILD_FULL} ]]; then + for library in {0..60}; do + if [ ${GPL_ENABLED} == "yes" ]; then + enable_library "$(get_library_name $library)" + else + if [[ $library -ne $LIBRARY_X264 ]] && [[ $library -ne $LIBRARY_XVIDCORE ]] && [[ $library -ne $LIBRARY_X265 ]] && [[ $library -ne $LIBRARY_LIBVIDSTAB ]] && [[ $library -ne $LIBRARY_RUBBERBAND ]]; then + enable_library "$(get_library_name $library)" + fi + fi + done +fi + +echo -e "\nBuilding ffmpeg-kit ${BUILD_TYPE_ID}static library for tvOS\n" +echo -e -n "INFO: Building ffmpeg-kit ${BUILD_VERSION} ${BUILD_TYPE_ID}for tvOS: " 1>>"${BASEDIR}"/build.log 2>&1 +echo -e "$(date)" 1>>"${BASEDIR}"/build.log 2>&1 + +# PRINT BUILD SUMMARY +print_enabled_architectures +print_enabled_libraries +print_reconfigure_requested_libraries +print_rebuild_requested_libraries +print_redownload_requested_libraries + +# CHECK GPL FLAG AND DOWNLOAD LIBRARIES +for gpl_library in {$LIBRARY_X264,$LIBRARY_XVIDCORE,$LIBRARY_X265,$LIBRARY_LIBVIDSTAB,$LIBRARY_RUBBERBAND}; do + if [[ ${ENABLED_LIBRARIES[$gpl_library]} -eq 1 ]]; then + library_name=$(get_library_name ${gpl_library}) + + if [ ${GPL_ENABLED} != "yes" ]; then + echo -e "\n(*) Invalid configuration detected. GPL library ${library_name} enabled without --enable-gpl flag.\n" + echo -e "\n(*) Invalid configuration detected. GPL library ${library_name} enabled without --enable-gpl flag.\n" 1>>"${BASEDIR}"/build.log 2>&1 + exit 1 + else + DOWNLOAD_RESULT=$(download_gpl_library_source "${library_name}") + if [[ ${DOWNLOAD_RESULT} -ne 0 ]]; then + echo -e "\n(*) Failed to download GPL library ${library_name} source. Please check build.log file for details. If the problem persists refer to offline building instructions.\n" + echo -e "\n(*) Failed to download GPL library ${library_name} source.\n" 1>>"${BASEDIR}"/build.log 2>&1 + exit 1 + fi + fi + fi +done + +TARGET_ARCH_LIST=() + +for run_arch in {0..10}; do + if [[ ${ENABLED_ARCHITECTURES[$run_arch]} -eq 1 ]]; then + export ARCH=$(get_arch_name $run_arch) + export TARGET_SDK=$(get_target_sdk) + export SDK_PATH=$(get_sdk_path) + export SDK_NAME=$(get_sdk_name) + + export LIPO="$(xcrun --sdk "$(get_sdk_name)" -f lipo)" + + . "${BASEDIR}"/scripts/main-tvos.sh "${ENABLED_LIBRARIES[@]}" + case ${ARCH} in + x86-64) + TARGET_ARCH="x86_64" + ;; + *) + TARGET_ARCH="${ARCH}" + ;; + esac + TARGET_ARCH_LIST+=(${TARGET_ARCH}) + + # CLEAR FLAGS + for library in {0..60}; do + library_name=$(get_library_name ${library}) + unset "$(echo "OK_${library_name}" | sed "s/\-/\_/g")" + unset "$(echo "DEPENDENCY_REBUILT_${library_name}" | sed "s/\-/\_/g")" + done + fi +done + +FFMPEG_LIBS="libavcodec libavdevice libavfilter libavformat libavutil libswresample libswscale" + +BUILD_LIBRARY_EXTENSION="a" + +if [[ -n ${TARGET_ARCH_LIST[0]} ]]; then + + echo -e -n "\n\nCreating frameworks and universal libraries under prebuilt: " + + # BUILDING UNIVERSAL LIBRARIES + rm -rf "${BASEDIR}"/prebuilt/tvos-universal 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${BASEDIR}"/prebuilt/tvos-universal 1>>"${BASEDIR}"/build.log 2>&1 + rm -rf "${BASEDIR}"/prebuilt/tvos-framework 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${BASEDIR}"/prebuilt/tvos-framework 1>>"${BASEDIR}"/build.log 2>&1 + + # 1. EXTERNAL LIBRARIES + for library in {0..6} {8..37} {39..44}; do + if [[ ${ENABLED_LIBRARIES[$library]} -eq 1 ]]; then + + library_name=$(get_library_name ${library}) + package_config_file_name=$(get_package_config_file_name ${library}) + library_version=$(get_external_library_version "${package_config_file_name}") + if [[ -z ${library_version} ]]; then + echo -e "Failed to detect version for ${library_name} from ${package_config_file_name}.pc\n" 1>>"${BASEDIR}"/build.log 2>&1 + echo -e "failed\n" + exit 1 + fi + + echo -e "Creating universal library for ${library_name}\n" 1>>"${BASEDIR}"/build.log 2>&1 + + if [[ ${LIBRARY_LIBTHEORA} == "$library" ]]; then + + LIBRARY_CREATED=$(create_static_fat_library "libtheora.a" "libtheora") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_static_fat_library "libtheoraenc.a" "libtheoraenc") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_static_fat_library "libtheoradec.a" "libtheoradec") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libtheora" "libtheora.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libtheoraenc" "libtheoraenc.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libtheoradec" "libtheoradec.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libtheora-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libtheoraenc-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libtheoradec-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libtheora.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libtheoraenc.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libtheoradec.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + elif [[ ${LIBRARY_LIBVORBIS} == "$library" ]]; then + + LIBRARY_CREATED=$(create_static_fat_library "libvorbisfile.a" "libvorbisfile") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_static_fat_library "libvorbisenc.a" "libvorbisenc") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_static_fat_library "libvorbis.a" "libvorbis") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libvorbisfile" "libvorbisfile.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libvorbisenc" "libvorbisenc.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libvorbis" "libvorbis.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libvorbisfile-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libvorbisenc-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libvorbis-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libvorbisfile.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libvorbisenc.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libvorbis.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + elif [[ ${LIBRARY_LIBWEBP} == "$library" ]]; then + + LIBRARY_CREATED=$(create_static_fat_library "libwebpmux.a" "libwebpmux") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_static_fat_library "libwebpdemux.a" "libwebpdemux") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_static_fat_library "libwebp.a" "libwebp") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libwebpmux" "libwebpmux.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libwebpdemux" "libwebpdemux.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libwebp" "libwebp.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libwebpmux-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libwebpdemux-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libwebp-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libwebpmux.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libwebpdemux.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libwebp.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + elif + [[ ${LIBRARY_OPENCOREAMR} == "$library" ]] + then + + LIBRARY_CREATED=$(create_static_fat_library "libopencore-amrnb.a" "libopencore-amrnb") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libopencore-amrnb" "libopencore-amrnb.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libopencore-amrnb-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libopencore-amrnb.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + elif [[ ${LIBRARY_NETTLE} == "$library" ]]; then + + LIBRARY_CREATED=$(create_static_fat_library "libnettle.a" "libnettle") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + LIBRARY_CREATED=$(create_static_fat_library "libhogweed.a" "libhogweed") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libnettle" "libnettle.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "libhogweed" "libhogweed.a" $library_version) + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libnettle-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/libhogweed-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libnettle.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/libhogweed.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + else + library_name=$(get_library_name $((library))) + static_archive_name=$(get_static_archive_name $((library))) + LIBRARY_CREATED=$(create_static_fat_library "$static_archive_name" "$library_name") + if [[ ${LIBRARY_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + FRAMEWORK_CREATED=$(create_static_framework "$library_name" "$static_archive_name" "$library_version") + if [[ ${FRAMEWORK_CREATED} -ne 0 ]]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-universal/${library_name}-universal/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + $(cp $(get_external_library_license_path ${library}) "${BASEDIR}"/prebuilt/tvos-framework/${library_name}.framework/LICENSE 1>>"${BASEDIR}"/build.log 2>&1) + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + fi + + fi + done + + # 2. FFMPEG + FFMPEG_UNIVERSAL="${BASEDIR}"/prebuilt/tvos-universal/ffmpeg-universal + mkdir -p "${FFMPEG_UNIVERSAL}"/include 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_UNIVERSAL}"/lib 1>>"${BASEDIR}"/build.log 2>&1 + + cp -r "${BASEDIR}"/prebuilt/tvos-"${TARGET_ARCH_LIST[0]}"-apple-darwin/ffmpeg/include/* "${FFMPEG_UNIVERSAL}"/include 1>>"${BASEDIR}"/build.log 2>&1 + cp "${BASEDIR}"/prebuilt/tvos-"${TARGET_ARCH_LIST[0]}"-apple-darwin/ffmpeg/include/config.h "${FFMPEG_UNIVERSAL}"/include 1>>"${BASEDIR}"/build.log 2>&1 + + for FFMPEG_LIB in ${FFMPEG_LIBS}; do + LIPO_COMMAND="${LIPO} -create" + + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + LIPO_COMMAND+=" ${BASEDIR}/prebuilt/tvos-${TARGET_ARCH}-apple-darwin/ffmpeg/lib/${FFMPEG_LIB}.${BUILD_LIBRARY_EXTENSION}" + done + + LIPO_COMMAND+=" -output ${FFMPEG_UNIVERSAL}/lib/${FFMPEG_LIB}.${BUILD_LIBRARY_EXTENSION}" + + ${LIPO_COMMAND} 1>>"${BASEDIR}"/build.log 2>&1 + + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + FFMPEG_LIB_UPPERCASE=$(echo "${FFMPEG_LIB}" | tr '[a-z]' '[A-Z]') + FFMPEG_LIB_CAPITALCASE=$(to_capital_case "${FFMPEG_LIB}") + + FFMPEG_LIB_MAJOR=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MAJOR" "${FFMPEG_UNIVERSAL}"/include/${FFMPEG_LIB}/version.h | sed -e "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MAJOR//g;s/\ //g") + FFMPEG_LIB_MINOR=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MINOR" "${FFMPEG_UNIVERSAL}"/include/${FFMPEG_LIB}/version.h | sed -e "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MINOR//g;s/\ //g") + FFMPEG_LIB_MICRO=$(grep "#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MICRO" "${FFMPEG_UNIVERSAL}"/include/${FFMPEG_LIB}/version.h | sed "s/#define ${FFMPEG_LIB_UPPERCASE}_VERSION_MICRO//g;s/\ //g") + + FFMPEG_LIB_VERSION="${FFMPEG_LIB_MAJOR}.${FFMPEG_LIB_MINOR}.${FFMPEG_LIB_MICRO}" + + FFMPEG_LIB_FRAMEWORK_PATH=${BASEDIR}/prebuilt/tvos-framework/${FFMPEG_LIB}.framework + + rm -rf "${FFMPEG_LIB_FRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_LIB_FRAMEWORK_PATH}"/Headers 1>>"${BASEDIR}"/build.log 2>&1 + + cp -r "${FFMPEG_UNIVERSAL}/include/${FFMPEG_LIB}/*" "${FFMPEG_LIB_FRAMEWORK_PATH}"/Headers 1>>"${BASEDIR}"/build.log 2>&1 + cp "${FFMPEG_UNIVERSAL}/lib/${FFMPEG_LIB}.${BUILD_LIBRARY_EXTENSION}" "${FFMPEG_LIB_FRAMEWORK_PATH}/${FFMPEG_LIB}" 1>>"${BASEDIR}"/build.log 2>&1 + + # COPY THE LICENSES + if [ ${GPL_ENABLED} == "yes" ]; then + + # GPLv3.0 + cp "${BASEDIR}"/LICENSE.GPLv3 "${FFMPEG_LIB_FRAMEWORK_PATH}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + else + + # LGPLv3.0 + cp "${BASEDIR}"/LICENSE.LGPLv3 "${FFMPEG_LIB_FRAMEWORK_PATH}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + fi + + build_info_plist "${FFMPEG_LIB_FRAMEWORK_PATH}/Info.plist" "${FFMPEG_LIB}" "com.arthenica.ffmpegkit.${FFMPEG_LIB_CAPITALCASE}" "${FFMPEG_LIB_VERSION}" "${FFMPEG_LIB_VERSION}" + + echo -e "Created ${FFMPEG_LIB} framework successfully.\n" 1>>"${BASEDIR}"/build.log 2>&1 + done + + # COPY THE LICENSES + if [ ${GPL_ENABLED} == "yes" ]; then + cp "${BASEDIR}"/LICENSE.GPLv3 "${FFMPEG_UNIVERSAL}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + else + cp "${BASEDIR}"/LICENSE.LGPLv3 "${FFMPEG_UNIVERSAL}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + fi + + # 3. FFMPEG KIT + FFMPEG_KIT_VERSION=$(get_ffmpeg_kit_version) + FFMPEG_KIT_UNIVERSAL=${BASEDIR}/prebuilt/tvos-universal/ffmpeg-kit-universal + FFMPEG_KIT_FRAMEWORK_PATH=${BASEDIR}/prebuilt/tvos-framework/ffmpegkit.framework + mkdir -p "${FFMPEG_KIT_UNIVERSAL}"/include 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_KIT_UNIVERSAL}"/lib 1>>"${BASEDIR}"/build.log 2>&1 + rm -rf "${FFMPEG_KIT_FRAMEWORK_PATH}" 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_KIT_FRAMEWORK_PATH}"/Headers 1>>"${BASEDIR}"/build.log 2>&1 + mkdir -p "${FFMPEG_KIT_FRAMEWORK_PATH}"/Modules 1>>"${BASEDIR}"/build.log 2>&1 + + LIPO_COMMAND="${LIPO} -create" + for TARGET_ARCH in "${TARGET_ARCH_LIST[@]}"; do + LIPO_COMMAND+=" ${BASEDIR}/prebuilt/tvos-${TARGET_ARCH}-apple-darwin/ffmpeg-kit/lib/libffmpegkit.${BUILD_LIBRARY_EXTENSION}" + done + LIPO_COMMAND+=" -output ${FFMPEG_KIT_UNIVERSAL}/lib/libffmpegkit.${BUILD_LIBRARY_EXTENSION}" + + ${LIPO_COMMAND} 1>>"${BASEDIR}"/build.log 2>&1 + + if [ $? -ne 0 ]; then + echo -e "failed\n" + exit 1 + fi + + cp -r "${BASEDIR}"/prebuilt/tvos-"${TARGET_ARCH_LIST[0]}"-apple-darwin/ffmpeg-kit/include/* "${FFMPEG_KIT_UNIVERSAL}"/include 1>>"${BASEDIR}"/build.log 2>&1 + cp -r "${FFMPEG_KIT_UNIVERSAL}"/include/* "${FFMPEG_KIT_FRAMEWORK_PATH}/Headers" 1>>"${BASEDIR}"/build.log 2>&1 + cp "${FFMPEG_KIT_UNIVERSAL}"/lib/libffmpegkit.${BUILD_LIBRARY_EXTENSION} "${FFMPEG_KIT_FRAMEWORK_PATH}"/ffmpegkit 1>>"${BASEDIR}"/build.log 2>&1 + + # COPY THE LICENSES + if [ ${GPL_ENABLED} == "yes" ]; then + cp "${BASEDIR}"/LICENSE.GPLv3 "${FFMPEG_KIT_UNIVERSAL}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + cp "${BASEDIR}"/LICENSE.GPLv3 "${FFMPEG_KIT_FRAMEWORK_PATH}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + else + cp "${BASEDIR}"/LICENSE.LGPLv3 "${FFMPEG_KIT_UNIVERSAL}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + cp "${BASEDIR}"/LICENSE.LGPLv3 "${FFMPEG_KIT_FRAMEWORK_PATH}"/LICENSE 1>>"${BASEDIR}"/build.log 2>&1 + fi + + build_info_plist "${FFMPEG_KIT_FRAMEWORK_PATH}/Info.plist" "ffmpegkit" "com.arthenica.ffmpegkit.FFmpegKit" "${FFMPEG_KIT_VERSION}" "${FFMPEG_KIT_VERSION}" + build_modulemap "${FFMPEG_KIT_FRAMEWORK_PATH}/Modules/module.modulemap" + + echo -e "Created ffmpeg-kit.framework and universal library successfully.\n" 1>>"${BASEDIR}"/build.log 2>&1 + + echo -e "ok\n" +fi