qing
(Qing Yang)
1
My apology if here is not the right place to ask a linker question.
I noticed that adding -ObjC linker flag will always force to load Swift libraries, even though no symbol is referenced. After digging into the source code of ld64, I found this was actually intentional. I understand that -ObjC is need to load Objective-C categories, but the behavior of loading Swift libraries isn't documented anywhere and surprised me. Along with Swift non-strippable public symbols, -ObjC could make binary size bigger than expected.
I'm curious to learn why Swift libraries are force loaded by -ObjC and if there is a way to disable it.
The sample code to verify this behavior:
echo "public struct Foo{}" > lib.swift
swiftc -c -o lib.o lib.swift
libtool -static lib.o -o lib.a
Link it with -ObjC and -why_load. We can see below message.
-ObjC forced load of lib.a(lib.o)
Keith
(Keith Smiley)
2
Joe_Groff
(Joe Groff)
3
It was a short-term modification to keep ld64 from dropping dynamically-referenced Swift metadata from getting stripped. As Swift's own dead stripping gets better it should become unnecessary. In the meantime, I don't think there is a way to disable the behavior; you could leave out -ObjC and manually mark ObjC categories and Swift metadata symbols you need with -u instead, perhaps.
1 Like
qing
(Qing Yang)
4
Thank you for the link! I remember that problem but didn't realize the fix was in -ObjC.
From the ld64 source code, -ObjC just loads all Swift object files. It doesn't seem to be better than -all_load for Swift-dominant codebase 
jrose
(Jordan Rose)
5
This will likely need to be tied to the "limit reflection" work, since a library might contain nothing but protocol conformances intended to be referenced dynamically (i.e. through as?).
1 Like
Joe_Groff
(Joe Groff)
6
Definitely. We'd need to address that issue before returning the flag to its original behavior.
1 Like
Is there different behavior for this when using Swift Package Manager for integration? We're noticing that when linking various things via an xcodeproj integration itself the -ObjC flag is required to force load libraries, but the flag is not required if we link the package via SPM.
1 Like