How Apple SDK overlays work?

I am curious about the inner workings of the Apple SDK overlays. For example, when we import Foundation what does the Swift compiler? The output executable seems to be linked against both to libswiftFoundation.dylib and the Foundation.framework.

Also, all the overlays mark the original Objective-C frameworks as @_exported so if we import the Swift equivalent we would have the Objective-C module imported as well.

How this works under-the-hood?

There’s nothing too complicated in there:

  • The overlays all have a line like @_exported import FooKit. This is basically the same effect as -import-underlying-module, which you’ll see when you compile a mixed-source Swift/Objective-C framework in Xcode, and all it means is “go find the Objective-C thing called FooKit, like me, and make it available to clients too”. (@_exported is an independently useful feature, too.)

  • The Swift compiler looks for Swift modules before it looks for Objective-C modules, so it finds FooKit.swiftmodule in the lib/swift/macosx/x86_64/ directory before it finds the real FooKit.framework (or whatever). This is kind of a hack, and isn’t necessary with a real mixed-source framework.

  • The overlays are compiled with a special flag that forces them to be linked into the final binary, even if you don’t use any symbols from them, because they have metadata that’s needed at runtime. They also specify that the library to link is named “swiftFooKit”. That’s not necessary with a mixed-source framework either, because the overlays will get linked as long as you use something from the Swift or Objective-C parts of the framework, and frameworks get autolinking for free on Apple platforms.

  • Xcode makes sure to copy the overlay dylibs into your app even if you don’t mention them in your project. Normally you’d be using the “Embed Frameworks” section in the target settings.

So overlays are just a way of doing Xcode-style mixed-source frameworks, but with a separate dylib so they can be packaged with an app. They’re a hack.


Great, thanks for the explanation! :+1:t2: