Skip to content

Build only what ffmpeg links - #846

Merged
wader merged 2 commits into
wader:masterfrom
Dummgelaufen007:build-only-needed
Oct 26, 2026
Merged

wader merged 2 commits into
wader:masterfrom
Dummgelaufen007:build-only-needed

Conversation

@Dummgelaufen007

@Dummgelaufen007 Dummgelaufen007 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Most recipes build everything their project offers by default: tools, test suites, examples, docs and sometimes a shared library next to the static one. None of it ends up in ffmpeg, but it costs compile time and, for some test suites, a download during the build. This PR switches that off and drops library features and apk packages nothing uses. ffmpeg loses nothing, builds faster.

Tools, tests, examples and docs

Where a project has an option, it is set (table at the end). glib has none for its tools (gio, gsettings, gdbus and others carry the install tag bin, gio/meson.build#L1056-L1139), so the recipe builds and installs only the targets tagged devel and bin-devel: libraries, headers, .pc files and build tools. meson's install tags are meant for packagers (Installing.md#L152-L161); a static library is devel (backends.py#L1746).

Library features ffmpeg cannot reach

The code dropped here runs only through API calls ffmpeg n9.0.2 never makes:

Library Option Why
cairo -Dtee=disabled no cairo_tee call in pango, librsvg, libass or ffmpeg (src/meson.build#L199-L201)
libbluray -Dfreetype=disabled freetype serves only bd_register_overlay_proc (bluray.c#L4133-L4144), which ffmpeg's bluray.c does not call
librabbitmq -DENABLE_SSL_SUPPORT=OFF ffmpeg opens only amqp_tcp_socket_new (libamqp.c#L138)
libssh -DWITH_PCAP=OFF needs ssh_set_pcap_file (pcap.c#L530-L541), which ffmpeg's libssh.c does not call
libjxl -DJPEGXL_ENABLE_TRANSCODE_JPEG=OFF ffmpeg never subscribes to JXL_DEC_JPEG_RECONSTRUCTION (libjxldec.c#L75-L77)

apk packages no recipe uses

Package Why
graphite2-static harfbuzz's graphite2 is disabled by default (meson_options.txt#L16-L19)
tiff, libjpeg-turbo, giflib (+-dev) lcms2 now --without-jpeg --without-tiff (configure.ac#L101, #L119), used only by its tools jpgicc and tificc (jpgicc, tificc); libjxl uses them only for tools or tests (lib/CMakeLists.txt#L187-L188), theora only for examples (configure.ac#L501-L513)
tcl for srt's Tcl configure (configure#L1); the recipe uses cmake
cunit cunit-dev libmysofa needs it only with BUILD_TESTS (src/CMakeLists.txt#L153-L156)

Options per library

Library Change Source
vmaf -Denable_tools=false meson_options.txt#L11
glib -Dtests=false, -Dsysprof=disabled (auto clones sysprof, meson.build#L34-L45) meson.options#L96, #L69-L73
harfbuzz gobject, subset, raster, vector, gpu, tests, utilities disabled meson_options.txt
pango -Dbuild-testsuite=false, -Dbuild-examples=false, so static instead of both meson.options#L23-L28
dav1d -Denable_tools=false, -Denable_tests=false (tests clone checkasm, tests/meson.build#L30-L36) meson_options.txt#L13, #L23
libbluray -Denable_tools=false meson_options.txt#L11
svtav1 -DBUILD_APPS=OFF, -DSVT_AV1_LTO=OFF (LTO moves code generation to ffmpeg's final, serial link) CMakeLists.txt#L268, #L409-L421
libvpx --disable-tools configure#L191-L196
x265 -DENABLE_CLI=OFF CMakeLists.txt#L1228
libjxl -DJPEGXL_ENABLE_TOOLS=OFF CMakeLists.txt#L142
libzmq --disable-perf, --disable-curve-keygen, --without-docs configure.ac#L490-L501
vvenc -DVVENC_LIBRARY_ONLY=ON, -DVVENC_ENABLE_LINK_TIME_OPT=OFF (as svtav1) CMakeLists.txt#L185, #L192, #L320-L328

Research and wording by Claude (Anthropic), directed and reviewed by me.

@wader wader left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most things looks good 👍 all the disabling of things to build like tests etc i think can be merged. I'm a bit more reluctant about some that does manual/complex installs, could some of those break in confusing ways in future versions of deps?

Comment thread Dockerfile Outdated
echo "$MP3LAME_SHA256 lame.tar.gz" | sha256sum -c - && \
tar $TAR_OPTS lame.tar.gz && cd lame-* && \
# configure never sets NDEBUG, the encoder is full of asserts
CFLAGS="$CFLAGS -DNDEBUG" \

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at some of the asserts, ex in https://github.com/enzo1982/lame/blob/8723d2fdd074c32083fed338fe2d437157b75471/libmp3lame/quantize.c#L2065, it seem like they might assert things that are required or limits of the mp3 frame formats or standard? so would the result of not asserting produce a broken output?

Comment thread Dockerfile Outdated
make -j$(nproc) xeve && \
install -D -m644 src_main/libxeve.a /usr/local/lib/xeve/libxeve.a && \
install -D -m644 -t /usr/local/include/xeve ../inc/xeve.h xeve_exports.h && \
install -D -m644 xeve.pc /usr/local/lib/pkgconfig/xeve.pc

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if doing manual install (here and some other places) might break in future versions? is it worth the build time save?

@Dummgelaufen007

Copy link
Copy Markdown
Contributor Author

Thanks for looking it over. Some settings were more aggressive than I saw myself, so I pulled a few teeth:

What remains are the projects' own options, LTO off in svtav1 and vvenc (ffmpeg's final link got 52 s faster in CI), the library features ffmpeg cannot reach and the unused apk packages.

Research and wording by Claude (Anthropic), directed and reviewed by me.

@wader

wader commented Oct 25, 2026

Copy link
Copy Markdown
Owner

Thanks for looking it over. Some settings were more aggressive than I saw myself, so I pulled a few teeth:

* `NDEBUG` for lame is gone: the asserts are lame's error handling in release builds ([configure.ac#L1092-L1096](https://svn.code.sf.net/p/lame/svn/tags/RELEASE__4_0/configure.ac)), and the flag saved no time.

No worries, i think both assert and produce broken frames is bad, but maybe assert it less confusing/bad? i wonder it this might be fixable in lame somehow but i don't know enough about lame. I've seen some of these asserts trigger in production systems so that why i noticed.

What remains are the projects' own options, LTO off in svtav1 and vvenc (ffmpeg's final link got 52 s faster in CI), the library features ffmpeg cannot reach and the unused apk packages.

Just out of curiosity: Any idea if it would be possible to do whole binary LTO and if so how would if affect performance? would it "just" involved compile more things with LTO and the linker knows how to mix LTO with non-LTO?

Comment thread Dockerfile
ninja -j$(nproc) -vC build install
# only the targets with the install tags devel and bin-devel: libraries, headers, .pc files and build tools
ninja -j$(nproc) -vC build $(jq -r --arg b "$PWD/build/" '.targets | to_entries[] | select(.value.tag == "devel" or .value.tag == "bin-devel") | .key | ltrimstr($b)' build/meson-info/intro-install_plan.json) && \
meson install -C build --no-rebuild --tags devel,bin-devel

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no standard way to express "install only dev stuff"? but i do appreciate some jq :)

@Dummgelaufen007

Copy link
Copy Markdown
Contributor Author

lame: Agreed, an abort is the clearer failure. lame's own configure calls the asserts "a quick and user-unfriendly fix", the real solution being proper error messages (configure.ac#L1092-L1096). Its history lists such asserts fixed once someone reported the input, e.g. ticket #501, so an input that triggers one in production is worth a report to lame.

meson: For installing, yes: meson install --tags devel is the standard way (Installing.md#L152-L161). But it only filters what gets installed; meson compile still builds every default target and takes target names, not tags (Commands.md). The jq reads the target names for those tags from meson's install plan.

Whole binary LTO: A bigger undertaking than it looks, so I opened #848 for it.

Research and wording by Claude (Anthropic), directed and reviewed by me.

Comment thread Dockerfile
-Dgobject=disabled \
-Dsubset=disabled \
-Draster=disabled \
-Dvector=disabled \

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need vector or raster because ffmpeg draw filter uses freetype for drawing? harfbuzz only for shaping?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, harfbuzz only shapes the text there and freetype draws it. raster and vector are separate libraries that nothing here links.

Research and wording by Claude (Anthropic), directed and reviewed by me.

@wader
wader merged commit 49c38a0 into wader:master Oct 26, 2026
2 checks passed
@wader

wader commented Oct 26, 2026

Copy link
Copy Markdown
Owner

Thanks!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants