Dead code stripping on a dynamic framework doesn't strip unused symbols from a linked static library (SPM)

When a dynamic framework target links a swift package that can be statically linked (I.e. SPM has decided it can be static due to having a single upstream dynamic dependency) unused symbols don't appear to be stripped. I'm defining unused here as the framework doesn't use the symbols from the static library, and the static library is an internal dependency of the framework.

I appreciate that the final executable linking the dynamic framework at runtime won't contain these unused symbols, but they are still present in the framework so may potentially incur an overhead when linking dynamically.

Screenshot 2023-03-14 at 11.00.33

Dead code stripping is enabled in the frameworks build settings.

I have confirmed that this also propagates through to the linker via the dead-strip flag

Side note: Whilst in this area I noticed that it appears using SPM static libraries acts differently to a cocoa touch static library or a static framework. The latter two produce an archive containing all the object files for that library, but I can't see evidence of SPM doing the same thing. Instead, it appears to produce a solitary object file for the whole library, this might also be contributing to the issue as it doesn't give the linker an opportunity to selectively load only the object files that are used.

Edit: I probed the resulting static library object file a bit more and it turns out all the public symbols in there are flagged as no dead strip. I'm not 100% why but there's probably a good reason for it.

0000000000000f78 (__DATA,__const) external [no dead strip] _$s12FeatureACore11UnusedClassC14unusedPropertySSvpMV
0000000000000928 (__TEXT,__const) external [no dead strip] _$s12FeatureACore11UnusedClassC14unusedPropertySSvpWvd
00000000000004a0 (__TEXT,__text) external [no dead strip] _$s12FeatureACore11UnusedClassC14unusedPropertySSvpfi
00000000000005f0 (__TEXT,__text) external [no dead strip] _$s12FeatureACore11UnusedClassC14unusedPropertySSvs
0000000000000994 (__TEXT,__const) external [no dead strip] [alt entry] _$s12FeatureACore11UnusedClassC14unusedPropertySSvsT
1 Like

Hey, I'm curious if you tried the Swift frontend flag internalize-at-link, would like to know if that makes a difference in your case.

See: Why public symbols are always no_dead_strip?