diff --git a/ffmpeg-android-maker-2.sh b/ffmpeg-android-maker-2.sh new file mode 100755 index 0000000..7d749ff --- /dev/null +++ b/ffmpeg-android-maker-2.sh @@ -0,0 +1,66 @@ +source scripts/parse-arguments.sh +source scripts/export-host-variables.sh + +function prepareOutput() { + OUTPUT_LIB=${OUTPUT_DIR}/lib/${ANDROID_ABI} + mkdir -p ${OUTPUT_LIB} + # CURRENT_INSTALL_PATH ! + cp ${BUILD_DIR_FFMPEG}/${ANDROID_ABI}/lib/*.so ${OUTPUT_LIB} + + OUTPUT_HEADERS=${OUTPUT_DIR}/include/${ANDROID_ABI} + mkdir -p ${OUTPUT_HEADERS} + cp -r ${BUILD_DIR_FFMPEG}/${ANDROID_ABI}/include/* ${OUTPUT_HEADERS} +} + +function checkTextRelocations() { + # Saving stats about text relocation presence. + # If the result file doesn't have 'TEXTREL' at all, then we are good. + TEXT_REL_STATS_FILE=${STATS_DIR}/text-relocations.txt + ${CROSS_PREFIX}readelf --dynamic ${BUILD_DIR_FFMPEG}/${ABI}/lib/*.so | grep 'TEXTREL\|File' >> ${TEXT_REL_STATS_FILE} + + if grep -q TEXTREL ${TEXT_REL_STATS_FILE}; then + echo "There are text relocations in output files:" + cat ${TEXT_REL_STATS_FILE} + exit 1 + fi +} + +rm -rf ${BUILD_DIR} +rm -rf ${STATS_DIR} +rm -rf ${OUTPUT_DIR} +mkdir -p ${STATS_DIR} +mkdir -p ${OUTPUT_DIR} + +COMPONENTS_TO_BUILD=${EXTERNAL_LIBRARIES[@]} +COMPONENTS_TO_BUILD+=( "ffmpeg" ) + +for COMPONENT in ${COMPONENTS_TO_BUILD[@]} +do + export ENSURE_SOURCE_DIR=$SOURCES_DIR/$COMPONENT + mkdir -p ${ENSURE_SOURCE_DIR} + source scripts/${COMPONENT}/download.sh +done + +# Build all libraries for each enabled arch +# ABIS_TO_BUILD=("armeabi-v7a" "arm64-v8a" "x86" "x86_64") +ABIS_TO_BUILD=("armeabi-v7a") + +for ABI in ${ABIS_TO_BUILD[@]} +do + source scripts/export-build-variables.sh ${ABI} + + for COMPONENT in ${COMPONENTS_TO_BUILD[@]} + do + echo "Building the component: ${COMPONENT}" + COMPONENT_SOURCES_DIR_VARIABLE=SOURCES_DIR_${COMPONENT} + echo ${!COMPONENT_SOURCES_DIR_VARIABLE} + cd ${!COMPONENT_SOURCES_DIR_VARIABLE} + ${SCRIPTS_DIR}/${COMPONENT}/build.sh + cd $BASE_DIR + done + + # Check for text rels + checkTextRelocations + + prepareOutput +done diff --git a/scripts/export-build-variables.sh b/scripts/export-build-variables.sh new file mode 100755 index 0000000..06ebac3 --- /dev/null +++ b/scripts/export-build-variables.sh @@ -0,0 +1,55 @@ +function max() { + [ $1 -ge $2 ] && echo "$1" || echo "$2" +} + +export ANDROID_ABI=$1 + +if [ $ANDROID_ABI = "arm64-v8a" ] || [ $ANDROID_ABI = "x86_64" ] ; then + export ANDROID_PLATFORM=$(max ${MIN_SDK_ARG} 21) +else + export ANDROID_PLATFORM=${MIN_SDK_ARG} +fi + +export TOOLCHAIN_PATH=${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/${HOST_TAG} +export SYSROOT=${TOOLCHAIN_PATH}/sysroot + +export TARGET_TRIPLE_MACHINE_BINUTILS= +TARGET_TRIPLE_MACHINE_CC= +export TARGET_TRIPLE_OS="android" + +case $ANDROID_ABI in + armeabi-v7a) + #cc armv7a-linux-androideabi16-clang + #binutils arm -linux-androideabi -ld + export TARGET_TRIPLE_MACHINE_BINUTILS=arm + TARGET_TRIPLE_MACHINE_CC=armv7a + export TARGET_TRIPLE_OS=androideabi + ;; + arm64-v8a) + #cc aarch64-linux-android21-clang + #binutils aarch64-linux-android -ld + export TARGET_TRIPLE_MACHINE_BINUTILS=aarch64 + ;; + x86) + #cc i686-linux-android16-clang + #binutils i686-linux-android -ld + export TARGET_TRIPLE_MACHINE_BINUTILS=i686 + ;; + x86_64) + #cc x86_64-linux-android21-clang + #binutils x86_64-linux-android -ld + export TARGET_TRIPLE_MACHINE_BINUTILS=x86_64 + ;; +esac + +# If the cc-specific variable isn't set, we fallback to binutils version +[ -z "${TARGET_TRIPLE_MACHINE_CC}" ] && TARGET_TRIPLE_MACHINE_CC=${TARGET_TRIPLE_MACHINE_BINUTILS} +export TARGET_TRIPLE_MACHINE_CC=$TARGET_TRIPLE_MACHINE_CC + +# Common prefix for ld, as, etc. +export CROSS_PREFIX=${TOOLCHAIN_PATH}/bin/${TARGET_TRIPLE_MACHINE_BINUTILS}-linux-${TARGET_TRIPLE_OS}- + +# The name for compiler is slightly different, so it is defined separatly. +export CC=${TOOLCHAIN_PATH}/bin/${TARGET_TRIPLE_MACHINE_CC}-linux-${TARGET_TRIPLE_OS}${ANDROID_PLATFORM}-clang + +export PKG_CONFIG_LIBDIR=/Users/javernaut/Development/FFmpeg/AOM/aom_build/output/lib/pkgconfig diff --git a/scripts/export-host-variables.sh b/scripts/export-host-variables.sh new file mode 100755 index 0000000..6aa86ca --- /dev/null +++ b/scripts/export-host-variables.sh @@ -0,0 +1,21 @@ +# Defining a toolchain directory's name according to the current OS. +# Assume that proper version of NDK is installed. +case "$OSTYPE" in + darwin*) HOST_TAG="darwin-x86_64" ;; + linux*) HOST_TAG="linux-x86_64" ;; + msys) + case "$(uname -m)" in + x86_64) HOST_TAG="windows-x86_64" ;; + i686) HOST_TAG="windows" ;; + esac + ;; +esac + +if [[ $OSTYPE == "darwin"* ]]; then + HOST_NPROC=$(sysctl -n hw.physicalcpu) +else + HOST_NPROC=$(nproc) +fi + +export HOST_TAG=$HOST_TAG +export HOST_NPROC=$HOST_NPROC diff --git a/scripts/ffmpeg/build.sh b/scripts/ffmpeg/build.sh new file mode 100755 index 0000000..5e63497 --- /dev/null +++ b/scripts/ffmpeg/build.sh @@ -0,0 +1,49 @@ +case $ANDROID_ABI in + armeabi-v7a) + EXTRA_BUILD_CONFIGURATION_FLAGS=--enable-thumb + ;; + x86) + # Disabling assembler optimizations, because they have text relocations + EXTRA_BUILD_CONFIGURATION_FLAGS=--disable-asm + ;; + x86_64) + EXTRA_BUILD_CONFIGURATION_FLAGS=--x86asmexe=${TOOLCHAIN_PATH}/bin/yasm + ;; +esac + +# Everything that goes below ${EXTRA_BUILD_CONFIGURATION_FLAGS} is my project-specific. +# You are free to enable/disable whatever you actually need. + +# Path for prefix should come as a single argument from ffmpeg-android-maker istself +./configure \ + --prefix=${BUILD_DIR_FFMPEG}/${ANDROID_ABI} \ + --enable-cross-compile \ + --target-os=android \ + --arch=${TARGET_TRIPLE_MACHINE_BINUTILS} \ + --sysroot=${SYSROOT} \ + --cross-prefix=${CROSS_PREFIX} \ + --cc=${CC} \ + --extra-cflags="-O3 -fPIC" \ + --enable-shared \ + --disable-static \ + ${EXTRA_BUILD_CONFIGURATION_FLAGS} \ + --disable-runtime-cpudetect \ + --disable-programs \ + --disable-muxers \ + --disable-encoders \ + --disable-avdevice \ + --disable-postproc \ + --disable-swresample \ + --disable-avfilter \ + --disable-doc \ + --disable-debug \ + --disable-pthreads \ + --disable-network \ + --disable-bsfs \ + --pkg-config=$(which pkg-config) + + # Add --enable-xxx flags here + +make clean +make -j${HOST_NPROC} +make install diff --git a/scripts/ffmpeg/download.sh b/scripts/ffmpeg/download.sh new file mode 100755 index 0000000..e18932b --- /dev/null +++ b/scripts/ffmpeg/download.sh @@ -0,0 +1,73 @@ +# Expecting FFMPEG_SOURCE_TYPE and FFMPEG_SOURCE_VALUE variables + +# Think of that names + +# Expecting ENSURE_SOURCE_DIR - where source code has to be downloaded +# Exports SOURCES_DIR_FFMPEG - path where actual sources are stored + +echo "Downloading sources for FFmpeg" + +echo ${FFMPEG_SOURCE_TYPE} +echo ${FFMPEG_SOURCE_VALUE} + +# Utility function +# Getting sources of a particular ffmpeg release. +# Same argument (ffmpeg version) produces the same source set. +function ensureSourcesTar() { + FFMPEG_SOURCES=${ENSURE_SOURCE_DIR}/ffmpeg-${FFMPEG_SOURCE_VALUE} + + if [[ ! -d "$FFMPEG_SOURCES" ]]; then + TARGET_FILE_NAME=ffmpeg-${FFMPEG_SOURCE_VALUE}.tar.bz2 + TARGET_FILE_PATH=${ENSURE_SOURCE_DIR}/${TARGET_FILE_NAME} + + curl https://www.ffmpeg.org/releases/${TARGET_FILE_NAME} --output ${TARGET_FILE_PATH} + tar xzf ${TARGET_FILE_PATH} -C ${ENSURE_SOURCE_DIR} + rm ${TARGET_FILE_PATH} + fi + + export SOURCES_DIR_ffmpeg=$FFMPEG_SOURCES +} + +# Utility function +# Getting sources of a particular branch of ffmpeg's git repository. +# Same argument (branch name) may produce different source set, +# as the branch in origin repository may be updated in future. +# function ensureSourcesBranch() { +# BRANCH=$1 +# +# GIT_DIRECTORY=ffmpeg-git +# +# FFMPEG_SOURCES=${SOURCES_DIR}/${GIT_DIRECTORY} +# +# cd ${SOURCES_DIR} +# +# if [[ ! -d "$FFMPEG_SOURCES" ]]; then +# git clone https://git.ffmpeg.org/ffmpeg.git ${GIT_DIRECTORY} +# fi +# +# cd ${GIT_DIRECTORY} +# git checkout $BRANCH +# # Forcing the update of a branch +# git pull origin $BRANCH +# +# # Additional logging to keep track of an exact commit to build +# echo "Commit to build:" +# git rev-parse HEAD +# +# cd ${BASE_DIR} +# } + +case ${FFMPEG_SOURCE_TYPE} in + # GIT_TAG) + # echo "Using FFmpeg ${SECOND_ARGUMENT}" + # ensureSourcesTag ${SECOND_ARGUMENT} + # ;; + # GIT_BRANCH) + # echo "Using FFmpeg git repository and its branch ${SECOND_ARGUMENT}" + # ensureSourcesBranch ${SECOND_ARGUMENT} + # ;; + TAR) + echo "Using FFmpeg source archive ${FFMPEG_FALLBACK_VERSION}" + ensureSourcesTar + ;; +esac diff --git a/scripts/parse-arguments.sh b/scripts/parse-arguments.sh new file mode 100755 index 0000000..b6c4fe9 --- /dev/null +++ b/scripts/parse-arguments.sh @@ -0,0 +1,64 @@ +# TODO Add desctiption of in and out params + +EXTERNAL_LIBRARIES=() + +SOURCE_TYPE=TAR +SOURCE_VALUE="4.2.1" + +MIN_SDK=16 + +for i in "$@" +do +case $i in + --min-sdk=*) + MIN_SDK="${i#*=}" + shift + ;; + --source-git-tag=*) + SOURCE_TYPE=GIT_TAG + SOURCE_VALUE="${i#*=}" + shift + ;; + --source-git-branch=*) + SOURCE_TYPE=GIT_BRANCH + SOURCE_VALUE="${i#*=}" + shift + ;; + --source-tar=*) + SOURCE_TYPE=TAR + SOURCE_VALUE="${i#*=}" + shift + ;; + --enable-libaom) + EXTERNAL_LIBRARIES+=( "libaom" ) + shift + ;; + --enable-libdav1d) + EXTERNAL_LIBRARIES+=( "libdav1d" ) + shift + ;; + --enable-libmp3lame) + EXTERNAL_LIBRARIES+=( "libmp3lame" ) + shift + ;; + *) + echo "Unknown argument $i" + ;; +esac +done + +export FFMPEG_SOURCE_TYPE=$SOURCE_TYPE +export FFMPEG_SOURCE_VALUE=$SOURCE_VALUE +export FFMPEG_EXTERNAL_LIBRARIES=${EXTERNAL_LIBRARIES[@]} + +export MIN_SDK_ARG=${MIN_SDK} + +# Download sources for all libraries +export BASE_DIR="$( cd "$( dirname "$0" )" && pwd )" +export SOURCES_DIR=${BASE_DIR}/sources +export STATS_DIR=${BASE_DIR}/stats +export SCRIPTS_DIR=${BASE_DIR}/scripts +export OUTPUT_DIR=${BASE_DIR}/output +BUILD_DIR=${BASE_DIR}/build +export BUILD_DIR_FFMPEG=$BUILD_DIR/ffmpeg +export BUILD_DIR_EXTERNAL=$BUILD_DIR/external