Symbol leakage after incremental build with unchanged Mergeable setting
0 reputation · 24 Jul 2022, 05:45 UTC
0 reputation · 24 Jul 2022, 05:45 UTC
Goal: Ensure that only the intended public symbols are present in the dSYM and archive when an Xcode target links Swift packages and relies on incremental builds.
Uncertainty: The Mergeable build setting controls whether symbols from prior builds are retained; its behavior may differ across Xcode major versions, and changing the setting after a clean does not automatically regenerate existing dSYM files. Additionally, setting a target's public header visibility to Project can increase the risk of exposing types when the Mergeable setting retains old symbols.
Questions: Does toggling Mergeable to NO guarantee that previously exported symbols are stripped in the next incremental build on Xcode 15? How does the combination of Mergeable setting and Target Membership affect symbol visibility in the final archive? What verification steps can confirm that the dSYM contents reflect the intended public API after a change to Mergeable?
Toggling the Mergeable (MERGEABLE_BINARY) setting to NO does not guarantee that previously exported symbols are stripped during a subsequent incremental build in Xcode 15. Because incremental builds rely on existing object files and cached debug information, changing a build setting often fails to invalidate all previously generated artifacts. Consequently, stale symbols may persist in the resulting dSYM and archive.
The Mergeable setting is designed to facilitate the merging of binaries in modular build environments; it is not a primary mechanism for controlling symbol visibility. Symbol leakage during incremental builds typically occurs because:
Project and public header visibility is expanded, the compiler exports more symbols than necessary. If these are captured in an incremental build, they remain until the build folder is purged.To guarantee that only the intended public API is present in your final archive, follow these steps:
public or open, and that Target Membership is restricted to the necessary targets.Mergeable to NO if you do not require modular binary merging.Cmd + Shift + K) to remove all cached object files and stale dSYMs. This is the only way to ensure the linker starts from a clean state.Use the following scoped commands to verify that leaked symbols have been removed from the final binary and dSYM:
# List all exported global symbols in the binary
nm -gU Path/To/Your.app/YourBinary
# Inspect the dSYM for specific leaked symbol names
dwarfdump --debug-info Path/To/Your.dSYM | grep "SymbolName"
Missing Diagnostic Detail: Are you using a custom build script or a third-party dependency manager (e.g., CocoaPods) that might be overriding the MERGEABLE_BINARY setting at the target level?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.