Auto Linking on iOS & macOS
Auto Linking Explained
When object files get linked at the final build stage, the linker needs to know which libraries to link against. For example, if you add #import <AppKit/AppKit.h>
to an implementation file, you need to also add -framework AppKit
to the linker flags.
Auto Linking aims to remove the latter step, i.e., it aims to derive the library linker flags from the import statements in your code. Developers do not need to add any framework/library linker flags anymore, they can just start using any framework by importing1.
Under the Hood
Auto Linking works by inserting linker flags in object files. When the linker creates the final executable, it’s as if those linker flags were passed as arguments.
The linker flags are stored as LC_LINKER_OPTION
load commands in object files. They can be printed using otool -l file.o
:
Load command 5
cmd LC_LINKER_OPTION
cmdsize 32
count 2
string #1 -framework
string #2 AppKit
Load command 6
cmd LC_LINKER_OPTION
cmdsize 40
count 2
string #1 -framework
string #2 QuartzCore
I recently added support for LC_LINKER_OPTION
to MachO-Explorer, so you can use it to inspect the linker flags visually as well.
Frameworks vs Dynamic Libraries
It’s important to note that Auto Linking can work with any Clang module, not just frameworks. For example, /usr/include/module.modulemap
in the macOS SDK defines the zlib
module as follows:
module zlib [system] [extern_c] {
header "zlib.h"
export *
link "z"
}
The above means that if we were to use #import <zlib.h>
with modules turned on, -lz
will be automatically inserted by the linker. We can verify this using otool -l
:
Load command 4
cmd LC_LINKER_OPTION
cmdsize 16
count 1
string #1 -lz
Controlling Auto Linking
Auto Linking is active only when Clang modules are turned on. If you’re invoking Clang on the command line, this means passing -fmodules
. The Xcode setting is CLANG_ENABLE_MODULES
(“Enable Modules (C and Objective-C)”).
Auto Linking itself can be disabled even if modules are enabled. The Clang option is -fno-autolink
and the corresponding Xcode setting is CLANG_MODULES_AUTOLINK
(“Link Frameworks Automatically”).
Swift
Swift extensively uses the Auto Linking mechanism to link against its runtime and overlay frameworks. For example, if you were to compile a simple Swift file using swiftc -c file.swift
and inspect it:
Load command 4
cmd LC_LINKER_OPTION
cmdsize 32
count 1
string #1 -lswiftAppKit
Load command 5
cmd LC_LINKER_OPTION
cmdsize 24
count 1
string #1 -lswiftCore
Load command 8
cmd LC_LINKER_OPTION
cmdsize 32
count 1
string #1 -lswiftDarwin
Load command 39
cmd LC_LINKER_OPTION
cmdsize 40
count 1
string #1 -lswiftSwiftOnoneSupport
Load command 41
cmd LC_LINKER_OPTION
cmdsize 40
count 1
string #1 -lswiftCompatibility50
Load command 42
cmd LC_LINKER_OPTION
cmdsize 56
count 1
string #1 -lswiftCompatibilityDynamicReplacements
References
-
Either using
#import
or@import
in Objective-C orimport
in Swift. ↩︎