mirror of
git://code.qt.io/qt/qt5.git
synced 2026-01-09 08:26:34 +08:00
Our iOS FFmpeg provisioning includes build info.plist manifest files for the FFMpeg framework files. This manifest includes the version of FFmpeg that we are deploying. This version string is currently hardcoded and does not match the version we are actually building. This patch changes the 'install-ffmpeg-ios.sh' script to programmatically grab the FFmpeg version from our related scripts, and inserts it in the info.plist manifest. Pick-to: 6.10 Task-number: QTBUG-136480 Change-Id: Iafeaade2ff6f2a933a0ba48749af459eef37ab51 Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
189 lines
7.4 KiB
Bash
Executable File
189 lines
7.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Copyright (C) 2024 The Qt Company Ltd.
|
|
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
|
|
|
# This script will build and install FFmpeg static libs
|
|
# Can take an optional final parameter to control installation directory
|
|
set -ex
|
|
|
|
# Must match or be lower than the minimum iOS version supported by the version of Qt that is
|
|
# is currently being built.
|
|
readonly MINIMUM_IOS_VERSION="16.0"
|
|
|
|
source "${BASH_SOURCE%/*}/../unix/ffmpeg-installation-utils.sh"
|
|
|
|
ffmpeg_version=$(ffmpeg_version_default)
|
|
ffmpeg_source_dir=$(download_ffmpeg)
|
|
ffmpeg_config_options=$(get_ffmpeg_config_options "shared")
|
|
default_prefix="/usr/local/ios/ffmpeg"
|
|
prefix="${1:-$default_prefix}"
|
|
dylib_regex="^@rpath/.*\.dylib$"
|
|
|
|
build_ffmpeg_ios() {
|
|
local target_platform=$1
|
|
local target_cpu_arch=""
|
|
if [ "$target_platform" == "arm64-simulator" ]; then
|
|
target_sdk="iphonesimulator"
|
|
target_cpu_arch="arm64"
|
|
minos="-mios-simulator-version-min=$MINIMUM_IOS_VERSION"
|
|
elif [ "$target_platform" == "x86_64-simulator" ]; then
|
|
target_sdk="iphonesimulator"
|
|
target_cpu_arch="x86_64"
|
|
minos="-mios-simulator-version-min=$MINIMUM_IOS_VERSION"
|
|
elif [ "$target_platform" == "arm64-iphoneos" ]; then
|
|
target_sdk="iphoneos"
|
|
target_cpu_arch="arm64"
|
|
minos="-miphoneos-version-min=$MINIMUM_IOS_VERSION"
|
|
else
|
|
echo "Error when building FFmpeg for iOS. Unknown parameter given for target_platform: '${target_platform}'"
|
|
exit 1
|
|
fi
|
|
|
|
local build_dir="$ffmpeg_source_dir/build_ios/$target_platform"
|
|
sudo mkdir -p "$build_dir"
|
|
pushd "$build_dir"
|
|
|
|
# shellcheck disable=SC2086
|
|
sudo "$ffmpeg_source_dir/configure" $ffmpeg_config_options \
|
|
--sysroot="$(xcrun --sdk "$target_sdk" --show-sdk-path)" \
|
|
--enable-cross-compile \
|
|
--enable-optimizations \
|
|
--prefix=$prefix \
|
|
--arch=$target_cpu_arch \
|
|
--cc="xcrun --sdk ${target_sdk} clang -arch $target_cpu_arch" \
|
|
--cxx="xcrun --sdk ${target_sdk} clang++ -arch $target_cpu_arch" \
|
|
--target-os=darwin \
|
|
--extra-ldflags="$minos" \
|
|
--enable-shared \
|
|
--disable-static \
|
|
--install-name-dir='@rpath' \
|
|
--disable-audiotoolbox
|
|
|
|
sudo make install DESTDIR="$build_dir/installed" -j4
|
|
popd
|
|
}
|
|
|
|
build_info_plist() {
|
|
local file_path="$1"
|
|
local framework_name="$2"
|
|
local framework_id="$3"
|
|
|
|
# Apple plist format has a strict requirement that the version string
|
|
# contains up to 3 numerics separated by a dot. Meanwhile, FFmpeg versioning
|
|
# tends to use an 'n' prefix in their versioning. We use a regex to convert
|
|
# and verify the version string.
|
|
#
|
|
# https://developer.apple.com/documentation/bundleresources/information-property-list/cfbundleversion
|
|
local formatted_ffmpeg_version
|
|
if [[ $ffmpeg_version =~ ([0-9]+(\.[0-9]+){0,2}) ]]; then
|
|
formatted_ffmpeg_version="${BASH_REMATCH[1]}"
|
|
else
|
|
echo "Unable to format FFmpeg version string '$ffmpeg_version' into corresponding Apple Info.plist format"
|
|
exit 1
|
|
fi
|
|
|
|
local minimum_version_key="MinimumOSVersion"
|
|
local supported_platforms="iPhoneOS"
|
|
|
|
info_plist="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
|
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
|
|
<plist version=\"1.0\">
|
|
<dict>
|
|
<key>CFBundleDevelopmentRegion</key>
|
|
<string>en</string>
|
|
<key>CFBundleExecutable</key>
|
|
<string>${framework_name}</string>
|
|
<key>CFBundleIdentifier</key>
|
|
<string>${framework_id}</string>
|
|
<key>CFBundleInfoDictionaryVersion</key>
|
|
<string>6.0</string>
|
|
<key>CFBundleName</key>
|
|
<string>${framework_name}</string>
|
|
<key>CFBundlePackageType</key>
|
|
<string>FMWK</string>
|
|
<key>CFBundleShortVersionString</key>
|
|
<string>${formatted_ffmpeg_version}</string>
|
|
<key>CFBundleVersion</key>
|
|
<string>${formatted_ffmpeg_version}</string>
|
|
<key>CFBundleSignature</key>
|
|
<string>????</string>
|
|
<key>${minimum_version_key}</key>
|
|
<string>${MINIMUM_IOS_VERSION}</string>
|
|
<key>CFBundleSupportedPlatforms</key>
|
|
<array>
|
|
<string>${supported_platforms}</string>
|
|
</array>
|
|
<key>NSPrincipalClass</key>
|
|
<string></string>
|
|
</dict>
|
|
</plist>"
|
|
echo $info_plist | sudo tee ${file_path} 1>/dev/null
|
|
}
|
|
|
|
|
|
create_framework() {
|
|
# Create a 'traditional' framework from the corresponding dylib.
|
|
local framework_name="$1"
|
|
local platform="$2" # For now it's either arm64, x86_64-simulator, see below.
|
|
local ffmpeg_library_path="$ffmpeg_source_dir/build_ios/${platform}/installed$prefix"
|
|
local framework_complete_path="${ffmpeg_library_path}/framework/${framework_name}.framework/${framework_name}"
|
|
|
|
sudo mkdir -p "${ffmpeg_library_path}/framework/${framework_name}.framework"
|
|
sudo cp "${ffmpeg_library_path}/lib/${framework_name}.dylib" "${ffmpeg_library_path}/framework/${framework_name}.framework/${framework_name}"
|
|
|
|
# Fix LC_ID_DYLIB (to be libavcodec.framework/libavcodec instead of @rpath/libavcodec.xx.yy.dylib
|
|
sudo install_name_tool -id @rpath/${framework_name}.framework/${framework_name} "${framework_complete_path}"
|
|
|
|
build_info_plist "${ffmpeg_library_path}/framework/${framework_name}.framework/Info.plist" "${framework_name}" "io.qt.ffmpegkit."${framework_name}
|
|
|
|
# Fix all FFmpeg-related LC_LOAD_DYLIB, similar to how we fixed LC_ID_DYLIB above:
|
|
otool -L "$framework_complete_path" | awk '/\t/ {print $1}' | egrep "$dylib_regex" | while read -r dependency_path; do
|
|
found_name=$(tmp=${dependency_path/*\/}; echo ${tmp/\.*})
|
|
if [ "$found_name" != "$framework_name" ]
|
|
then
|
|
sudo install_name_tool -change "$dependency_path" @rpath/${found_name}.framework/${found_name} "${framework_complete_path}"
|
|
fi
|
|
done
|
|
#sudo mkdir -p "$prefix/framework/"
|
|
#sudo cp -r "${ffmpeg_library_path}/framework/${framework_name}.framework" "$prefix/framework/"
|
|
}
|
|
|
|
create_xcframework() {
|
|
# Create 'traditional' framework from the corresponding dylib,
|
|
# also creating
|
|
local framework_name="$1"
|
|
local target_platform_a="$2"
|
|
local target_platform_b="$3"
|
|
|
|
local fw_a="$ffmpeg_source_dir/build_ios/${target_platform_a}/installed$prefix/framework/${framework_name}.framework"
|
|
local fw_b="$ffmpeg_source_dir/build_ios/${target_platform_b}/installed$prefix/framework/${framework_name}.framework"
|
|
|
|
sudo mkdir -p "$prefix/framework/"
|
|
sudo xcodebuild -create-xcframework -framework $fw_a -framework $fw_b -output "${prefix}/framework/${framework_name}.xcframework"
|
|
}
|
|
|
|
build_ffmpeg_ios "x86_64-simulator"
|
|
build_ffmpeg_ios "arm64-iphoneos"
|
|
|
|
ffmpeg_libs="libavcodec libavformat libavutil libswresample libswscale"
|
|
|
|
for name in $ffmpeg_libs; do
|
|
create_framework $name "arm64-iphoneos"
|
|
create_framework $name "x86_64-simulator"
|
|
done
|
|
|
|
# Create corresponding (xc)frameworks containing both arm64 and arm64-simulator frameworks:
|
|
for name in $ffmpeg_libs; do
|
|
create_xcframework $name "arm64-iphoneos" "x86_64-simulator"
|
|
done
|
|
|
|
# xcframeworks are already installed directly into the target output directory.
|
|
# We need to install headers
|
|
sudo cp -r "$ffmpeg_source_dir/build_ios/arm64-iphoneos/installed$prefix/include" $prefix
|
|
# The set_ffmpeg_dir_env_var requires the presence of the "lib" subfolder in order to validate
|
|
# our FFmpeg install. On iOS we don't use this subfolder, we only rely on the "framework" subfolder.
|
|
# So we create a dummy "lib" folder to pass the check.
|
|
sudo mkdir -p "${prefix}/lib"
|
|
|
|
set_ffmpeg_dir_env_var "FFMPEG_DIR_IOS" $prefix
|