[commit: ghc] master: dead strip dylibs on macOS (b592bd9)

git at git.haskell.org git at git.haskell.org
Thu May 31 02:06:03 UTC 2018


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/b592bd98ff25730bbe3c13d6f62a427df8c78e28/ghc

>---------------------------------------------------------------

commit b592bd98ff25730bbe3c13d6f62a427df8c78e28
Author: Moritz Angermann <moritz.angermann at gmail.com>
Date:   Wed May 30 20:40:11 2018 -0400

    dead strip dylibs on macOS
    
    When linking dynamic libraries or executables, we compute the full
    transitive closure over the dependencies, and instruct the linker
    to link all dependencies.  With deep dependency trees the number
    of transitive dependencies can grow quickly.
    
    macOS since the Sierra release has an upper limit on the load
    command sizes the linker parses when loading dynamic lirbaries.
    As such it is mandatory to keep the number of load commands (and
    their size) small on recent macOS releases.
    
    An approach that would just link direct dependencies as specified
    by the -package-id flag is insufficient, because GHC can inline
    across packages and the library or executable being linked could
    refer to symbols deep in the dependency tree.
    
    If we just recursively linked librarys and re-exported their
    symbols, this increases the number of symbols in libraries with
    many dependencies and ultimately puts excessive strain on the
    linker to the point where linking takes a lot longer than even
    the compilation of the modules.
    
    We can however build a list of symbols from the obejcts we want
    to link, and try to compute the libraries we need to link that
    contain those symbols from the transitive dependency closure.
    Luckily, we don't need to write this ourselves, but can use
    the ld64 `-dead_strip_dylibs` linker flag on macOS to achive
    the same result.  This will link only the libraries that are
    actually referenced, which is usually a small subset of the
    full transitive dependency closure.  As such we should stay
    within the load command size limit for almost all but pathological
    cases.
    
    Reviewers: bgamari
    
    Reviewed By: bgamari
    
    Subscribers: lelf, rwbarton, thomie, carter
    
    GHC Trac Issues: #14444
    
    Differential Revision: https://phabricator.haskell.org/D4714


>---------------------------------------------------------------

b592bd98ff25730bbe3c13d6f62a427df8c78e28
 compiler/main/DriverPipeline.hs | 3 +++
 compiler/main/SysTools.hs       | 1 +
 2 files changed, 4 insertions(+)

diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 5ea83ce..e4a9fa2 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -1884,6 +1884,9 @@ linkBinary' staticLink dflags o_files dep_packages = do
                       ++ pkg_framework_opts
                       ++ debug_opts
                       ++ thread_opts
+                      ++ (if platformOS platform == OSDarwin
+                          then [ "-Wl,-dead_strip_dylibs" ]
+                          else [])
                     ))
 
 exeFileName :: Bool -> DynFlags -> FilePath
diff --git a/compiler/main/SysTools.hs b/compiler/main/SysTools.hs
index 2e52ef9..d987d7d 100644
--- a/compiler/main/SysTools.hs
+++ b/compiler/main/SysTools.hs
@@ -540,6 +540,7 @@ linkDynLib dflags0 o_files dep_packages
                  ++ map Option pkg_lib_path_opts
                  ++ map Option pkg_link_opts
                  ++ map Option pkg_framework_opts
+                 ++ [ Option "-Wl,-dead_strip_dylibs" ]
               )
         _ -> do
             -------------------------------------------------------------------



More information about the ghc-commits mailing list