5.4 · Library evolution, module interfaces, and the ABI boundary
Shipping a binary framework means promising other people’s apps that a new version will still load. Swift has a mode that makes that promise, and a text file that records it.
Mental model. Library evolution turns the question “can I see this type’s layout?” from a compile-time given into a runtime query, and @frozen and @inlinable are how you opt back out.
Making a library evolvable
What the flag changes, and what it costs.
- What does -enable-library-evolution change, and why would you not turn it on for an app?
By default Swift compiles a module for its own build: it freely bakes in struct layouts, enum case numbers and function bodies, and a client must be rebuilt…
What clients actually see
The module interface file.
- What is a .swiftinterface file, and what does it show about @inlinable and @frozen?
A compiled .swiftmodule is a binary tied to one compiler version. A .swiftinterface is a textual description of a module’s public API, generated with library…
More in Compiler & language internals
- 5.1 · From source to machine code, and how to look inside
- 5.2 · Devirtualisation, whole-module optimisation, inlining, exclusivity
- 5.3 · Specialisation, witness tables, and opaque vs existential in the compiled code
- 5.5 · How Swift macros work, and the roles they play
- 5.6 · Why it compiles slowly, and what rebuilds
- 5.7 · Swift 6 language mode and upcoming features
- 5.8 · Symbol names, linkage, lazy globals and reflection metadata: what is in the binary
- 5.9 · Optimisation levels, closure contexts, ownership conventions and value layout
- 5.10 · What property wrappers, result builders, async and throws compile to
- 5.11 · Package access, SPI, internal imports, strict memory safety and pre-specialisation