Skip to content
  • Moritz Angermann's avatar
    [macOS] improved runpath handling · 43f97049
    Moritz Angermann authored and Ben Gamari's avatar Ben Gamari committed
    In b592bd98 we started using
    -dead_strip_dylib on macOS when lining dynamic libraries and binaries.
    The underlying reason being the Load Command Size Limit in macOS
    Sierra (10.14) and later.
    
    GHC will produce @rpath/libHS... dependency entries together with a
    corresponding RPATH entry pointing to the location of the libHS...
    library. Thus for every library we produce two Load Commands.  One to
    specify the dependent library, and one with the path where to find it.
    This makes relocating libraries and binaries easier, as we just need to
    update the RPATH entry with the install_name_tool. The dynamic linker
    will then subsitute each @rpath with the RPATH entries it finds in the
    libraries load commands or the environement, when looking up @rpath
    relative libraries.
    
    -dead_strip_dylibs intructs the linker to drop unused libraries. This in
    turn help us reduce the number of referenced libraries, and subsequently
    the size of the load commands.  This however does not remove the RPATH
    entries.  Subsequently we can end up (in extreme cases) with only a
    single @rpath/libHS... entry, but 100s or more RPATH entries in the Load
    Commands.
    
    This patch rectifies this (slighly unorthodox) by passing *no* -rpath
    arguments to the linker at link time, but -headerpad 8000.  The
    headerpad argument is in hexadecimal and the maxium 32k of the load
    command size.  This tells the linker to pad the load command section
    enough for us to inject the RPATHs later.  We then proceed to link the
    library or binary with -dead_strip_dylibs, and *after* the linking
    inspect the library to find the left over (non-dead-stripped)
    dependencies (using otool).  We find the corresponding RPATHs for each
    @rpath relative dependency, and inject them into the library or binary
    using the install_name_tool.  Thus achieving a deadstripped dylib (and
    rpaths) build product.
    
    We can not do this in GHC, without starting to reimplement a dynamic
    linker as we do not know which symbols and subsequently libraries are
    necessary.
    
    Commissioned-by: Mercury Technologies, Inc. (mercury.com)
    (cherry picked from commit 4ff93292
    
    )
    Signed-off-by: default avatarMoritz Angermann <moritz.angermann@iohk.io>
    43f97049