Skip to content

Commit 4b6ebcc

Browse files
angermanandreabedini
authored andcommitted
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 ee59583 commit 4b6ebcc

File tree

2 files changed

+44
-33
lines changed

2 files changed

+44
-33
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: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -103,32 +103,42 @@ targetPlatform ghcInfo = platformFromTriple =<< lookup "Target platform" ghcInfo
103103

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

217-
configureLd :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
218-
configureLd v ldProg = do
219-
ldProg' <- configureLd' v ldProg
227+
configureLd :: ConfiguredProgram -> Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
228+
configureLd gccProg v ldProg = do
229+
ldProg' <- configureLd' gccProg v ldProg
220230
return
221231
ldProg'
222232
{ programDefaultArgs = programDefaultArgs ldProg' ++ ldLinkerFlags
223233
}
224234

225235
-- we need to find out if ld supports the -x flag
226-
configureLd' :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
227-
configureLd' verbosity ldProg = do
236+
configureLd' :: ConfiguredProgram -> Verbosity -> ConfiguredProgram -> IO ConfiguredProgram
237+
configureLd' gccProg verbosity ldProg = do
228238
ldx <- withTempFile ".c" $ \testcfile testchnd ->
229239
withTempFile ".o" $ \testofile testohnd -> do
230240
hPutStrLn testchnd "int foo() { return 0; }"
231241
hClose testchnd
232242
hClose testohnd
233243
runProgram
234244
verbosity
235-
ghcProg
236-
[ "-hide-all-packages"
237-
, "-c"
245+
gccProg
246+
[ "-c"
238247
, testcfile
239248
, "-o"
240249
, testofile

0 commit comments

Comments
 (0)