summaryrefslogtreecommitdiff
path: root/compiler/main
diff options
context:
space:
mode:
authorMoritz Angermann <moritz.angermann@gmail.com>2018-05-30 20:40:11 -0400
committerBen Gamari <ben@smart-cactus.org>2018-05-30 22:05:37 -0400
commitb592bd98ff25730bbe3c13d6f62a427df8c78e28 (patch)
treecda9fa34b3ba645cfe6f1283157b10d5647ae08b /compiler/main
parent21a9fb5ff3714addf28dbe270af5d10640d89ad9 (diff)
downloadhaskell-b592bd98ff25730bbe3c13d6f62a427df8c78e28.tar.gz
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
Diffstat (limited to 'compiler/main')
-rw-r--r--compiler/main/DriverPipeline.hs3
-rw-r--r--compiler/main/SysTools.hs1
2 files changed, 4 insertions, 0 deletions
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 5ea83ce2c7..e4a9fa2150 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 2e52ef97da..d987d7dcd0 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
-------------------------------------------------------------------