Skip to content

Instantly share code, notes, and snippets.

@crsib
Created July 2, 2021 10:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save crsib/d985afddf739f91edb15c1abbaec21e7 to your computer and use it in GitHub Desktop.
Save crsib/d985afddf739f91edb15c1abbaec21e7 to your computer and use it in GitHub Desktop.
Build the FFmpeg libraries, that can be used with Audacity 3.0.3 AppImage
#!/bin/bash
################################################################################
# Build the FFmpeg libraries, that can be used with Audacity 3.0.3 AppImage
# This requires build-essential, GCC, nasm or yasm from the distro of your choice.
# This script will create FFmpeg_Package_v2.2.2 in the current working directory,
# that contains the required libraries in the lib folder.
# The DT_RUNPATH is set to the location of the resulting package, so it is
# not really movable
################################################################################
################################################################################
# Specify the URLs for the following packages
################################################################################
GSM='http://www.quut.com/gsm/gsm-1.0.19.tar.gz'
SPEEX='http://downloads.us.xiph.org/releases/speex/speex-1.2.0.tar.gz'
AMR='https://downloads.sourceforge.net/project/opencore-amr/opencore-amr/opencore-amr-0.1.5.tar.gz'
LAME='https://downloads.sourceforge.net/project/lame/lame/3.100/lame-3.100.tar.gz'
OPUS='https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz'
FFMPEG='http://ffmpeg.org/releases/ffmpeg-2.2.2.tar.gz'
# Uncomment the following for snapshot builds
#FFMPEG='http://www.ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2'
export CPPFLAGS="-fPIC"
export CFLAGS="-fPIC"
export CXXFLAGS="-fPIC"
export LDFLAGS="-fPIC"
################################################################################
# Define and create temporary installation destinations
################################################################################
ROOT="$(pwd)"
BUILD_DIR="${ROOT}/build"
PARENT="${ROOT}/.."
PREFIX="${BUILD_DIR}/local"
OUTPUT="${BUILD_DIR}/Output"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
################################################################################
# Retrieve distributions
################################################################################
for VAR in GSM SPEEX AMR LAME OPUS FFMPEG
do
eval URL="\$${VAR}"
TAR=$(basename "$URL")
if [ ! -e "${TAR}" ]
then
echo "Downloading ${TAR}"
curl -L -o "${TAR}" "${URL}"
if [ $? -ne 0 ]
then
echo "Failed to download required package...check to make sure URLs are valid"
exit 1
fi
fi
eval DIR="$(tar tf ${TAR} | sed -e '1s/\/.*//;2,$d')"
[ ! -x "${DIR}" ] && tar xf "${TAR}"
eval ${VAR}_DIR="${DIR}"
done
################################################################################
# Speed things up a bit
################################################################################
export MAKEFLAGS="-j $(nproc)"
mkdir -p "${PREFIX}/include"
mkdir -p "${PREFIX}/lib"
mkdir -p "${PREFIX}/lib/pkgconfig"
mkdir -p "${OUTPUT}"
export PKG_CONFIG_PATH="${PREFIX}/lib/pkgconfig"
echo "################################################################################"
echo "# Gsm"
echo "################################################################################"
if true
then
cd "${GSM_DIR}"
make CCINC="${CFLAGS}" LDINC="${LDFLAGS}" lib/libgsm.a
if [ $? -ne 0 ]
then
echo "gsm make failed"
exit 1
fi
mkdir -p "${PREFIX}/include/gsm"
cp -pR inc/* "${PREFIX}/include/gsm"
cp -pR $(find . -name \*.a) "${PREFIX}/lib"
cd ..
fi
echo "################################################################################"
echo "# Speex"
echo "################################################################################"
if true
then
cd "${SPEEX_DIR}"
./configure --enable-static=yes --enable-shared=no --disable-dependency-tracking
if [ $? -ne 0 ]
then
echo "speex configure failed"
exit 1
fi
make -C libspeex
if [ $? -ne 0 ]
then
echo "speex make failed"
exit 1
fi
make -C include
if [ $? -ne 0 ]
then
echo "speex make failed"
exit 1
fi
cp -pR include/* "${PREFIX}/include"
cp -pR speex.pc "${PREFIX}/lib/pkgconfig"
cp -pR $(find . -name \*.a) "${PREFIX}/lib"
cd ..
fi
echo "################################################################################"
echo "# Opencore-amr"
echo "################################################################################"
if true
then
cd "${AMR_DIR}"
./configure --enable-static=yes --enable-shared=no --disable-dependency-tracking
if [ $? -ne 0 ]
then
echo "opencore-amr configure failed"
exit 1
fi
make -C amrnb
if [ $? -ne 0 ]
then
echo "opencore-amrnb make failed"
exit 1
fi
make -C amrwb
if [ $? -ne 0 ]
then
echo "opencore-amrwb make failed"
exit 1
fi
mkdir -p "${PREFIX}/include/opencore-amrnb"
mkdir -p "${PREFIX}/include/opencore-amrwb"
cp -pR amrnb/*.h "${PREFIX}/include/opencore-amrnb"
cp -pR amrwb/*.h "${PREFIX}/include/opencore-amrwb"
cp -pR $(find . -name \*.a) "${PREFIX}/lib"
cd ..
fi
echo "################################################################################"
echo "# Lame"
echo "################################################################################"
if true
then
cd "${LAME_DIR}"
./configure --enable-static=yes --enable-shared=no --disable-dependency-tracking --disable-frontend
if [ $? -ne 0 ]
then
echo "lame configure failed"
exit 1
fi
make -C mpglib
if [ $? -ne 0 ]
then
echo "lame make mpglib failed"
exit 1
fi
make -C libmp3lame
if [ $? -ne 0 ]
then
echo "lame make mp3lame failed"
exit 1
fi
mkdir -p "${PREFIX}/include/lame"
cp -p include/* "${PREFIX}/include/lame"
cp -pR $(find . -name \*.a) "${PREFIX}/lib"
cd ..
fi
echo "################################################################################"
echo "# Opus"
echo "################################################################################"
if true
then
cd "${OPUS_DIR}"
./configure --enable-static=yes --enable-shared=no --disable-dependency-tracking --disable-doc --disable-extra-programs
if [ $? -ne 0 ]
then
echo "opus configure failed"
exit 1
fi
make
if [ $? -ne 0 ]
then
echo "opus make failed"
exit 1
fi
cp -pR opus.pc "${PREFIX}/lib/pkgconfig"
cp -pR include/opus.h include/opus_multistream.h include/opus_types.h include/opus_defines.h include/opus_projection.h "${PREFIX}/include"
cp -pR $(find .libs -name \*.a) "${PREFIX}/lib"
cd ..
fi
echo "################################################################################"
echo "# FFmpeg"
echo "################################################################################"
if true
then
cd "${FFMPEG_DIR}"
if true
then
./configure --arch=x86_64 \
--cc=gcc \
--disable-ffplay \
--disable-ffprobe \
--disable-avdevice \
--disable-debug \
--disable-static \
--disable-doc \
--disable-swresample \
--disable-swscale \
--disable-postproc \
--disable-avfilter \
--enable-gpl \
--enable-nonfree \
--enable-version3 \
--enable-libopencore-amrnb \
--enable-libopencore-amrwb \
--enable-pthreads \
--enable-libspeex \
--enable-libgsm \
--enable-libmp3lame \
--enable-libopus \
--enable-shared \
--extra-cflags="-I../local/include" \
--extra-ldflags="-L../local/lib"
if [ $? -ne 0 ]
then
echo "ffmpeg configure failed"
exit 1
fi
make
if [ $? -ne 0 ]
then
echo "ffmpeg make failed"
exit 1
fi
fi
################################################################################
# Get the FFmpeg version and create the package name
################################################################################
if [ "${FFMPEG/*snapshot*/snapshot}" = "snapshot" ]
then
VER="$(date +%Y%m%d)"
else
VER="v$(<VERSION)"
fi
PKG="FFmpeg_Package_${VER}"
mkdir -p "${ROOT}/${PKG}/"{docs,libs}
cp COPYING.GPLv3 "${ROOT}/${PKG}/docs/License.txt"
OUT_LIB_DIR="${ROOT}/${PKG}/libs"
for lib in $(find . -name \*.so.\*)
do
cp -p "${lib}" "${OUT_LIB_DIR}"
patchelf --set-rpath "${OUT_LIB_DIR}" "${OUT_LIB_DIR}/$(basename ${lib})"
done
cd ..
fi
rm -Rf "${BUILD_DIR}"
@shoogle
Copy link

