Skip to content

Commit 8b831aa

Browse files
committed
lib:Cabal - do not use GHC to configure LD.
Cabal uses a peculiar c program to check if LD supports and should use -x. To do this, it shells out to GHC to compiler the C file. This however requires that GHC will not bail out, yet cabal does not pass --package-db flags to this GHC invocation, and as such we can run into situations where GHC bails out, especially during GHC bootstrap phases where not all boot packages are available. We however do not need GHC to compiler a c program, and can rely on the C compiler. Fundamentally cabal does not allow modelling program dependencies in the program db, as such we must configure gcc first before using it. We make a small change to lib:Cabal (specifically the GHC module, and it's Internal companion) to allow it to configure gcc first, before trying to configure ld, and thus having gcc in scope while configuring ld. This removes the need for the awkward ghc invocation to compiler the test program.
1 parent 55aba14 commit 8b831aa

File tree

2 files changed

+48
-38
lines changed

2 files changed

+48
-38
lines changed

Cabal/src/Distribution/Simple/GHC.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,10 @@ configure verbosity hcPath hcPkgPath conf0 = do
261261
, compilerProperties = ghcInfoMap
262262
}
263263
compPlatform = Internal.targetPlatform ghcInfo
264-
-- configure gcc and ld
265-
progdb4 = Internal.configureToolchain implInfo ghcProg ghcInfoMap progdb3
264+
-- configure gcc and ld
265+
-- similarly to how we need ghc above, we need to know the c compiler
266+
-- generally named `gcc` in cabal, to configure other programs, e.g. ld.
267+
progdb4 <- Internal.configureToolchain verbosity implInfo ghcProg ghcInfoMap progdb3
266268
return (comp, compPlatform, progdb4)
267269

268270
-- | Given something like /usr/local/bin/ghc-6.6.1(.exe) we try and find

Cabal/src/Distribution/Simple/GHC/Internal.hs

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -100,37 +100,46 @@ targetPlatform ghcInfo = platformFromTriple =<< lookup "Target platform" ghcInfo
100100

101101
-- | Adjust the way we find and configure gcc and ld
102102
configureToolchain
103-
:: GhcImplInfo
103+
:: Verbosity
104+
-> GhcImplInfo
104105
-> ConfiguredProgram
105106
-> Map String String
106107
-> ProgramDb
107-
-> ProgramDb
108-
configureToolchain _implInfo ghcProg ghcInfo =
109-
addKnownProgram
110-
gccProgram
111-
{ programFindLocation = findProg gccProgramName extraGccPath
112-
, programPostConf = configureGcc
113-
}
114-
. addKnownProgram
115-
gppProgram
116-
{ programFindLocation = findProg gppProgramName extraGppPath
117-
, programPostConf = configureGpp
118-
}
119-
. addKnownProgram
120-
ldProgram
121-
{ programFindLocation = findProg ldProgramName extraLdPath
122-
, programPostConf = \v cp ->
123-
-- Call any existing configuration first and then add any new configuration
124-
configureLd v =<< programPostConf ldProgram v cp
125-
}
126-
. addKnownProgram
127-
arProgram
128-
{ programFindLocation = findProg arProgramName extraArPath
129-
}
130-
. addKnownProgram
131-
stripProgram
132-
{ programFindLocation = findProg stripProgramName extraStripPath
133-
}
108+
-> IO ProgramDb
109+
configureToolchain verbosity _implInfo ghcProg ghcInfo db = do
110+
-- this is a bit of a hack. We have a dependency of ld on gcc.
111+
-- ld needs to compiler a c program, to check an ld feature.
112+
-- we _could_ use ghc as a c frontend, but we do not pass all
113+
-- db stack appropriately, and thus we can run into situations
114+
-- where GHC will fail if it's stricter in it's wired-in-unit
115+
-- selction and has the wrong db stack. However we don't need
116+
-- ghc to compile a _test_ c program. So we configure `gcc`
117+
-- first and then use `gcc` (the generic c compiler in cabal
118+
-- terminology) to compile the test program.
119+
let db' = flip addKnownProgram db $
120+
gccProgram
121+
{ programFindLocation = findProg gccProgramName extraGccPath
122+
, programPostConf = configureGcc
123+
}
124+
(gccProg, db'') <- requireProgram verbosity gccProgram db'
125+
return $ flip addKnownPrograms db'' $
126+
[ gppProgram
127+
{ programFindLocation = findProg gppProgramName extraGppPath
128+
, programPostConf = configureGpp
129+
}
130+
, ldProgram
131+
{ programFindLocation = findProg ldProgramName extraLdPath
132+
, programPostConf = \v cp ->
133+
-- Call any existing configuration first and then add any new configuration
134+
configureLd gccProg v =<< programPostConf ldProgram v cp
135+
}
136+
, arProgram
137+
{ programFindLocation = findProg arProgramName extraArPath
138+
}
139+
, stripProgram
140+
{ programFindLocation = findProg stripProgramName extraStripPath
141+
}
142+
]
134143
where
135144
compilerDir, base_dir, mingwBinDir :: FilePath
136145
compilerDir = takeDirectory (programPath ghcProg)
@@ -230,27 +239,26 @@ configureToolchain _implInfo ghcProg ghcInfo =
230239
++ cxxFlags
231240
}
232241

233-
configureLd :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
234-
configureLd v ldProg = do
235-
ldProg' <- configureLd' v ldProg
242+
configureLd :: ConfiguredProgram -> Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
243+
configureLd gccProg v ldProg = do
244+
ldProg' <- configureLd' gccProg v ldProg
236245
return
237246
ldProg'
238247
{ programDefaultArgs = programDefaultArgs ldProg' ++ ldLinkerFlags
239248
}
240249

241250
-- we need to find out if ld supports the -x flag
242-
configureLd' :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
243-
configureLd' verbosity ldProg = do
251+
configureLd' :: ConfiguredProgram -> Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
252+
configureLd' gccProg verbosity ldProg = do
244253
ldx <- withTempFile ".c" $ \testcfile testchnd ->
245254
withTempFile ".o" $ \testofile testohnd -> do
246255
hPutStrLn testchnd "int foo() { return 0; }"
247256
hClose testchnd
248257
hClose testohnd
249258
runProgram
250259
verbosity
251-
ghcProg
252-
[ "-hide-all-packages"
253-
, "-c"
260+
gccProg
261+
[ "-c"
254262
, testcfile
255263
, "-o"
256264
, testofile

0 commit comments

Comments
 (0)