Compile Statically Linked FFmpeg on macOS

Compiling a statically linked version of FFmpeg on macOS allows you to create a portable executable that runs on other macOS systems without requiring external dependency installations. Because macOS does not support fully static binaries due to the requirement of linking against the system’s closed-source libSystem.dylib, “static” on macOS means statically linking all third-party libraries (like x264, x265, and VP9) while dynamically linking only the essential system frameworks. This guide provides the step-by-step terminal commands required to set up your environment, download the source code, and compile a portable FFmpeg binary.

Step 1: Install Required Build Tools

Before compiling, you need to install the macOS command line tools and essential build utilities. Open your terminal and run the following commands:

# Install Xcode Command Line Tools
xcode-select --install

# Install build dependencies via Homebrew
brew install automake autoconf libtool pkg-config nasm yasm cmake

Step 2: Create a Build Directory

To keep your files organized, create a dedicated workspace directory where the source code will be downloaded and compiled.

mkdir -p ~/ffmpeg-static/target
cd ~/ffmpeg-static

Step 3: Download and Compile Static Dependencies

To ensure third-party encoders are statically compiled into FFmpeg, you must build them from source as static libraries (.a files) rather than dynamic libraries (.dylib).

Below is how to compile libx264 (H.264 video encoder) statically:

git clone --depth 1 https://code.videolan.org/videolan/x264.git
cd x264
./configure --prefix="../target" --enable-static --disable-shared --enable-pic
make -j$(sysctl -n hw.ncpu)
make install
cd ..

To compile libx265 (HEVC video encoder) statically:

git clone https://bitbucket.org/multicoreware/x265_git.git
cd x265_git/source
cmake -G "Unix Makefiles" \
  -DCMAKE_INSTALL_PREFIX="../../target" \
  -DENABLE_SHARED=OFF \
  -DENABLE_CLI=OFF \
  .
make -j$(sysctl -n hw.ncpu)
make install
cd ../..

Step 4: Download and Configure FFmpeg

Now, download the latest stable FFmpeg source code and configure it to point to your statically compiled target directory.

# Clone FFmpeg source
git clone --depth 1 https://git.ffmpeg.org/ffmpeg.git
cd ffmpeg

# Export path variables so FFmpeg configuration can find the static libraries
export PKG_CONFIG_PATH="$HOME/ffmpeg-static/target/lib/pkgconfig"
export PATH="$HOME/ffmpeg-static/target/bin:$PATH"

# Configure the build
./configure \
  --prefix="$HOME/ffmpeg-static/target" \
  --pkg-config-flags="--static" \
  --extra-cflags="-I$HOME/ffmpeg-static/target/include" \
  --extra-ldflags="-L$HOME/ffmpeg-static/target/lib" \
  --extra-libs="-lpthread -lm" \
  --bindir="$HOME/ffmpeg-static/target/bin" \
  --enable-gpl \
  --enable-nonfree \
  --enable-static \
  --disable-shared \
  --enable-libx264 \
  --enable-libx265

Step 5: Compile and Verify the Binary

With the configuration complete, you can now compile the binary and verify that it does not dynamically link to any non-system libraries.

# Compile using all available CPU cores
make -j$(sysctl -n hw.ncpu)
make install

Once the compilation finishes, verify the portability of your new ffmpeg binary using the otool command:

otool -L ~/ffmpeg-static/target/bin/ffmpeg

The output will list the dynamic libraries used by the executable. You should only see system paths (such as /usr/lib/libSystem.B.dylib and system frameworks like CoreFoundation), while libx264 and libx265 will not appear, indicating they have been successfully linked statically into the executable. Your portable binary is located at ~/ffmpeg-static/target/bin/ffmpeg.