shoogle commented Jul 2, 2021

DT_RUNPATH is set to the location of the resulting package, so it is not really movable

I think there's a trick you can do with RUNPATH=$ORIGIN (or $ORIGIN/../../path/to/something) to make it movable.

Also, Audacity's AppRun script could look for FFMPEG and add it to LD_LIBRARY_PATH if it is found in a known location, such as in the same directory as the AppImage location.

ffmpeg_libs="$(dirname "${APPIMAGE}")/FFMPEG/libs"

if [[ -d "${ffmpeg_libs}" ]]; then
    export LD_LIBRARY_PATH="${ffmpeg_libs}:${LD_LIBRARY_PATH}"
fi

@crsib
Copy link
Author

crsib commented Jul 2, 2021

I've tried $ORIGIN with no luck. Seems like it always expands to an executable path. There is a chance I've mistaken something though.

Setting LD_LIBRARY_PATH will surely work, but I don't like messing with the global environment.

Also, I'm pretty sure that Audacity always looks in the LD_LIBRARY_PATH as we do dlopen("avformat.so.55") as a fallback measure.

@crsib
Copy link
Author

crsib commented Jul 2, 2021

Sorry, looked carefully for your workaround. It will work, but still, FFMPEG libraries won't be really relocatable anyway. Also, we will need to check all the dependencies, so it can work across at least a few of the systems

@minhntp
Copy link

minhntp commented Sep 16, 2021

Thank you so much. This helped me to use the 3.0.4 AppImage. I tried build the libraries with --enable-shared but the AppImage doesn't recognize.

@eSavior
Copy link

eSavior commented Aug 4, 2022

Great script. Thanks for creating. FYI, I've twice now had to re-run this script because the patchelf package isn't installed by default in a Linux Mint 20 environment. Takes a while to re-run because it blows away all the source and intermediate object files after it runs. Suggest adding an auto-install of patchelf or at least an error / warning to the user that the patchelf package must be installed prior to running the script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment