diff --git a/Cabal/src/Distribution/Simple/Program/Builtin.hs b/Cabal/src/Distribution/Simple/Program/Builtin.hs index 909ecc7e4b6..1f3db0740f3 100644 --- a/Cabal/src/Distribution/Simple/Program/Builtin.hs +++ b/Cabal/src/Distribution/Simple/Program/Builtin.hs @@ -347,7 +347,33 @@ greencardProgram :: Program greencardProgram = simpleProgram "greencard" ldProgram :: Program -ldProgram = simpleProgram "ld" +ldProgram = + (simpleProgram "ld") + { programPostConf = \verbosity ldProg -> do + -- The `lld` linker cannot create merge (relocatable) objects so we + -- want to detect this. + -- If the linker does support relocatable objects, we want to use that + -- to create partially pre-linked objects for GHCi, so we get much + -- faster loading as we do not have to do the separate loading and + -- in-memory linking the static linker in GHC does, but can offload + -- parts of this process to a pre-linking step. + -- However this requires the linker to support this features. Not all + -- linkers do, and notably as of this writing `lld` which is a popular + -- choice for windows linking does not support this feature. However + -- if using binutils ld or another linker that supports --relocatable, + -- we should still be good to generate pre-linked objects. + ldHelpOutput <- + getProgramInvocationOutput + verbosity + (programInvocation ldProg ["--help"]) + -- In case the linker does not support '--help'. Eg the LLVM linker, + -- `lld` only accepts `-help`. + `catchIO` (\_ -> return "") + let k = "Supports relocatable output" + v = if "--relocatable" `isInfixOf` ldHelpOutput then "YES" else "NO" + m = Map.insert k v (programProperties ldProg) + return $ ldProg{programProperties = m} + } tarProgram :: Program tarProgram =