Skip to content

3.0.0 - Namespaced frameworks (AetherLibavcodec and friends)

Latest

Choose a tag to compare

@superuser404notfound superuser404notfound released this 31 Aug 08:17

Renames every shipped target, product, framework bundle, install name and module map to carry an Aether prefix, so this package can sit in one app next to another FFmpeg. Nothing is rebuilt: the binaries are the same n8.1.2 build as 2.5.0, with the same decoder, parser and demuxer counts. Only names change, and the FFmpeg C API is not among them.

Why

SwiftPM target and product names are unique across the whole dependency graph, and every FFmpeg packaged for Apple platforms declares the same six: FFmpegKit and its forks, MobileVLCKit, the mpv builds. An app whose player has a fallback ladder therefore could not resolve this package at all:

error: multiple similar targets 'Libavcodec', 'Libavfilter', 'Libavformat' and 3 others
appear in package 'ffmpegbuild' and 'ffmpegkit', this may indicate that the two packages
are the same and can be de-duplicated by using mirrors

Neither remedy in that message applies. moduleAliases renames Swift source targets, not binary ones, and mirrors would substitute one FFmpeg for the other, which is wrong here: this build has no network stack and a deliberately small allowlist, the other is a full build its own player needs.

Behind the graph error sat a second collision. Both packages embed a Libavcodec.framework into App.app/Frameworks/ with the install name @rpath/Libavcodec.framework/Libavcodec, so even a graph that resolved would have had two bundles claiming one path.

Both are name problems. Both are fixed by naming.

What changed

Before Now
.product(name: "FFmpegBuild", package: "FFmpegBuild") .product(name: "AetherFFmpegBuild", package: "FFmpegBuild")
import Libavcodec import AetherLibavcodec
Libavformat, Libavutil, Libswresample, Libswscale, Libavfilter, Libdav1d, Libzimg, Libzvbi the same names with an Aether prefix
@rpath/Libavcodec.framework/Libavcodec @rpath/AetherLibavcodec.framework/AetherLibavcodec

The package itself keeps its name and its URL, so the dependency declaration only changes in the version.

avcodec_open2, avformat_open_input, AVCodecContext and the rest are untouched. Sources that call FFmpeg need their import line changed and nothing else.

The part a rename cannot do

Distinct module and bundle names do not rename C symbols, and this release does not pretend otherwise.

Two dynamic frameworks are enough on their own: the two-level namespace records, per reference, which dylib a symbol came from, so an app can hold this build and another one and each caller reaches its own. That is the shape this package ships, and it is the case the rename unblocks.

A static FFmpeg in the same executable is different. Its symbols become ordinary definitions inside the executable and win for every object linked beside them, including a statically linked copy of the code that meant to call this build. The fix is on the host side: link that code into its own dynamic framework, so its _av* references bind at that framework's link instead. AetherEngine's docs/api.md › One FFmpeg documents that recipe and the two commands that show which build actually answered.

With distinct framework names, otool -L is finally unambiguous about that.

Upgrading

  • Change the product name in your target's dependencies, and prefix every import Libav….
  • If you carried this rename as a private fork, this release is that fork upstream. Drop the fork and pin from: "3.0.0".
  • If you consume AetherEngine, nothing here reaches you: the engine's public API never exposed an FFmpeg type. Take an engine release that pins 3.0.0.

Under the hood

The frameworks' own headers needed the same rewrite. Clang resolves a header's #include "libavutil/frame.h" as a framework include, case insensitively, which is how these headers found their siblings while the frameworks were named Libavutil. Under the prefix that lookup finds nothing, so build.sh rewrites the cross-includes while it packages, rather than patching the vendored headers.

Reported by KIPTV, who had been carrying the rename privately, as IPTVX/FFmpegBuild and others were.