Skip to content

2.0.0 - Dynamic frameworks

Choose a tag to compare

@superuser404notfound superuser404notfound released this 17 Jul 06:51

Dynamic frameworks

FFmpegBuild 2.0.0 changes the shipped shape of the xcframeworks from static archives to dynamic frameworks (dylib-in-framework, @rpath install names, ad-hoc signed). Xcode embeds and signs them in the consuming app bundle automatically; no integration changes are needed beyond picking up the new version.

Why

The previous README claimed "App Store compatible when linked dynamically" while the package actually shipped static archives that SPM linked into the app binary. For closed-source App Store apps, statically linked LGPL code has no realistic compliance path (LGPL 6(a) would require publishing relinkable object files of the app). Dynamic frameworks satisfy LGPL section 6(b): end users can swap the FFmpeg libraries and re-sign, the app binary stays untouched. Thanks to the adopter who flagged the contradiction precisely.

License corrections

  • The FFmpeg portions are LGPL-2.1-or-later, not LGPL-3.0 as previously stated: the build enables neither --enable-version3 nor --enable-gpl. The repo LICENSE now carries the LGPL-2.1 text.
  • New LICENSES/ directory with all component texts and a per-component map (FFmpeg LGPL-2.1+, dav1d BSD-2-Clause, zimg WTFPL, libzvbi LGPL-2.0+ with MIT ure.c).
  • README gained a "Shipping in an App Store app" section with the concrete adopter steps (embed dynamically, reproduce license texts, link the source of the exact build).

libzvbi GPL excision

zvbi's tree contains three GPL-2 licensed source files (packet-830.c, pdc.c GPL-2-only, exp-vtx.c GPL-2+). packet-830.o was reachable from the LGPL packet.c and therefore got statically linked into consuming apps, which is incompatible with an LGPL distribution. build.sh now removes all three files from the library and replaces the two referenced entry points with LGPL stubs. They sit behind the VBI_EVENT_LOCAL_TIME / VBI_EVENT_PROG_ID event masks, which FFmpeg's teletext decoder never registers (it only registers VBI_EVENT_TTX_PAGE), so teletext subtitle decoding is unaffected.

Build script

  • ./build.sh builds the dynamic shape (default). ./build.sh static builds the previous static shape for adopters who can meet LGPL 6(a) themselves.
  • Framework Info.plists gained CFBundleSupportedPlatforms and CFBundleInfoDictionaryVersion (the plists get validated for real now that the frameworks are embedded).
  • Inter-framework references are rewritten to @rpath/<FW>.framework/<FW> (Versions/A layout on macOS); binaries are stripped and ad-hoc re-signed.

Breaking

  • SemVer major because the linkage shape changes: apps now carry the frameworks in YourApp.app/Frameworks/ instead of inside the app binary. Consumers pinning from: "1.x" stay on 1.0.5 until they opt in.
  • App size bookkeeping shifts from "app binary" to "embedded frameworks"; totals are comparable.

Sizes

Framework binaries as embedded in the app, release configuration:

Target FFmpeg dav1d Total
iOS / tvOS arm64 ~8.7 MB ~0.8 MB ~9.5 MB
macOS universal (arm64 + x86_64) ~18.1 MB ~2.4 MB ~20.5 MB

Comparable to the previous static shape.