Skip to content

Use linker capability detection to improve linker use (backport #9443) #9716

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions Cabal/src/Distribution/Simple/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,16 @@ import Distribution.PackageDescription.Configuration
import Distribution.PackageDescription.Check hiding (doesFileExist)
import Distribution.Simple.BuildToolDepends
import Distribution.Simple.Program
<<<<<<< HEAD
import Distribution.Simple.Setup as Setup
import Distribution.Simple.BuildTarget
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Program.Db (appendProgramSearchPath)
=======
import Distribution.Simple.Program.Db (lookupProgramByName)
import Distribution.Simple.Setup.Common as Setup
import Distribution.Simple.Setup.Config as Setup
>>>>>>> 53fc3d36f (Use linker capability detection to improve linker use)
import Distribution.Simple.Utils
import Distribution.System
import Distribution.Types.PackageVersionConstraint
Expand Down Expand Up @@ -619,6 +625,7 @@ configure (pkg_descr0, pbi) cfg = do
"--enable-split-sections; ignoring")
return False

<<<<<<< HEAD
-- Decide if we're going to compile with split objects.
split_objs :: Bool <-
if not (fromFlag $ configSplitObjs cfg)
Expand Down Expand Up @@ -679,6 +686,44 @@ configure (pkg_descr0, pbi) cfg = do
++ " GHC 9.4 and later; ignoring..."
return False
v -> return v
=======
-- Basically yes/no/unknown.
let linkerSupportsRelocations :: Maybe Bool
linkerSupportsRelocations =
case lookupProgramByName "ld" programDb'' of
Nothing -> Nothing
Just ld ->
case Map.lookup "Supports relocatable output" $ programProperties ld of
Just "YES" -> Just True
Just "NO" -> Just False
_other -> Nothing
let ghciLibByDefault =
case compilerId comp of
CompilerId GHC _ ->
-- If ghc is non-dynamic, then ghci needs object files,
-- so we build one by default.
--
-- Technically, archive files should be sufficient for ghci,
-- but because of GHC bug #8942, it has never been safe to
-- rely on them. By the time that bug was fixed, ghci had
-- been changed to read shared libraries instead of archive
-- files (see next code block).
not (GHC.isDynamic comp)
CompilerId GHCJS _ ->
not (GHCJS.isDynamic comp)
_ -> False

withGHCiLib_ <-
case fromFlagOrDefault ghciLibByDefault (configGHCiLib cfg) of
-- NOTE: If linkerSupportsRelocations is Nothing this may still fail if the
-- linker does not support -r.
True | not (fromMaybe True linkerSupportsRelocations) -> do
warn verbosity $
"--enable-library-for-ghci is not supported with the current"
++ " linker; ignoring..."
return False
v -> return v
>>>>>>> 53fc3d36f (Use linker capability detection to improve linker use)

let sharedLibsByDefault
| fromFlag (configDynExe cfg) =
Expand Down
23 changes: 23 additions & 0 deletions Cabal/src/Distribution/Simple/GHC/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ configureToolchain :: GhcImplInfo
-> ProgramDb
-> ProgramDb
configureToolchain _implInfo ghcProg ghcInfo =
<<<<<<< HEAD
addKnownProgram gccProgram {
programFindLocation = findProg gccProgramName extraGccPath,
programPostConf = configureGcc
Expand All @@ -109,6 +110,28 @@ configureToolchain _implInfo ghcProg ghcInfo =
. addKnownProgram stripProgram {
programFindLocation = findProg stripProgramName extraStripPath
}
=======
addKnownProgram
gccProgram
{ programFindLocation = findProg gccProgramName extraGccPath
, programPostConf = configureGcc
}
. addKnownProgram
ldProgram
{ programFindLocation = findProg ldProgramName extraLdPath
, programPostConf = \v cp ->
-- Call any existing configuration first and then add any new configuration
configureLd v =<< programPostConf ldProgram v cp
}
. addKnownProgram
arProgram
{ programFindLocation = findProg arProgramName extraArPath
}
. addKnownProgram
stripProgram
{ programFindLocation = findProg stripProgramName extraStripPath
}
>>>>>>> 4336f4c48 (Chain configuration of ldProgram)
where
compilerDir = takeDirectory (programPath ghcProg)
base_dir = takeDirectory compilerDir
Expand Down
42 changes: 42 additions & 0 deletions Cabal/src/Distribution/Simple/Program/Builtin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,49 @@ greencardProgram :: Program
greencardProgram = simpleProgram "greencard"

ldProgram :: Program
<<<<<<< HEAD
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"
-- Standard GNU `ld` uses `--relocatable` while `ld.gold` uses
-- `-relocatable` (single `-`).
v
| "-relocatable" `isInfixOf` ldHelpOutput = "YES"
-- ld64 on macOS has this lovely response for "--help"
--
-- ld64: For information on command line options please use 'man ld'.
--
-- it does however support -r, if you read the manpage
-- (e.g. https://www.manpagez.com/man/1/ld64/)
| "ld64:" `isPrefixOf` ldHelpOutput = "YES"
| otherwise = "NO"

m = Map.insert k v (programProperties ldProg)
return $ ldProg{programProperties = m}
}
>>>>>>> fb14e4e29 (Fix configuation of ldProgram)

tarProgram :: Program
tarProgram = (simpleProgram "tar") {
Expand Down
26 changes: 25 additions & 1 deletion Cabal/src/Distribution/Simple/Program/Db.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module Distribution.Simple.Program.Db (
restoreProgramDb,

-- ** Query and manipulate the program db
<<<<<<< HEAD
addKnownProgram,
addKnownPrograms,
appendProgramSearchPath,
Expand All @@ -49,6 +50,25 @@ module Distribution.Simple.Program.Db (
lookupProgram,
updateProgram,
configuredPrograms,
=======
, addKnownProgram
, addKnownPrograms
, lookupKnownProgram
, knownPrograms
, getProgramSearchPath
, setProgramSearchPath
, modifyProgramSearchPath
, userSpecifyPath
, userSpecifyPaths
, userMaybeSpecifyPath
, userSpecifyArgs
, userSpecifyArgss
, userSpecifiedArgs
, lookupProgram
, lookupProgramByName
, updateProgram
, configuredPrograms
>>>>>>> 53fc3d36f (Use linker capability detection to improve linker use)

-- ** Query and manipulate the program db
configureProgram,
Expand Down Expand Up @@ -309,7 +329,11 @@ userSpecifiedArgs prog =

-- | Try to find a configured program
lookupProgram :: Program -> ProgramDb -> Maybe ConfiguredProgram
lookupProgram prog = Map.lookup (programName prog) . configuredProgs
lookupProgram = lookupProgramByName . programName

-- | Try to find a configured program
lookupProgramByName :: String -> ProgramDb -> Maybe ConfiguredProgram
lookupProgramByName name = Map.lookup name . configuredProgs


-- | Update a configured program in the database.
Expand Down
11 changes: 11 additions & 0 deletions changelog.d/pr-9443
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
synopsis: Use linker capability detection to improve linker use
packages: Cabal
prs: #9443

description: {

- Previously the GHC version number and platform were used as a proxy for whether
the linker can generate relocatable objects.
- Now, the ability of the linker to create relocatable objects is detected.

}