GHC should expose a mode for object merging
Problem
Function-section-splitting (e.g. GHC's -split-sections flag) allows the linker to reduce the size of statically-linked executables by placing each function in its own section, allowing unused sections to be dropped in the final link.
However, this carries with it a cost: loading such an object file (e.g. using GHC's RTS linker) requires a great deal of work as each section must be separately mapped. This can result in significant object loading times in GHCi.
To reduce this cost @simonmar introduced the notion of a "GHCi library", which is an object produced from the constitute module objects of a library, merging all text sections into a single section. This significantly lowers the cost of loading.
However, currently the logic for producing these objects is repeated throughout the ecosystem:
- the Hadrian and
makebuild systems both contain some logic - GHC has
GHC.Driver.Pipeline.Execute.joinObjectFiles -
CabalhasDistribution.Simple.Program.Ld.combineObjectFiles
This repetition seems unnecessary and a potential source of bugs. In the case of Cabal the logic is actually wrong, resulting in #15524 and #20682.
Solution
I suggest that GHC grows a new mode for the production of GHCi objects. The mode, e.g. ghc --join-objects, would be invoked with a list of objects and a --output flag and would invoke ld with the appropriate flags (e.g. -r and possibly a linker script). Hadrian, make, and Cabal could all use this mode, eliminating the repetition of object joining logic.