Skip to content

Commit 7ea381f

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 b7ed37b commit 7ea381f

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
@@ -263,8 +263,10 @@ configure verbosity hcPath hcPkgPath conf0 = do
263263
, compilerProperties = ghcInfoMap
264264
}
265265
compPlatform = Internal.targetPlatform ghcInfo
266-
-- configure gcc and ld
267-
progdb4 = Internal.configureToolchain implInfo ghcProg ghcInfoMap progdb3
266+
-- configure gcc and ld
267+
-- similarly to how we need ghc above, we need to know the c compiler
268+
-- generally named `gcc` in cabal, to configure other programs, e.g. ld.
269+
progdb4 <- Internal.configureToolchain verbosity implInfo ghcProg ghcInfoMap progdb3
268270
return (comp, compPlatform, progdb4)
269271

270272
-- | 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)