Files
qt5/coin/provisioning/common/shared/fix_ffmpeg_dependencies.sh
Nils Petter Skålerud 07ec75fa35 FFmpeg, Android: Use llvm-readelf
In the current Android FFmpeg provisioning, we rely on the tool
'readelf' to be installed on the host. On macOS we currently pull this
tool through the Homebrew 'binutils' package. This has proven
unreliable on older macOS hosts.

The Android NDK provides the same tool under the name 'llvm-readelf'.
This patch makes us rely on this tool during provisioning, which is
guaranteed to be provided.

Pick-to: 6.11
Change-Id: I47a186d2dd4b442929b82f35b4d257d011cb9d10
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
Reviewed-by: Dimitrios Apostolou <jimis@qt.io>
Reviewed-by: Tero Heikkinen <tero.heikkinen@qt.io>
2026-04-08 19:45:56 +01:00

109 lines
3.7 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
set -euox pipefail
lib_dir="$1/lib"
additional_suffix="${2:-}"
set_rpath="${3:-yes}"
page_size="${4:-}"
custom_readelf="${5:-""}"
# If custom_readelf is not provided, we fallback to host readelf.
if [ -n "$custom_readelf" ]; then
if ! command -v "$custom_readelf"; then
echo "Error. Provided readelf executable '${custom_readelf}' is not a valid executable"
exit 1
fi
elif ! command -v readelf; then
echo "Found no valid readelf command. It is possible it was not correctly installed."
exit 1
fi
readelf_wrapper() {
if [ -n "$custom_readelf" ]; then
"$custom_readelf" "$@"
else
readelf "$@"
fi
}
if ! command -v patchelf; then
echo "Found no valid patchelf command. It is possible it was not correctly installed."
exit 1
fi
# Get patchelf version
patchelf_version=$(patchelf --version 2>/dev/null | awk '{print $2}')
if [[ "$patchelf_version" == "0.18.0" ]]; then
echo "WARNING: patchelf version 0.18.0 is known to have issues with Android." >&2
fi
ffmpeg_libs=("avcodec" "avdevice" "avfilter" "avformat" "avutil" "swresample" "swscale")
stub_prefix="Qt6FFmpegStub-"
for lib_name in "${ffmpeg_libs[@]}"; do
lib_path="$lib_dir/lib$lib_name.so"
pkg_config_file_path="$lib_dir/pkgconfig/lib$lib_name.pc"
stubs_required_versions=""
if [ ! -f "$lib_path" ]; then
echo "FFmpeg lib $lib_path hasn't been found"
exit 1
fi
if [ ! -f "$pkg_config_file_path" ]; then
echo "FFmpeg pc file $pkg_config_file_path hasn't been found"
exit 1
fi
read_needed_deps() {
readelf_wrapper -d "$lib_path" | grep '(NEEDED)'
}
while read -r line; do
if [[ $line =~ .*\[(lib((ssl|crypto|va|va-x11|va-drm)(_3)?\.so(\.[0-9]+)*))\].* ]]; then
stub_name="lib$stub_prefix${BASH_REMATCH[2]}"
android_ssl_suffix=${BASH_REMATCH[4]}
soversion=${BASH_REMATCH[5]}
if [ -n "$android_ssl_suffix" ] && [ -n "$soversion" ]; then
>&2 echo "both, android_ssl_suffix $android_ssl_suffix and soversion $soversion are found"
continue
fi
if [[ "$android_ssl_suffix" == "_3" ]]; then
stub_name="${stub_name/_3/}" # Remove "_3" from stub_name
stubs_required_versions+=" ${stub_name/.so/ = 3},"
elif [[ -n "$soversion" ]]; then
stubs_required_versions+=" ${stub_name/.so./ = },"
fi
if [[ -n "$additional_suffix" ]]; then
stub_name="${stub_name%%.*}${additional_suffix}.${stub_name#*.}" # Add additional_suffix
fi
additional_command_args=""
if [ -n "$page_size" ]; then
additional_command_args+="--page-size ${page_size}"
fi
patchelf ${additional_command_args} --replace-needed "${BASH_REMATCH[1]}" "${stub_name}" "$lib_path"
fi
done <<< "$(read_needed_deps)"
sed_cmd="/^Libs.private:/s/ -l(va|va-x11|va-drm|ssl|crypto)/ -l$stub_prefix\\1/g;"
if [[ -n "$stubs_required_versions" ]]; then
stubs_required_versions="${stubs_required_versions%?}" # remove the last comma
sed_cmd+="s/(^Requires.private:[^,]*(,)?.*$)/\\1\\2$stubs_required_versions/g;"
fi
# sed -i doesn't work without parameter on macOS 13
sed -i.bak -E "$sed_cmd" "$pkg_config_file_path" && rm -f "${pkg_config_file_path}.bak"
if [[ "$set_rpath" == "yes" ]]; then
# shellcheck disable=SC2016
patchelf --set-rpath '$ORIGIN' "$lib_path"
fi
done