mirror of
git://f0xx.org/android_cast
synced 2026-07-29 04:38:53 +03:00
236 lines
7.8 KiB
Bash
Executable File
236 lines
7.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Build libvpx for Android ABIs and produce libvpx.a for ANDROIDCAST_LIBVPX_LIB.
|
|
#
|
|
# With --enable-external-build, libvpx does not provide a libvpx.a make target;
|
|
# this script uses the NDK (ndk-build) + generated Android.mk, as upstream intends.
|
|
#
|
|
# Prerequisites:
|
|
# git submodule update --init third-party/libvpx
|
|
# Android NDK (auto-detected via scripts/android-ndk.sh)
|
|
#
|
|
# Usage:
|
|
# ./scripts/build-native-codecs.sh arm64-v8a
|
|
# ANDROIDCAST_LIBVPX_LIB=$PWD/build/native/arm64-v8a/libvpx.a ./gradlew assembleDebug
|
|
#
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
ABI="${1:-arm64-v8a}"
|
|
VPX_SRC_REAL="$ROOT/third-party/libvpx"
|
|
PROJECT_OUT="$ROOT/build/native/$ABI"
|
|
OUT="$PROJECT_OUT"
|
|
BUILD_DIR="$OUT/libvpx-build"
|
|
|
|
if [[ ! -d "$VPX_SRC_REAL" ]]; then
|
|
echo "ERROR: $VPX_SRC_REAL missing. Run:"
|
|
echo " git submodule update --init third-party/libvpx"
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck source=android-ndk.sh
|
|
source "$ROOT/scripts/android-ndk.sh"
|
|
if ! NDK="$(androidcast_find_ndk_root "$ROOT")"; then
|
|
exit 1
|
|
fi
|
|
NDK_HOST_BIN="$(androidcast_ndk_host_bin "$NDK")"
|
|
if [[ ! -d "$NDK_HOST_BIN" ]]; then
|
|
echo "ERROR: NDK host toolchain bin not found under $NDK"
|
|
exit 1
|
|
fi
|
|
|
|
case "$ABI" in
|
|
arm64-v8a) VPX_TARGET=arm64-android-gcc ;;
|
|
armeabi-v7a) VPX_TARGET=armv7-android-gcc ;;
|
|
x86_64) VPX_TARGET=x86_64-android-gcc ;;
|
|
x86) VPX_TARGET=x86-android-gcc ;;
|
|
*)
|
|
echo "Unsupported ABI: $ABI"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
# libvpx Makefiles break on spaces in SRC_PATH_BARE.
|
|
path_has_space() {
|
|
case "$1" in
|
|
*" "*) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
VPX_SRC="$VPX_SRC_REAL"
|
|
STAGING=""
|
|
if path_has_space "$ROOT" || path_has_space "$VPX_SRC_REAL"; then
|
|
STAGING="/tmp/androidcast-libvpx-${USER:-build}"
|
|
VPX_SRC="$STAGING/src"
|
|
BUILD_DIR="$STAGING/build/$ABI"
|
|
OUT="$STAGING/out/$ABI"
|
|
mkdir -p "$STAGING/build" "$STAGING/out"
|
|
ln -sfn "$VPX_SRC_REAL" "$VPX_SRC"
|
|
echo "Repo path contains spaces; using space-free staging under $STAGING"
|
|
fi
|
|
|
|
mkdir -p "$BUILD_DIR" "$OUT" "$PROJECT_OUT"
|
|
export ANDROID_NDK_HOME="$NDK"
|
|
export ANDROID_NDK_ROOT="$NDK"
|
|
export PATH="$NDK_HOST_BIN:$PATH"
|
|
|
|
# shellcheck source=native-build-cache.sh
|
|
source "$ROOT/scripts/native-build-cache.sh"
|
|
androidcast_apply_native_build_accelerators "$ROOT" "$ABI" "$NDK" "$NDK_HOST_BIN"
|
|
|
|
VPX_CONFIGURE_EXTRA=()
|
|
APP_CFLAGS_EXTRA=""
|
|
case "$ABI" in
|
|
x86)
|
|
# NDK does not infer -msse4.1/-mavx from libvpx source names; AVX-512 is unused on Android x86.
|
|
VPX_CONFIGURE_EXTRA+=(--disable-avx512)
|
|
APP_CFLAGS_EXTRA="-msse4.1 -mavx"
|
|
;;
|
|
x86_64)
|
|
VPX_CONFIGURE_EXTRA+=(--disable-avx512)
|
|
APP_CFLAGS_EXTRA="-msse4.1 -mavx -mavx2"
|
|
;;
|
|
esac
|
|
|
|
## common native optimization options
|
|
APP_CFLAGS_EXTRA+=" -O2 -fdata-sections -ffunction-sections -Wl,--gc-sections -ftree-vectorize -O2 -s -funroll-loops -fomit-frame-pointer "
|
|
|
|
echo "Building libvpx for $ABI (target=$VPX_TARGET) ..."
|
|
echo " source: $VPX_SRC"
|
|
echo " build: $BUILD_DIR"
|
|
|
|
cd "$BUILD_DIR"
|
|
|
|
# Out-of-tree build fails if someone previously ran configure inside third-party/libvpx.
|
|
if [[ -f "$VPX_SRC/vpx_config.h" ]]; then
|
|
src_real="$(cd "$VPX_SRC" && pwd)"
|
|
build_real="$(pwd)"
|
|
if [[ "$src_real" != "$build_real" ]]; then
|
|
echo "Cleaning in-tree configure artifacts from libvpx source (needed for out-of-tree build)..."
|
|
make -C "$VPX_SRC" distclean >/dev/null 2>&1 || true
|
|
rm -f "$VPX_SRC"/vpx_config.h "$VPX_SRC"/vpx_config.c "$VPX_SRC"/vpx_version.h \
|
|
"$VPX_SRC"/config.mk "$VPX_SRC"/Makefile
|
|
rm -f "$VPX_SRC"/libs-*.mk "$VPX_SRC"/vp*_rtcd.h "$VPX_SRC"/libvpx*.a 2>/dev/null || true
|
|
fi
|
|
fi
|
|
|
|
LIBS_MK="$BUILD_DIR/libs-${VPX_TARGET}.mk"
|
|
need_configure=false
|
|
if [[ ! -f Makefile ]]; then
|
|
need_configure=true
|
|
elif [[ ! -f "$LIBS_MK" ]] || ! grep -q "^TOOLCHAIN := ${VPX_TARGET}\$" "$BUILD_DIR/config.mk" 2>/dev/null; then
|
|
echo "Re-configuring (stale or wrong ABI in $BUILD_DIR)..."
|
|
make distclean >/dev/null 2>&1 || rm -f Makefile config.mk "$LIBS_MK" vpx_config.h vpx_config.c vpx_config.asm \
|
|
vpx_version.h vp8_rtcd.h vp9_rtcd.h vpx_scale_rtcd.h vpx_dsp_rtcd.h
|
|
need_configure=true
|
|
elif [[ "$ABI" == x86 || "$ABI" == x86_64 ]] && [[ -f "$BUILD_DIR/vpx_config.h" ]] \
|
|
&& grep -q '#define HAVE_AVX512 1' "$BUILD_DIR/vpx_config.h"; then
|
|
echo "Re-configuring (AVX-512 disabled for Android NDK on $ABI)..."
|
|
make distclean >/dev/null 2>&1 || rm -f Makefile config.mk "$LIBS_MK" vpx_config.h vpx_config.c vpx_config.asm \
|
|
vpx_version.h vp8_rtcd.h vp9_rtcd.h vpx_scale_rtcd.h vpx_dsp_rtcd.h
|
|
need_configure=true
|
|
fi
|
|
|
|
if $need_configure; then
|
|
# CC/CXX may be ccache-wrapped NDK clang (see native-build-cache.sh).
|
|
"$VPX_SRC/configure" \
|
|
--target="$VPX_TARGET" \
|
|
--disable-examples \
|
|
--disable-tools \
|
|
--disable-unit-tests \
|
|
--disable-webm-io \
|
|
--enable-vp8 \
|
|
--enable-vp9 \
|
|
--enable-static \
|
|
--disable-shared \
|
|
--extra-cflags="-fPIC -O2" \
|
|
--enable-multi-res-encoding \
|
|
--enable-vp9-temporal-denoising \
|
|
--enable-onthefly-bitpacking \
|
|
--enable-error-concealment \
|
|
--enable-realtime-only \
|
|
--enable-postproc \
|
|
--enable-vp9-postproc \
|
|
--enable-multithread \
|
|
--enable-spatial-resampling \
|
|
--disable-debug-libs \
|
|
--disable-docs \
|
|
--enable-external-build \
|
|
"${VPX_CONFIGURE_EXTRA[@]}"
|
|
fi
|
|
|
|
# armeabi-v7a ndk-build runs make in ndk-app/ and needs vpx_config.asm (not required for arm64).
|
|
make vpx_config.asm 2>/dev/null || true
|
|
if [[ -f "$BUILD_DIR/vpx_config.asm" ]] && [[ ! -s "$BUILD_DIR/vpx_config.asm" ]]; then
|
|
rm -f "$BUILD_DIR/vpx_config.asm"
|
|
make vpx_config.asm
|
|
fi
|
|
|
|
# RTCD headers (configure creates them; refresh if missing).
|
|
make -j1 vp8_rtcd.h vp9_rtcd.h vpx_scale_rtcd.h vpx_dsp_rtcd.h
|
|
|
|
# NDK project root must not contain libvpx's top-level Makefile (ndk-build would invoke it).
|
|
NDK_ROOT="$BUILD_DIR/ndk-app"
|
|
JNI_DIR="$NDK_ROOT/jni"
|
|
rm -rf "$NDK_ROOT"
|
|
mkdir -p "$JNI_DIR"
|
|
ln -sfn "$VPX_SRC" "$JNI_DIR/libvpx"
|
|
|
|
# NDK Android.mk prepends jni/ to ASM_CONVERSION; keep the configure-generated absolute path
|
|
# in BUILD_DIR for `make vpx_config.asm`, and use a jni-only copy for ndk-build.
|
|
LIBS_MK_NDK="$BUILD_DIR/libs-ndk-${VPX_TARGET}.mk"
|
|
if [[ -f "$LIBS_MK" ]]; then
|
|
cp -f "$LIBS_MK" "$LIBS_MK_NDK"
|
|
sed -i 's|^ASM_CONVERSION=.*|ASM_CONVERSION=libvpx/build/make/ads2gas.pl|' "$LIBS_MK_NDK"
|
|
fi
|
|
|
|
for f in config.mk vpx_config.c vpx_config.h vpx_config.asm vpx_version.h \
|
|
vp8_rtcd.h vp9_rtcd.h vpx_scale_rtcd.h vpx_dsp_rtcd.h; do
|
|
if [[ -f "$BUILD_DIR/$f" ]]; then
|
|
ln -sfn "$BUILD_DIR/$f" "$JNI_DIR/$f"
|
|
# ndk-build may invoke make in ndk-app/ (not jni/) for RTCD / vpx_config.asm on armeabi-v7a.
|
|
ln -sfn "$BUILD_DIR/$f" "$NDK_ROOT/$f"
|
|
fi
|
|
done
|
|
if [[ -f "$LIBS_MK_NDK" ]]; then
|
|
ln -sfn "$LIBS_MK_NDK" "$JNI_DIR/libs-${VPX_TARGET}.mk"
|
|
fi
|
|
|
|
{
|
|
echo "APP_ABI := $ABI"
|
|
echo "APP_PLATFORM := android-29"
|
|
echo "APP_STL := c++_static"
|
|
if [[ -n "$APP_CFLAGS_EXTRA" ]]; then
|
|
echo "APP_CFLAGS += $APP_CFLAGS_EXTRA"
|
|
fi
|
|
} > "$JNI_DIR/Application.mk"
|
|
|
|
cat > "$JNI_DIR/Android.mk" <<'EOF'
|
|
LOCAL_PATH := $(call my-dir)
|
|
include $(CLEAR_VARS)
|
|
# configure outputs (RTCD headers, vpx_config.h) live in jni/ — not inside libvpx sources
|
|
LOCAL_CFLAGS += -I$(LOCAL_PATH)
|
|
include $(LOCAL_PATH)/libvpx/build/make/Android.mk
|
|
EOF
|
|
|
|
"$NDK/ndk-build" -C "$NDK_ROOT" -j"$(nproc)"
|
|
|
|
LIBVPX_A="$NDK_ROOT/obj/local/$ABI/libvpx.a"
|
|
if [[ ! -f "$LIBVPX_A" ]]; then
|
|
echo "ERROR: expected $LIBVPX_A after ndk-build"
|
|
exit 1
|
|
fi
|
|
|
|
cp -f "$LIBVPX_A" "$OUT/libvpx.a"
|
|
cp -f "$OUT/libvpx.a" "$PROJECT_OUT/libvpx.a"
|
|
|
|
echo ""
|
|
echo "Built: $PROJECT_OUT/libvpx.a (size $(ls -lah "${PROJECT_OUT}/libvpx.a" | awk '{print $5}'))"
|
|
if [[ -n "$STAGING" ]]; then
|
|
echo "(staged under $STAGING because of spaces in repo path)"
|
|
fi
|
|
echo "Build other ABIs as needed, e.g.:"
|
|
echo " ./scripts/build-native-codecs.sh armeabi-v7a"
|
|
echo "Then rebuild the APK (CMake picks build/native/<abi>/libvpx.a per ABI):"
|
|
echo " ./gradlew assembleDebug"
|