Skip to content

Instantly share code, notes, and snippets.

@tarampampam
Created May 6, 2024 09:04
Show Gist options
  • Save tarampampam/84b5e188673321ef285066a16457130b to your computer and use it in GitHub Desktop.
Save tarampampam/84b5e188673321ef285066a16457130b to your computer and use it in GitHub Desktop.
FFmpeg static binary build using docker
# GitLab CI help: <https://docs.gitlab.com/ee/ci/yaml/>
# GitLab environments: <https://docs.gitlab.com/ee/ci/variables/>
variables:
GITLAB_IMAGE: $CI_REGISTRY_IMAGE
GITHUB_IMAGE: ...
stages:
- build
# ...
.podman: # Job template: use Podman to build docker images (https://github.com/containers/podman)
image: quay.io/podman/stable
variables: {GIT_DEPTH: 1, GIT_FETCH_EXTRA_FLAGS: '--no-tags'}
before_script:
- echo "$CI_REGISTRY_PASSWORD" | podman login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
- echo "$GHCR_TOKEN" | podman login -u "$GHCR_LOGIN" --password-stdin ghcr.io
after_script:
- podman logout "$CI_REGISTRY"
- podman logout ghcr.io
.branch:build:
extends: [.branch, .podman]
retry: 1
timeout: 12h # so much time is needed to build the image on arm64 (thx, qemu)
script:
- if [[ $USE_QEMU == "yes" ]]; then
podman run --rm --privileged docker.io/multiarch/qemu-user-static --reset -p yes;
fi
# build the image
- podman build
--cache-from "$CI_REGISTRY_IMAGE/cache"
--cache-to "$CI_REGISTRY_IMAGE/cache"
--platform "$PLATFORM"
--tag "$GITLAB_IMAGE:$IMAGE_TAG"
--tag "$GITHUB_IMAGE:$IMAGE_TAG" .
- podman push "$GITLAB_IMAGE:$IMAGE_TAG"
- podman push "$GITHUB_IMAGE:$IMAGE_TAG"
# extract binary files from the image to local file system
- podman create --name ffmpeg-local "$GITLAB_IMAGE:$IMAGE_TAG"
- podman cp ffmpeg-local:/bin/ffmpeg ./ffmpeg
- podman cp ffmpeg-local:/bin/ffprobe ./ffprobe
- podman rm -f ffmpeg-local
# make an archive with the binaries
- tar -czf "$FILENAME.tar.gz" ffmpeg ffprobe
artifacts:
paths: [$FILENAME.tar.gz]
expire_in: 2 weeks
branch:build:amd64:
extends: [.branch:build]
variables:
IMAGE_TAG: "amd64-$CI_COMMIT_REF_SLUG-branch"
PLATFORM: linux/amd64
FILENAME: ffmpeg-amd64
branch:build:arm64v8:
extends: [.branch:build]
variables:
IMAGE_TAG: "arm64v8-$CI_COMMIT_REF_SLUG-branch"
PLATFORM: linux/arm64/v8
FILENAME: ffmpeg-arm64v8
USE_QEMU: 'yes'
#tags: [arm64] # only on arm64 runners
branch:build:manifest: # create and push the image manifest
extends: [.branch, .podman]
needs: [branch:build:amd64, branch:build:arm64v8]
timeout: 5m
variables: {GIT_STRATEGY: none}
script:
# manifest for GitLab
- podman manifest create "$GITLAB_IMAGE:$CI_COMMIT_REF_SLUG-branch"
"$GITLAB_IMAGE:amd64-$CI_COMMIT_REF_SLUG-branch"
"$GITLAB_IMAGE:arm64v8-$CI_COMMIT_REF_SLUG-branch"
- podman manifest push --format v2s2 --all
"$GITLAB_IMAGE:$CI_COMMIT_REF_SLUG-branch"
"docker://$GITLAB_IMAGE:$CI_COMMIT_REF_SLUG-branch"
# and for GitHub
- podman manifest create "$GITHUB_IMAGE:$CI_COMMIT_REF_SLUG-branch"
"$GITHUB_IMAGE:amd64-$CI_COMMIT_REF_SLUG-branch"
"$GITHUB_IMAGE:arm64v8-$CI_COMMIT_REF_SLUG-branch"
- podman manifest push --all
"$GITHUB_IMAGE:$CI_COMMIT_REF_SLUG-branch"
"docker://$GITHUB_IMAGE:$CI_COMMIT_REF_SLUG-branch"
# ...
FROM docker.io/library/alpine:3.19.0 AS builder
RUN set -x \
&& apk add --no-cache \
libsamplerate-dev libsamplerate-static \
freetype freetype-dev freetype-static \
vo-amrwbenc-dev vo-amrwbenc-static \
fontconfig-dev fontconfig-static \
snappy snappy-dev snappy-static \
openssl-dev openssl-libs-static \
libjpeg-turbo libjpeg-turbo-dev \
harfbuzz-dev harfbuzz-static \
libxml2-dev libxml2-static \
fribidi-dev fribidi-static \
libpng-dev libpng-static \
brotli-dev brotli-static \
expat-dev expat-static \
bzip2-dev bzip2-static \
soxr-dev soxr-static \
zlib-dev zlib-static \
rust cargo cargo-c \
cmake meson ninja \
autoconf automake \
giflib giflib-dev \
graphite2-static \
xz-dev xz-static \
ca-certificates \
cunit cunit-dev \
tiff tiff-dev \
glib-static \
numactl-dev \
build-base \
diffutils \
yasm nasm \
coreutils \
fftw-dev \
libtool \
texinfo \
wget \
bash \
tcl \
git \
tar \
xxd
# -O3 makes sure we compile with optimization. setting CFLAGS/CXXFLAGS seems to override
# default automake cflags.
# -static-libgcc is needed to make gcc not include gcc_s as "as-needed" shared library which
# cmake will include as a implicit library.
# other options to get hardened build (same as ffmpeg hardened)
ENV CFLAGS="-O3 -s -static-libgcc -fno-strict-overflow -fstack-protector-all -fPIC" \
CXXFLAGS="-O3 -s -static-libgcc -fno-strict-overflow -fstack-protector-all -fPIC" \
LDFLAGS="-Wl,-z,relro,-z,now" \
WGET_OPTS="--no-verbose --retry-on-host-error --retry-on-http-error=429,500,502,503"
# workaround for https://github.com/pkgconf/pkgconf/issues/268
# link order somehow ends up reversed for libbrotlidec and libbrotlicommon with pkgconf 1.9.4 but not 1.9.3
# adding libbrotlicommon directly to freetype2 required libraries seems to fix it
RUN sed -i 's/libbrotlidec/libbrotlidec, libbrotlicommon/' /usr/lib/pkgconfig/freetype2.pc
WORKDIR /tmp
# before aom as libvmaf uses it
RUN set -x \
&& wget $WGET_OPTS -O vmaf.tar.gz "https://github.com/Netflix/vmaf/archive/refs/tags/v3.0.0.tar.gz" \
&& tar xf vmaf.tar.gz \
&& cd vmaf-*/libvmaf \
&& meson build \
--buildtype=release \
-Ddefault_library=static \
-Dbuilt_in_models=true \
-Denable_tests=false \
-Denable_docs=false \
-Denable_avx512=true \
-Denable_float=true \
&& ninja -j$(nproc) -vC build install \
# extra libs stdc++ is for vmaf https://github.com/Netflix/vmaf/issues/788
&& sed -i 's/-lvmaf /-lvmaf -lstdc++ /' /usr/local/lib/pkgconfig/libvmaf.pc \
&& rm -r /tmp/vmaf*
# build after libvmaf
RUN set -x \
&& git clone --depth 1 --branch 'v3.8.0' 'https://aomedia.googlesource.com/aom' \
&& cd aom \
&& mkdir build_tmp \
&& cd build_tmp \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_EXAMPLES=NO \
-DENABLE_DOCS=NO \
-DENABLE_TESTS=NO \
-DENABLE_TOOLS=NO \
-DCONFIG_TUNE_VMAF=1 \
-DENABLE_NASM=ON \
-DCMAKE_INSTALL_LIBDIR=lib \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/aom*
RUN set -x \
&& wget $WGET_OPTS -O libaribb24.tar.gz 'https://github.com/nkoriyama/aribb24/archive/v1.0.3.tar.gz' \
&& mkdir libaribb24 \
&& tar xf libaribb24.tar.gz -C libaribb24 --strip-components=1 \
&& cd libaribb24 \
&& autoreconf -fiv \
&& ./configure --enable-static --disable-shared \
&& make -j$(nproc) \
&& make install \
&& rm -r /tmp/libaribb24*
RUN set -x \
&& version='0.17.1' \
&& wget $WGET_OPTS -O libass.tar.gz "https://github.com/libass/libass/releases/download/${version}/libass-${version}.tar.gz" \
&& tar xf libass.tar.gz \
&& cd libass-* \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) \
&& make install \
&& rm -r /tmp/libass*
RUN set -x \
&& version='1.3.4' \
&& wget $WGET_OPTS -O libbluray.tar.gz "https://code.videolan.org/videolan/libbluray/-/archive/${version}/libbluray-${version}.tar.gz" \
&& tar xf libbluray.tar.gz \
&& cd libbluray-* \
&& git clone https://code.videolan.org/videolan/libudfread.git contrib/libudfread \
&& autoreconf -fiv \
&& ./configure \
--with-pic \
--disable-doxygen-doc \
--disable-doxygen-dot \
--enable-static \
--disable-shared \
--disable-examples \
--disable-bdjava-jar \
&& make -j$(nproc) install \
&& rm -r /tmp/libbluray*
RUN set -x \
&& version='1.3.0' \
&& wget $WGET_OPTS -O dav1d.tar.gz "https://code.videolan.org/videolan/dav1d/-/archive/${version}/dav1d-${version}.tar.gz" \
&& tar xf dav1d.tar.gz \
&& cd dav1d-* \
&& meson build --buildtype release -Ddefault_library=static \
&& ninja -j$(nproc) -C build install \
&& rm -r /tmp/dav1d*
# TODO: seems to be issues with asm on musl
RUN set -x \
&& wget $WGET_OPTS -O davs2.tar.gz 'https://github.com/pkuvcl/davs2/archive/refs/tags/1.7.tar.gz' \
&& tar xf davs2.tar.gz \
&& cd davs2-*/build/linux \
&& ./configure --disable-asm --enable-pic --enable-strip --disable-cli \
&& make -j$(nproc) install \
&& rm -r /tmp/davs2*
RUN set -x \
&& wget $WGET_OPTS -O fdk-aac.tar.gz 'https://github.com/mstorsjo/fdk-aac/archive/v2.0.3.tar.gz' \
&& tar xf fdk-aac.tar.gz \
&& cd fdk-aac-* \
&& ./autogen.sh \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/fdk-aac*
RUN set -x \
&& git clone 'https://github.com/libgme/game-music-emu.git' \
&& cd game-music-emu \
&& git checkout '3efb7ad1a34ef0b7c3436db7c6a40f3fdef8ba35' \
&& mkdir build \
&& cd build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_UBSAN=OFF \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/game-music-emu*
RUN set -x \
&& git clone 'https://github.com/timothytylee/libgsm.git' \
&& cd libgsm \
&& git checkout '98f1708fb5e06a0dfebd58a3b40d610823db9715' \
# Makefile is garbage, hence use specific compile arguments and flags
# no need to build toast cli tool
&& rm src/toast* \
&& SRC=$(echo src/*.c) \
&& gcc ${CFLAGS} -c -ansi -pedantic -s -DNeedFunctionPrototypes=1 -Wall -Wno-comment -DSASR -DWAV49 -DNDEBUG -I./inc ${SRC} \
&& ar cr libgsm.a *.o \
&& ranlib libgsm.a \
&& mkdir -p /usr/local/include/gsm \
&& cp inc/*.h /usr/local/include/gsm \
&& cp libgsm.a /usr/local/lib \
&& rm -r /tmp/libgsm*
RUN set -x \
&& wget $WGET_OPTS -O kvazaar.tar.gz 'https://github.com/ultravideo/kvazaar/archive/v2.2.0.tar.gz' \
&& tar xf kvazaar.tar.gz \
&& cd kvazaar-* \
&& ./autogen.sh \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/kvazaar*
RUN set -x \
&& wget $WGET_OPTS -O libmodplug.tar.gz 'https://downloads.sourceforge.net/modplug-xmms/libmodplug-0.8.9.0.tar.gz' \
&& tar xf libmodplug.tar.gz \
&& cd libmodplug-* \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/libmodplug*
RUN set -x \
&& version='3.100' \
&& wget $WGET_OPTS -O lame.tar.gz "https://sourceforge.net/projects/lame/files/lame/${version}/lame-${version}.tar.gz/download" \
&& tar xf lame.tar.gz \
&& cd lame-* \
&& ./configure --disable-shared --enable-static --enable-nasm --disable-gtktest --disable-cpml --disable-frontend \
&& make -j$(nproc) install \
&& rm -r /tmp/lame*
RUN set -x \
&& version='2.16' \
&& wget -O lcms2.tar.gz "https://github.com/mm2/Little-CMS/releases/download/lcms${version}/lcms2-${version}.tar.gz" \
&& tar xfz lcms2.tar.gz \
&& cd lcms2-* \
&& ./autogen.sh \
&& ./configure --enable-static --disable-shared \
&& make -j$(nproc) install \
&& rm -r /tmp/lcms2*
RUN set -x \
&& wget $WGET_OPTS -O libmysofa.tar.gz 'https://github.com/hoene/libmysofa/archive/refs/tags/v1.3.2.tar.gz' \
&& tar xf libmysofa.tar.gz \
&& cd libmysofa-*/build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_INSTALL_LIBDIR=lib \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTS=OFF \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/libmysofa*
RUN set -x \
&& wget $WGET_OPTS -O opencoreamr.tar.gz 'https://sourceforge.net/projects/opencore-amr/files/opencore-amr/opencore-amr-0.1.6.tar.gz' \
&& tar xf opencoreamr.tar.gz \
&& cd opencore-amr-* \
&& ./configure --enable-static --disable-shared \
&& make -j$(nproc) install \
&& rm -r /tmp/opencore*
RUN set -x \
&& wget $WGET_OPTS -O openjpeg.tar.gz 'https://github.com/uclouvain/openjpeg/archive/v2.5.0.tar.gz' \
&& tar xf openjpeg.tar.gz \
&& cd openjpeg-* \
&& mkdir build \
&& cd build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DBUILD_PKGCONFIG_FILES=ON \
-DBUILD_CODEC=OFF \
-DWITH_ASTYLE=OFF \
-DBUILD_TESTING=OFF \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/openjpeg*
RUN set -x \
&& wget $WGET_OPTS -O frei0r.tar.gz 'https://github.com/dyne/frei0r/archive/refs/tags/v2.2.0.tar.gz' \
&& tar xf frei0r.tar.gz \
&& cd ./frei0r-* \
&& mkdir ./build \
&& cd ./build \
&& cmake ./.. \
&& make -j $(nproc) \
&& make install \
&& rm -r /tmp/frei0r*
RUN set -x \
&& version='1.4' \
&& wget $WGET_OPTS -O opus.tar.gz "https://github.com/xiph/opus/releases/download/v${version}/opus-${version}.tar.gz" \
&& tar xf opus.tar.gz \
&& cd opus-* \
&& ./configure --disable-shared --enable-static --disable-extra-programs --disable-doc \
&& make -j$(nproc) install \
&& rm -r /tmp/opus*
# RUSTFLAGS need to fix gcc_s
# https://gitlab.alpinelinux.org/alpine/aports/-/issues/11806
RUN set -x \
&& wget $WGET_OPTS -O rav1e.tar.gz 'https://github.com/xiph/rav1e/archive/v0.7.1.tar.gz' \
&& tar xf rav1e.tar.gz \
&& cd rav1e-* \
&& RUSTFLAGS="-C target-feature=+crt-static" cargo cinstall --release \
&& rm -r /tmp/rav1e*
RUN set -x \
&& git clone 'https://git.ffmpeg.org/rtmpdump.git' \
&& cd rtmpdump \
&& git checkout 'f1b83c10d8beb43fcc70a6e88cf4325499f25857' \
# Patch/port librtmp to openssl 1.1
&& for _dlp in dh.h handshake.h hashswf.c; do \
wget $WGET_OPTS https://raw.githubusercontent.com/microsoft/vcpkg/38bb87c5571555f1a4f64cb4ed9d2be0017f9fc1/ports/librtmp/${_dlp%.*}.patch; \
patch librtmp/${_dlp} < ${_dlp%.*}.patch; \
done \
&& make SYS=posix SHARED=off -j$(nproc) install \
&& rm -r /tmp/rtmpdump*
RUN set -x \
&& wget $WGET_OPTS -O rubberband.tar.bz2 'https://breakfastquay.com/files/releases/rubberband-2.0.2.tar.bz2' \
&& tar xf rubberband.tar.bz2 \
&& cd rubberband-* \
&& meson -Ddefault_library=static -Dfft=fftw -Dresampler=libsamplerate build \
&& ninja -j$(nproc) -vC build install \
&& echo "Requires.private: fftw3 samplerate" >> /usr/local/lib/pkgconfig/rubberband.pc \
&& rm -r /tmp/rubberband*
RUN set -x \
&& version='3.1.1' \
&& wget $WGET_OPTS -O libshine.tar.gz "https://github.com/toots/shine/releases/download/${version}/shine-${version}.tar.gz" \
&& tar xf libshine.tar.gz \
&& cd shine* \
&& ./configure --with-pic --enable-static --disable-shared --disable-fast-install \
&& make -j$(nproc) install \
&& rm -r /tmp/*shine*
RUN set -x \
&& wget $WGET_OPTS -O speex.tar.gz 'https://github.com/xiph/speex/archive/Speex-1.2.1.tar.gz' \
&& tar xf speex.tar.gz \
&& cd speex-Speex-* \
&& ./autogen.sh \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/speex*
RUN set -x \
&& wget $WGET_OPTS -O libsrt.tar.gz 'https://github.com/Haivision/srt/archive/v1.5.3.tar.gz' \
&& tar xf libsrt.tar.gz \
&& cd srt-* \
&& mkdir build \
&& cd build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_SHARED=OFF \
-DENABLE_APPS=OFF \
-DENABLE_CXX11=ON \
-DUSE_STATIC_LIBSTDCXX=ON \
-DOPENSSL_USE_STATIC_LIBS=ON \
-DENABLE_LOGGING=OFF \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_INSTALL_INCLUDEDIR=include \
-DCMAKE_INSTALL_BINDIR=bin \
.. \
&& make -j$(nproc) \
&& make install \
&& rm -r /tmp/*srt*
RUN set -x \
&& version='1.8.0' \
&& wget $WGET_OPTS -O svtav1.tar.bz2 "https://gitlab.com/AOMediaCodec/SVT-AV1/-/archive/v${version}/SVT-AV1-v${version}.tar.bz2" \
&& tar xf svtav1.tar.bz2 \
&& cd SVT-AV1-*/Build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_INSTALL_LIBDIR=lib \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_BUILD_TYPE=Release \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/svtav1* /tmp/SVT-AV1-*
# has to be before theora
RUN set -x \
&& wget $WGET_OPTS -O libogg.tar.gz 'https://downloads.xiph.org/releases/ogg/libogg-1.3.5.tar.gz' \
&& tar xf libogg.tar.gz \
&& cd libogg-* \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/libogg*
RUN set -x \
&& wget $WGET_OPTS -O libtheora.tar.bz2 'https://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2' \
&& tar xf libtheora.tar.bz2 \
# --build=$(arch)-unknown-linux-gnu helps with guessing the correct build. For some reason,
# build script can't guess the build type in arm64 (hardware and emulated) environment.
&& cd libtheora-* \
&& ./configure --build=$(arch)-unknown-linux-gnu --disable-examples --disable-oggtest --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/libtheora*
RUN set -x \
&& version='0.4.0' \
&& wget $WGET_OPTS -O twolame.tar.gz "https://github.com/njh/twolame/releases/download/${version}/twolame-${version}.tar.gz" \
&& tar xf twolame.tar.gz \
&& cd twolame-* \
&& ./configure --disable-shared --enable-static --disable-sndfile --with-pic \
&& make -j$(nproc) install \
&& rm -r /tmp/twolame*
# Removes BIT_DEPTH 10 to be able to build on other platforms. 10 was overkill anyways.
RUN set -x \
&& git clone 'https://github.com/uavs3/uavs3d.git' \
&& cd uavs3d \
&& git checkout '1fd04917cff50fac72ae23e45f82ca6fd9130bd8' \
# sed -i 's/define BIT_DEPTH 8/define BIT_DEPTH 10/' source/decore/com_def.h && \
&& mkdir build/linux \
&& cd build/linux \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
../.. \
&& make -j$(nproc) install \
&& rm -r /tmp/uavs3d*
RUN set -x \
&& wget $WGET_OPTS -O vid.stab.tar.gz 'https://github.com/georgmartius/vid.stab/archive/v1.1.1.tar.gz' \
&& tar xf vid.stab.tar.gz \
&& cd vid.stab-* \
&& mkdir build \
&& cd build \
# This line workarounds the issue that happens when the image builds in emulated (buildx) arm64 environment.
# Since in emulated container the /proc is mounted from the host, the cmake not able to detect CPU features correctly.
&& sed -i 's/include (FindSSE)/if(CMAKE_SYSTEM_ARCH MATCHES "amd64")\ninclude (FindSSE)\nendif()/' ../CMakeLists.txt \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_SYSTEM_ARCH=$(arch) \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DUSE_OMP=ON \
.. \
&& make -j$(nproc) install \
&& echo "Libs.private: -ldl" >> /usr/local/lib/pkgconfig/vidstab.pc \
&& rm -r /tmp/vid*
RUN set -x \
&& wget $WGET_OPTS -O libvorbis.tar.gz "https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.gz" \
&& tar xf libvorbis.tar.gz \
&& cd libvorbis-* \
&& ./configure --disable-shared --enable-static --disable-oggtest \
&& make -j$(nproc) install \
&& rm -r /tmp/libvorbis*
RUN set -x \
&& wget $WGET_OPTS -O libvpx.tar.gz 'https://github.com/webmproject/libvpx/archive/v1.13.1.tar.gz' \
&& tar xf libvpx.tar.gz \
&& cd libvpx-* \
&& ./configure --enable-static --enable-vp9-highbitdepth --disable-shared --disable-unit-tests --disable-examples \
&& make -j$(nproc) install \
&& rm -r /tmp/libvpx*
RUN set -x \
&& wget $WGET_OPTS -O libwebp.tar.gz 'https://github.com/webmproject/libwebp/archive/v1.3.2.tar.gz' \
&& tar xf libwebp.tar.gz \
&& cd libwebp-* \
&& ./autogen.sh \
&& ./configure \
--disable-shared \
--enable-static \
--with-pic \
--enable-libwebpmux \
--disable-libwebpextras \
--disable-libwebpdemux \
--disable-sdl \
--disable-gl \
--disable-png \
--disable-jpeg \
--disable-tiff \
--disable-gif \
&& make -j$(nproc) install \
&& rm -r /tmp/libwebp*
# x264 only have a stable branch no tags and we checkout commit so no hash is needed
RUN set -x \
&& git clone 'https://code.videolan.org/videolan/x264.git' \
&& cd x264 \
&& git checkout '31e19f92f00c7003fa115047ce50978bc98c3a0d' \
&& ./configure --enable-pic --enable-static --disable-cli --disable-lavf --disable-swscale \
&& make -j$(nproc) install \
&& rm -r /tmp/*x264*
# x265 release is over 1 years old and master branch has a lot of fixes and improvements, so we checkout commit so no hash is needed
# -w-macro-params-legacy to not log lots of asm warnings
# https://bitbucket.org/multicoreware/x265_git/issues/559/warnings-when-assembling-with-nasm-215
# CMAKEFLAGS issue
# https://bitbucket.org/multicoreware/x265_git/issues/620/support-passing-cmake-flags-to-multilibsh
RUN set -x \
&& wget $WGET_OPTS -O x265_git.tar.bz2 'https://bitbucket.org/multicoreware/x265_git/get/ce8642f22123f0b8cf105c88fc1e8af9888bd345.tar.bz2' \
&& tar xf x265_git.tar.bz2 \
&& cd multicoreware-x265_git-*/build/linux \
&& sed -i '/^cmake / s/$/ -G "Unix Makefiles" ${CMAKEFLAGS}/' ./multilib.sh \
&& sed -i 's/ -DENABLE_SHARED=OFF//g' ./multilib.sh \
&& MAKEFLAGS="-j$(nproc)" \
CMAKEFLAGS="-DENABLE_SHARED=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_AGGRESSIVE_CHECKS=ON -DCMAKE_ASM_NASM_FLAGS=-w-macro-params-legacy -DENABLE_NASM=ON -DCMAKE_BUILD_TYPE=Release" \
./multilib.sh \
&& make -C 8bit -j$(nproc) install \
&& rm -r /tmp/*x265*
# TODO: seems to be issues with asm on musl
RUN set -x \
&& wget $WGET_OPTS -O xavs2.tar.gz 'https://github.com/pkuvcl/xavs2/archive/refs/tags/1.4.tar.gz' \
&& tar xf xavs2.tar.gz \
&& cd xavs2-*/build/linux \
&& ./configure --disable-asm --enable-pic --disable-cli \
&& make -j$(nproc) install \
&& rm -r /tmp/*xavs2*
# http://websvn.xvid.org/cvs/viewvc.cgi/trunk/xvidcore/build/generic/configure.in?revision=2146&view=markup
# add extra CFLAGS that are not enabled by -O3
RUN set -x \
&& wget $WGET_OPTS -O libxvid.tar.gz 'https://downloads.xvid.com/downloads/xvidcore-1.3.7.tar.gz' \
&& tar xf libxvid.tar.gz \
&& cd xvidcore/build/generic \
&& CFLAGS="$CFLAGS -fstrength-reduce -ffast-math" ./configure \
&& make -j$(nproc) \
&& make install \
&& rm -r /tmp/libxvid* /tmp/xvidcore*
RUN set -x \
&& wget $WGET_OPTS -O zimg.tar.gz "https://github.com/sekrit-twc/zimg/archive/release-3.0.5.tar.gz" \
&& tar xf zimg.tar.gz \
&& cd zimg-* \
&& ./autogen.sh \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/zimg*
# sed changes --toolchain=hardened -pie to -static-pie
# extra ldflags stack-size=2097152 is to increase default stack size from 128KB (musl default) to something
# more similar to glibc (2MB). This fixing segfault with libaom-av1 and libsvtav1 as they seems to pass
# large things on the stack.
RUN set -x \
&& version='5.1.4' \
&& wget $WGET_OPTS -O ffmpeg.tar.bz2 "https://ffmpeg.org/releases/ffmpeg-${version}.tar.bz2" \
&& tar xf ffmpeg.tar.bz2 \
&& cd ffmpeg-* \
&& sed -i 's/add_ldexeflags -fPIE -pie/add_ldexeflags -fPIE -static-pie/' ./configure \
&& ./configure \
--pkg-config-flags='--static' \
--extra-cflags='-fopenmp' \
--extra-ldflags='-fopenmp -Wl,-z,stack-size=2097152' \
--extra-version="$(date '+%Y-%m-%d')" \
--toolchain=hardened \
--disable-debug \
--disable-shared \
--disable-ffplay \
--disable-indev=sndio \
--disable-outdev=sndio \
--enable-static \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--enable-fontconfig \
--enable-gray \
--enable-iconv \
--enable-lcms2 \
--enable-libaom \
--enable-libaribb24 \
--enable-libass \
--enable-libbluray \
--enable-libdav1d \
--enable-libdavs2 \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libfribidi \
--enable-libgme \
--enable-libgsm \
--enable-libkvazaar \
--enable-libmodplug \
--enable-libmp3lame \
--enable-libmysofa \
--enable-libopencore-amrnb \
--enable-libopencore-amrwb \
--enable-libopenjpeg \
--enable-frei0r \
--enable-libopus \
--enable-librav1e \
--enable-librtmp \
--enable-librubberband \
--enable-libshine \
--enable-libsnappy \
--enable-libsoxr \
--enable-libspeex \
--enable-libsrt \
--enable-libsvtav1 \
--enable-libtheora \
--enable-libtwolame \
--enable-libuavs3d \
--enable-libvidstab \
--enable-libvmaf \
--enable-libvo-amrwbenc \
--enable-libvorbis \
--enable-libvpx \
--enable-libwebp \
--enable-libx264 \
--enable-libx265 \
--enable-libxavs2 \
--enable-libxml2 \
--enable-libxvid \
--enable-libzimg \
--enable-openssl \
&& make -j$(nproc) install
RUN set -x \
# prepare etc directory for usage in runtime
&& mkdir -p ./etc/ssl \
&& echo 'ffmpeg:x:10001:10001::/nonexistent:/sbin/nologin' > ./etc/passwd \
&& echo 'ffmpeg:x:10001:' > ./etc/group \
&& cp /etc/ssl/cert.pem ./etc/ssl/cert.pem
FROM scratch AS tests
COPY --from=builder /usr/local/bin/ffmpeg /bin/ffmpeg
COPY --from=builder /usr/local/bin/ffprobe /bin/ffprobe
COPY --from=builder /tmp/etc /etc
# sanity tests
RUN ["/bin/ffmpeg", "-version"]
RUN ["/bin/ffprobe", "-version"]
RUN ["/bin/ffmpeg", "-hide_banner", "-buildconf"]
# stack size
RUN ["/bin/ffmpeg", "-f", "lavfi", "-i", "testsrc", "-c:v", "libsvtav1", "-t", "100ms", "-f", "null", "-"]
# dns
RUN ["/bin/ffprobe", "-i", "https://github.com/favicon.ico"]
# tls/https certs
RUN ["/bin/ffprobe", "-tls_verify", "1", "-ca_file", "/etc/ssl/cert.pem", "-i", "https://github.com/favicon.ico"]
# clamp all files into one layer
FROM scratch AS runtime
COPY --from=builder /tmp/etc /etc
COPY --from=tests /bin /bin
LABEL \
# docs: <https://github.com/opencontainers/image-spec/blob/master/annotations.md>
org.opencontainers.image.title="ffmpeg" \
org.opencontainers.image.description="Statically built FFmpeg"
# use an unprivileged user
USER 10001:10001
ENTRYPOINT ["/bin/ffmpeg"]
FROM docker.io/library/alpine:3.19.0 AS builder
RUN set -x \
&& apk add --no-cache \
libsamplerate-dev libsamplerate-static \
freetype freetype-dev freetype-static \
vo-amrwbenc-dev vo-amrwbenc-static \
fontconfig-dev fontconfig-static \
snappy snappy-dev snappy-static \
openssl-dev openssl-libs-static \
libjpeg-turbo libjpeg-turbo-dev \
harfbuzz-dev harfbuzz-static \
libxml2-dev libxml2-static \
fribidi-dev fribidi-static \
libpng-dev libpng-static \
brotli-dev brotli-static \
expat-dev expat-static \
bzip2-dev bzip2-static \
soxr-dev soxr-static \
zlib-dev zlib-static \
rust cargo cargo-c \
cmake meson ninja \
autoconf automake \
giflib giflib-dev \
graphite2-static \
xz-dev xz-static \
ca-certificates \
cunit cunit-dev \
tiff tiff-dev \
glib-static \
numactl-dev \
build-base \
diffutils \
yasm nasm \
coreutils \
fftw-dev \
libtool \
texinfo \
wget \
bash \
tcl \
git \
tar \
xxd
# -O3 makes sure we compile with optimization. setting CFLAGS/CXXFLAGS seems to override
# default automake cflags.
# -static-libgcc is needed to make gcc not include gcc_s as "as-needed" shared library which
# cmake will include as a implicit library.
# other options to get hardened build (same as ffmpeg hardened)
ENV CFLAGS="-O3 -s -static-libgcc -fno-strict-overflow -fstack-protector-all -fPIC" \
CXXFLAGS="-O3 -s -static-libgcc -fno-strict-overflow -fstack-protector-all -fPIC" \
LDFLAGS="-Wl,-z,relro,-z,now" \
WGET_OPTS="--no-verbose --retry-on-host-error --retry-on-http-error=429,500,502,503"
# workaround for https://github.com/pkgconf/pkgconf/issues/268
# link order somehow ends up reversed for libbrotlidec and libbrotlicommon with pkgconf 1.9.4 but not 1.9.3
# adding libbrotlicommon directly to freetype2 required libraries seems to fix it
RUN sed -i 's/libbrotlidec/libbrotlidec, libbrotlicommon/' /usr/lib/pkgconfig/freetype2.pc
WORKDIR /tmp
# before aom as libvmaf uses it
RUN set -x \
&& wget $WGET_OPTS -O vmaf.tar.gz "https://github.com/Netflix/vmaf/archive/refs/tags/v3.0.0.tar.gz" \
&& tar xf vmaf.tar.gz \
&& cd vmaf-*/libvmaf \
&& meson build \
--buildtype=release \
-Ddefault_library=static \
-Dbuilt_in_models=true \
-Denable_tests=false \
-Denable_docs=false \
-Denable_avx512=true \
-Denable_float=true \
&& ninja -j$(nproc) -vC build install \
# extra libs stdc++ is for vmaf https://github.com/Netflix/vmaf/issues/788
&& sed -i 's/-lvmaf /-lvmaf -lstdc++ /' /usr/local/lib/pkgconfig/libvmaf.pc \
&& rm -r /tmp/vmaf*
# build after libvmaf
RUN set -x \
&& git clone --depth 1 --branch 'v3.8.0' 'https://aomedia.googlesource.com/aom' \
&& cd aom \
&& mkdir build_tmp \
&& cd build_tmp \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_EXAMPLES=NO \
-DENABLE_DOCS=NO \
-DENABLE_TESTS=NO \
-DENABLE_TOOLS=NO \
-DCONFIG_TUNE_VMAF=1 \
-DENABLE_NASM=ON \
-DCMAKE_INSTALL_LIBDIR=lib \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/aom*
RUN set -x \
&& wget $WGET_OPTS -O libaribb24.tar.gz 'https://github.com/nkoriyama/aribb24/archive/v1.0.3.tar.gz' \
&& mkdir libaribb24 \
&& tar xf libaribb24.tar.gz -C libaribb24 --strip-components=1 \
&& cd libaribb24 \
&& autoreconf -fiv \
&& ./configure --enable-static --disable-shared \
&& make -j$(nproc) \
&& make install \
&& rm -r /tmp/libaribb24*
RUN set -x \
&& version='0.17.1' \
&& wget $WGET_OPTS -O libass.tar.gz "https://github.com/libass/libass/releases/download/${version}/libass-${version}.tar.gz" \
&& tar xf libass.tar.gz \
&& cd libass-* \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) \
&& make install \
&& rm -r /tmp/libass*
RUN set -x \
&& version='1.3.4' \
&& wget $WGET_OPTS -O libbluray.tar.gz "https://code.videolan.org/videolan/libbluray/-/archive/${version}/libbluray-${version}.tar.gz" \
&& tar xf libbluray.tar.gz \
&& cd libbluray-* \
&& git clone https://code.videolan.org/videolan/libudfread.git contrib/libudfread \
&& autoreconf -fiv \
&& ./configure \
--with-pic \
--disable-doxygen-doc \
--disable-doxygen-dot \
--enable-static \
--disable-shared \
--disable-examples \
--disable-bdjava-jar \
&& make -j$(nproc) install \
&& rm -r /tmp/libbluray*
RUN set -x \
&& version='1.3.0' \
&& wget $WGET_OPTS -O dav1d.tar.gz "https://code.videolan.org/videolan/dav1d/-/archive/${version}/dav1d-${version}.tar.gz" \
&& tar xf dav1d.tar.gz \
&& cd dav1d-* \
&& meson build --buildtype release -Ddefault_library=static \
&& ninja -j$(nproc) -C build install \
&& rm -r /tmp/dav1d*
# TODO: seems to be issues with asm on musl
RUN set -x \
&& wget $WGET_OPTS -O davs2.tar.gz 'https://github.com/pkuvcl/davs2/archive/refs/tags/1.7.tar.gz' \
&& tar xf davs2.tar.gz \
&& cd davs2-*/build/linux \
&& ./configure --disable-asm --enable-pic --enable-strip --disable-cli \
&& make -j$(nproc) install \
&& rm -r /tmp/davs2*
RUN set -x \
&& wget $WGET_OPTS -O fdk-aac.tar.gz 'https://github.com/mstorsjo/fdk-aac/archive/v2.0.3.tar.gz' \
&& tar xf fdk-aac.tar.gz \
&& cd fdk-aac-* \
&& ./autogen.sh \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/fdk-aac*
RUN set -x \
&& git clone 'https://github.com/libgme/game-music-emu.git' \
&& cd game-music-emu \
&& git checkout '3efb7ad1a34ef0b7c3436db7c6a40f3fdef8ba35' \
&& mkdir build \
&& cd build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DENABLE_UBSAN=OFF \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/game-music-emu*
RUN set -x \
&& git clone 'https://github.com/timothytylee/libgsm.git' \
&& cd libgsm \
&& git checkout '98f1708fb5e06a0dfebd58a3b40d610823db9715' \
# Makefile is garbage, hence use specific compile arguments and flags
# no need to build toast cli tool
&& rm src/toast* \
&& SRC=$(echo src/*.c) \
&& gcc ${CFLAGS} -c -ansi -pedantic -s -DNeedFunctionPrototypes=1 -Wall -Wno-comment -DSASR -DWAV49 -DNDEBUG -I./inc ${SRC} \
&& ar cr libgsm.a *.o \
&& ranlib libgsm.a \
&& mkdir -p /usr/local/include/gsm \
&& cp inc/*.h /usr/local/include/gsm \
&& cp libgsm.a /usr/local/lib \
&& rm -r /tmp/libgsm*
RUN set -x \
&& wget $WGET_OPTS -O kvazaar.tar.gz 'https://github.com/ultravideo/kvazaar/archive/v2.2.0.tar.gz' \
&& tar xf kvazaar.tar.gz \
&& cd kvazaar-* \
&& ./autogen.sh \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/kvazaar*
RUN set -x \
&& wget $WGET_OPTS -O libmodplug.tar.gz 'https://downloads.sourceforge.net/modplug-xmms/libmodplug-0.8.9.0.tar.gz' \
&& tar xf libmodplug.tar.gz \
&& cd libmodplug-* \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/libmodplug*
RUN set -x \
&& version='3.100' \
&& wget $WGET_OPTS -O lame.tar.gz "https://sourceforge.net/projects/lame/files/lame/${version}/lame-${version}.tar.gz/download" \
&& tar xf lame.tar.gz \
&& cd lame-* \
&& ./configure --disable-shared --enable-static --enable-nasm --disable-gtktest --disable-cpml --disable-frontend \
&& make -j$(nproc) install \
&& rm -r /tmp/lame*
RUN set -x \
&& version='2.16' \
&& wget -O lcms2.tar.gz "https://github.com/mm2/Little-CMS/releases/download/lcms${version}/lcms2-${version}.tar.gz" \
&& tar xfz lcms2.tar.gz \
&& cd lcms2-* \
&& ./autogen.sh \
&& ./configure --enable-static --disable-shared \
&& make -j$(nproc) install \
&& rm -r /tmp/lcms2*
RUN set -x \
&& wget $WGET_OPTS -O libmysofa.tar.gz 'https://github.com/hoene/libmysofa/archive/refs/tags/v1.3.2.tar.gz' \
&& tar xf libmysofa.tar.gz \
&& cd libmysofa-*/build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_INSTALL_LIBDIR=lib \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTS=OFF \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/libmysofa*
RUN set -x \
&& wget $WGET_OPTS -O opencoreamr.tar.gz 'https://sourceforge.net/projects/opencore-amr/files/opencore-amr/opencore-amr-0.1.6.tar.gz' \
&& tar xf opencoreamr.tar.gz \
&& cd opencore-amr-* \
&& ./configure --enable-static --disable-shared \
&& make -j$(nproc) install \
&& rm -r /tmp/opencore*
RUN set -x \
&& wget $WGET_OPTS -O openjpeg.tar.gz 'https://github.com/uclouvain/openjpeg/archive/v2.5.0.tar.gz' \
&& tar xf openjpeg.tar.gz \
&& cd openjpeg-* \
&& mkdir build \
&& cd build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DBUILD_PKGCONFIG_FILES=ON \
-DBUILD_CODEC=OFF \
-DWITH_ASTYLE=OFF \
-DBUILD_TESTING=OFF \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/openjpeg*
RUN set -x \
&& wget $WGET_OPTS -O frei0r.tar.gz 'https://github.com/dyne/frei0r/archive/refs/tags/v2.2.0.tar.gz' \
&& tar xf frei0r.tar.gz \
&& cd ./frei0r-* \
&& mkdir ./build \
&& cd ./build \
&& cmake ./.. \
&& make -j $(nproc) \
&& make install \
&& rm -r /tmp/frei0r*
RUN set -x \
&& version='1.4' \
&& wget $WGET_OPTS -O opus.tar.gz "https://github.com/xiph/opus/releases/download/v${version}/opus-${version}.tar.gz" \
&& tar xf opus.tar.gz \
&& cd opus-* \
&& ./configure --disable-shared --enable-static --disable-extra-programs --disable-doc \
&& make -j$(nproc) install \
&& rm -r /tmp/opus*
# RUSTFLAGS need to fix gcc_s
# https://gitlab.alpinelinux.org/alpine/aports/-/issues/11806
RUN set -x \
&& wget $WGET_OPTS -O rav1e.tar.gz 'https://github.com/xiph/rav1e/archive/v0.7.1.tar.gz' \
&& tar xf rav1e.tar.gz \
&& cd rav1e-* \
&& RUSTFLAGS="-C target-feature=+crt-static" cargo cinstall --release \
&& rm -r /tmp/rav1e*
RUN set -x \
&& git clone 'https://git.ffmpeg.org/rtmpdump.git' \
&& cd rtmpdump \
&& git checkout 'f1b83c10d8beb43fcc70a6e88cf4325499f25857' \
# Patch/port librtmp to openssl 1.1
&& for _dlp in dh.h handshake.h hashswf.c; do \
wget $WGET_OPTS https://raw.githubusercontent.com/microsoft/vcpkg/38bb87c5571555f1a4f64cb4ed9d2be0017f9fc1/ports/librtmp/${_dlp%.*}.patch; \
patch librtmp/${_dlp} < ${_dlp%.*}.patch; \
done \
&& make SYS=posix SHARED=off -j$(nproc) install \
&& rm -r /tmp/rtmpdump*
RUN set -x \
&& wget $WGET_OPTS -O rubberband.tar.bz2 'https://breakfastquay.com/files/releases/rubberband-2.0.2.tar.bz2' \
&& tar xf rubberband.tar.bz2 \
&& cd rubberband-* \
&& meson -Ddefault_library=static -Dfft=fftw -Dresampler=libsamplerate build \
&& ninja -j$(nproc) -vC build install \
&& echo "Requires.private: fftw3 samplerate" >> /usr/local/lib/pkgconfig/rubberband.pc \
&& rm -r /tmp/rubberband*
RUN set -x \
&& version='3.1.1' \
&& wget $WGET_OPTS -O libshine.tar.gz "https://github.com/toots/shine/releases/download/${version}/shine-${version}.tar.gz" \
&& tar xf libshine.tar.gz \
&& cd shine* \
&& ./configure --with-pic --enable-static --disable-shared --disable-fast-install \
&& make -j$(nproc) install \
&& rm -r /tmp/*shine*
RUN set -x \
&& wget $WGET_OPTS -O speex.tar.gz 'https://github.com/xiph/speex/archive/Speex-1.2.1.tar.gz' \
&& tar xf speex.tar.gz \
&& cd speex-Speex-* \
&& ./autogen.sh \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/speex*
RUN set -x \
&& wget $WGET_OPTS -O libsrt.tar.gz 'https://github.com/Haivision/srt/archive/v1.5.3.tar.gz' \
&& tar xf libsrt.tar.gz \
&& cd srt-* \
&& mkdir build \
&& cd build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_SHARED=OFF \
-DENABLE_APPS=OFF \
-DENABLE_CXX11=ON \
-DUSE_STATIC_LIBSTDCXX=ON \
-DOPENSSL_USE_STATIC_LIBS=ON \
-DENABLE_LOGGING=OFF \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_INSTALL_INCLUDEDIR=include \
-DCMAKE_INSTALL_BINDIR=bin \
.. \
&& make -j$(nproc) \
&& make install \
&& rm -r /tmp/*srt*
RUN set -x \
&& version='1.8.0' \
&& wget $WGET_OPTS -O svtav1.tar.bz2 "https://gitlab.com/AOMediaCodec/SVT-AV1/-/archive/v${version}/SVT-AV1-v${version}.tar.bz2" \
&& tar xf svtav1.tar.bz2 \
&& cd SVT-AV1-*/Build \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_INSTALL_LIBDIR=lib \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_BUILD_TYPE=Release \
.. \
&& make -j$(nproc) install \
&& rm -r /tmp/svtav1* /tmp/SVT-AV1-*
# has to be before theora
RUN set -x \
&& wget $WGET_OPTS -O libogg.tar.gz 'https://downloads.xiph.org/releases/ogg/libogg-1.3.5.tar.gz' \
&& tar xf libogg.tar.gz \
&& cd libogg-* \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/libogg*
RUN set -x \
&& wget $WGET_OPTS -O libtheora.tar.bz2 'https://downloads.xiph.org/releases/theora/libtheora-1.1.1.tar.bz2' \
&& tar xf libtheora.tar.bz2 \
# --build=$(arch)-unknown-linux-gnu helps with guessing the correct build. For some reason,
# build script can't guess the build type in arm64 (hardware and emulated) environment.
&& cd libtheora-* \
&& ./configure --build=$(arch)-unknown-linux-gnu --disable-examples --disable-oggtest --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/libtheora*
RUN set -x \
&& version='0.4.0' \
&& wget $WGET_OPTS -O twolame.tar.gz "https://github.com/njh/twolame/releases/download/${version}/twolame-${version}.tar.gz" \
&& tar xf twolame.tar.gz \
&& cd twolame-* \
&& ./configure --disable-shared --enable-static --disable-sndfile --with-pic \
&& make -j$(nproc) install \
&& rm -r /tmp/twolame*
# Removes BIT_DEPTH 10 to be able to build on other platforms. 10 was overkill anyways.
RUN set -x \
&& git clone 'https://github.com/uavs3/uavs3d.git' \
&& cd uavs3d \
&& git checkout '1fd04917cff50fac72ae23e45f82ca6fd9130bd8' \
# sed -i 's/define BIT_DEPTH 8/define BIT_DEPTH 10/' source/decore/com_def.h && \
&& mkdir build/linux \
&& cd build/linux \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
../.. \
&& make -j$(nproc) install \
&& rm -r /tmp/uavs3d*
RUN set -x \
&& wget $WGET_OPTS -O vid.stab.tar.gz 'https://github.com/georgmartius/vid.stab/archive/v1.1.1.tar.gz' \
&& tar xf vid.stab.tar.gz \
&& cd vid.stab-* \
&& mkdir build \
&& cd build \
# This line workarounds the issue that happens when the image builds in emulated (buildx) arm64 environment.
# Since in emulated container the /proc is mounted from the host, the cmake not able to detect CPU features correctly.
&& sed -i 's/include (FindSSE)/if(CMAKE_SYSTEM_ARCH MATCHES "amd64")\ninclude (FindSSE)\nendif()/' ../CMakeLists.txt \
&& cmake \
-G"Unix Makefiles" \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_SYSTEM_ARCH=$(arch) \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF \
-DUSE_OMP=ON \
.. \
&& make -j$(nproc) install \
&& echo "Libs.private: -ldl" >> /usr/local/lib/pkgconfig/vidstab.pc \
&& rm -r /tmp/vid*
RUN set -x \
&& wget $WGET_OPTS -O libvorbis.tar.gz "https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.gz" \
&& tar xf libvorbis.tar.gz \
&& cd libvorbis-* \
&& ./configure --disable-shared --enable-static --disable-oggtest \
&& make -j$(nproc) install \
&& rm -r /tmp/libvorbis*
RUN set -x \
&& wget $WGET_OPTS -O libvpx.tar.gz 'https://github.com/webmproject/libvpx/archive/v1.13.1.tar.gz' \
&& tar xf libvpx.tar.gz \
&& cd libvpx-* \
&& ./configure --enable-static --enable-vp9-highbitdepth --disable-shared --disable-unit-tests --disable-examples \
&& make -j$(nproc) install \
&& rm -r /tmp/libvpx*
RUN set -x \
&& wget $WGET_OPTS -O libwebp.tar.gz 'https://github.com/webmproject/libwebp/archive/v1.3.2.tar.gz' \
&& tar xf libwebp.tar.gz \
&& cd libwebp-* \
&& ./autogen.sh \
&& ./configure \
--disable-shared \
--enable-static \
--with-pic \
--enable-libwebpmux \
--disable-libwebpextras \
--disable-libwebpdemux \
--disable-sdl \
--disable-gl \
--disable-png \
--disable-jpeg \
--disable-tiff \
--disable-gif \
&& make -j$(nproc) install \
&& rm -r /tmp/libwebp*
# x264 only have a stable branch no tags and we checkout commit so no hash is needed
RUN set -x \
&& git clone 'https://code.videolan.org/videolan/x264.git' \
&& cd x264 \
&& git checkout '31e19f92f00c7003fa115047ce50978bc98c3a0d' \
&& ./configure --enable-pic --enable-static --disable-cli --disable-lavf --disable-swscale \
&& make -j$(nproc) install \
&& rm -r /tmp/*x264*
# x265 release is over 1 years old and master branch has a lot of fixes and improvements, so we checkout commit so no hash is needed
# -w-macro-params-legacy to not log lots of asm warnings
# https://bitbucket.org/multicoreware/x265_git/issues/559/warnings-when-assembling-with-nasm-215
# CMAKEFLAGS issue
# https://bitbucket.org/multicoreware/x265_git/issues/620/support-passing-cmake-flags-to-multilibsh
RUN set -x \
&& wget $WGET_OPTS -O x265_git.tar.bz2 'https://bitbucket.org/multicoreware/x265_git/get/ce8642f22123f0b8cf105c88fc1e8af9888bd345.tar.bz2' \
&& tar xf x265_git.tar.bz2 \
&& cd multicoreware-x265_git-*/build/linux \
&& sed -i '/^cmake / s/$/ -G "Unix Makefiles" ${CMAKEFLAGS}/' ./multilib.sh \
&& sed -i 's/ -DENABLE_SHARED=OFF//g' ./multilib.sh \
&& MAKEFLAGS="-j$(nproc)" \
CMAKEFLAGS="-DENABLE_SHARED=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DENABLE_AGGRESSIVE_CHECKS=ON -DCMAKE_ASM_NASM_FLAGS=-w-macro-params-legacy -DENABLE_NASM=ON -DCMAKE_BUILD_TYPE=Release" \
./multilib.sh \
&& make -C 8bit -j$(nproc) install \
&& rm -r /tmp/*x265*
# TODO: seems to be issues with asm on musl
RUN set -x \
&& wget $WGET_OPTS -O xavs2.tar.gz 'https://github.com/pkuvcl/xavs2/archive/refs/tags/1.4.tar.gz' \
&& tar xf xavs2.tar.gz \
&& cd xavs2-*/build/linux \
&& ./configure --disable-asm --enable-pic --disable-cli \
&& make -j$(nproc) install \
&& rm -r /tmp/*xavs2*
# http://websvn.xvid.org/cvs/viewvc.cgi/trunk/xvidcore/build/generic/configure.in?revision=2146&view=markup
# add extra CFLAGS that are not enabled by -O3
RUN set -x \
&& wget $WGET_OPTS -O libxvid.tar.gz 'https://downloads.xvid.com/downloads/xvidcore-1.3.7.tar.gz' \
&& tar xf libxvid.tar.gz \
&& cd xvidcore/build/generic \
&& CFLAGS="$CFLAGS -fstrength-reduce -ffast-math" ./configure \
&& make -j$(nproc) \
&& make install \
&& rm -r /tmp/libxvid* /tmp/xvidcore*
RUN set -x \
&& wget $WGET_OPTS -O zimg.tar.gz "https://github.com/sekrit-twc/zimg/archive/release-3.0.5.tar.gz" \
&& tar xf zimg.tar.gz \
&& cd zimg-* \
&& ./autogen.sh \
&& ./configure --disable-shared --enable-static \
&& make -j$(nproc) install \
&& rm -r /tmp/zimg*
# sed changes --toolchain=hardened -pie to -static-pie
# extra ldflags stack-size=2097152 is to increase default stack size from 128KB (musl default) to something
# more similar to glibc (2MB). This fixing segfault with libaom-av1 and libsvtav1 as they seems to pass
# large things on the stack.
RUN set -x \
&& version='6.1.1' \
&& wget $WGET_OPTS -O ffmpeg.tar.bz2 "https://ffmpeg.org/releases/ffmpeg-${version}.tar.bz2" \
&& tar xf ffmpeg.tar.bz2 \
&& cd ffmpeg-* \
&& sed -i 's/add_ldexeflags -fPIE -pie/add_ldexeflags -fPIE -static-pie/' ./configure \
&& ./configure \
--pkg-config-flags='--static' \
--extra-cflags='-fopenmp' \
--extra-ldflags='-fopenmp -Wl,-z,stack-size=2097152' \
--extra-version="$(date '+%Y-%m-%d')" \
--toolchain=hardened \
--disable-debug \
--disable-shared \
--disable-ffplay \
--disable-indev=sndio \
--disable-outdev=sndio \
--enable-static \
--enable-gpl \
--enable-version3 \
--enable-nonfree \
--enable-fontconfig \
--enable-gray \
--enable-iconv \
--enable-lcms2 \
--enable-libaom \
--enable-libaribb24 \
--enable-libass \
--enable-libbluray \
--enable-libdav1d \
--enable-libdavs2 \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libfribidi \
--enable-libgme \
--enable-libgsm \
--enable-libkvazaar \
--enable-libmodplug \
--enable-libmp3lame \
--enable-libmysofa \
--enable-libopencore-amrnb \
--enable-libopencore-amrwb \
--enable-libopenjpeg \
--enable-frei0r \
--enable-libopus \
--enable-librav1e \
--enable-librtmp \
--enable-librubberband \
--enable-libshine \
--enable-libsnappy \
--enable-libsoxr \
--enable-libspeex \
--enable-libsrt \
--enable-libsvtav1 \
--enable-libtheora \
--enable-libtwolame \
--enable-libuavs3d \
--enable-libvidstab \
--enable-libvmaf \
--enable-libvo-amrwbenc \
--enable-libvorbis \
--enable-libvpx \
--enable-libwebp \
--enable-libx264 \
--enable-libx265 \
--enable-libxavs2 \
--enable-libxml2 \
--enable-libxvid \
--enable-libzimg \
--enable-openssl \
&& make -j$(nproc) install
RUN set -x \
# prepare etc directory for usage in runtime
&& mkdir -p ./etc/ssl \
&& echo 'ffmpeg:x:10001:10001::/nonexistent:/sbin/nologin' > ./etc/passwd \
&& echo 'ffmpeg:x:10001:' > ./etc/group \
&& cp /etc/ssl/cert.pem ./etc/ssl/cert.pem
FROM scratch AS tests
COPY --from=builder /usr/local/bin/ffmpeg /bin/ffmpeg
COPY --from=builder /usr/local/bin/ffprobe /bin/ffprobe
COPY --from=builder /tmp/etc /etc
# sanity tests
RUN ["/bin/ffmpeg", "-version"]
RUN ["/bin/ffprobe", "-version"]
RUN ["/bin/ffmpeg", "-hide_banner", "-buildconf"]
# stack size
RUN ["/bin/ffmpeg", "-f", "lavfi", "-i", "testsrc", "-c:v", "libsvtav1", "-t", "100ms", "-f", "null", "-"]
# dns
RUN ["/bin/ffprobe", "-i", "https://github.com/favicon.ico"]
# tls/https certs
RUN ["/bin/ffprobe", "-tls_verify", "1", "-ca_file", "/etc/ssl/cert.pem", "-i", "https://github.com/favicon.ico"]
# clamp all files into one layer
FROM scratch AS runtime
COPY --from=builder /tmp/etc /etc
COPY --from=tests /bin /bin
LABEL \
# docs: <https://github.com/opencontainers/image-spec/blob/master/annotations.md>
org.opencontainers.image.title="ffmpeg" \
org.opencontainers.image.description="Statically built FFmpeg"
# use an unprivileged user
USER 10001:10001
ENTRYPOINT ["/bin/ffmpeg"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment