Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions .github/workflows/binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,30 @@ jobs:

- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: brew install nasm pkg-config x264 x265
run: brew install nasm pkg-config x265

- name: Install dependencies (Linux)
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends nasm pkg-config clang libx264-dev libx265-dev
sudo apt-get install -y --no-install-recommends nasm pkg-config clang libx265-dev

# x264 puts its ABI version in its symbol names (x264_encoder_open_165), so an FFmpeg
# compiled against the runner's x264 doesn't link with the x264 of another system. The
# archive carries its own static x264 instead, which the linker finds before the system's.
- name: Compile x264
if: contains(matrix.features, 'x264')
env:
X264_REV: b35605ace3ddf7c1a5d67a2eb553f034aef41d55 # stable, 0.165.3222
run: |
git init -q x264
git -C x264 fetch -q --depth 1 https://code.videolan.org/videolan/x264.git "$X264_REV"
git -C x264 checkout -q FETCH_HEAD
cd x264
./configure --prefix="$GITHUB_WORKSPACE/external" --enable-static --enable-pic --disable-cli --disable-opencl
make -j"$(getconf _NPROCESSORS_ONLN)" install-lib-static
echo "PKG_CONFIG_PATH=$GITHUB_WORKSPACE/external/lib/pkgconfig" >> "$GITHUB_ENV"
echo "FFMPEG_BINARIES_BUNDLE_LIBS=$GITHUB_WORKSPACE/external/lib/libx264.a" >> "$GITHUB_ENV"

- name: Compile FFmpeg
run: cargo build --release --target ${{ matrix.target.triple }} --features "build,static,build-portable,${{ matrix.features }}"
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ build script first downloads a static FFmpeg matching the target and the enabled
the [`binaries-<version>` release](https://github.com/dmtrKovalenko/rust-ffmpeg-sys/releases)
and only compiles FFmpeg from source when there is none. Archives are built by
`.github/workflows/binaries.yml` for macOS (arm64, x86_64) and Linux (x86_64, arm64) with the
codec sets fframes uses. External codec libraries (x264, x265) still come from the system.
codec sets fframes uses. They carry a static x264, because x264 puts its ABI version in its
symbol names and an FFmpeg compiled against one x264 doesn't link with another. x265 still
comes from the system.

- `FFMPEG_FORCE_BUILD=1` always compiles from source (so do `FFMPEG_MARCH`/`FFMPEG_MTUNE`, the
archives are compiled with `build-portable`).
- `FFMPEG_BINARIES_URL` overrides the download URL template (`{tag}`, `{key}`; `file://` works).
- `FFMPEG_BINARIES_CACHE` is where downloads are kept (default: the user cache directory).
- `FFMPEG_BINARIES_EXPORT_DIR` makes a source build write its archive there.
- `FFMPEG_BINARIES_BUNDLE_LIBS` lists static libraries an exported archive carries in `lib/`.

## Feature flags

Expand Down
14 changes: 14 additions & 0 deletions build_prebuilt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
//! directory), so that every project on the machine downloads them once.
//! - `FFMPEG_BINARIES_EXPORT_DIR`: after compiling from source, write the archive and its key to
//! this directory (used by CI to produce the binaries).
//! - `FFMPEG_BINARIES_BUNDLE_LIBS`: static libraries (a path list, like `PATH`) that are copied
//! into the archive's `lib/` on export. CI bundles x264 this way: its ABI version is part of
//! its symbol names (`x264_encoder_open_165`), so an FFmpeg compiled against one x264 doesn't
//! link with another, and the system's x264 differs from machine to machine.
//!
//! Archives are compiled with the `build-portable` flags, so setting `FFMPEG_MARCH` or
//! `FFMPEG_MTUNE` compiles from source as well.
Expand All @@ -39,6 +43,7 @@ pub fn rerun_if_env_changed() {
"FFMPEG_FORCE_BUILD",
"FFMPEG_BINARIES_CACHE",
"FFMPEG_BINARIES_EXPORT_DIR",
"FFMPEG_BINARIES_BUNDLE_LIBS",
"FFMPEG_MARCH",
"FFMPEG_MTUNE",
] {
Expand Down Expand Up @@ -203,6 +208,15 @@ pub fn export(dist: &Path) -> io::Result<()> {
return Ok(());
};
fs::create_dir_all(&export_dir)?;
// Next to FFmpeg's own libraries, the linker finds them before the system's.
if let Some(libs) = env::var_os("FFMPEG_BINARIES_BUNDLE_LIBS") {
for lib in env::split_paths(&libs) {
let name = lib
.file_name()
.ok_or_else(|| io::Error::other(format!("{} is not a library", lib.display())))?;
fs::copy(&lib, dist.join("lib").join(name))?;
}
}
let key = key();
run(Command::new("tar")
// pkg-config files hold absolute paths of the build machine
Expand Down