Commit 02f8eef1 authored by Duncan Coutts's avatar Duncan Coutts
Browse files

Separate compiling and linking phases for bulding exes with ghc

And move compiling of C files after the compile of Haskell modules,
just like we do for libraries. Reversing the order is important because
C files can depend on headers generated for Haskell FFI exports.

This is based on a patch by Edward Z. Yang <ezyang@mit.edu>
parent 7b2e3630
......@@ -824,46 +824,42 @@ buildExe verbosity _pkg_descr lbi
-- FIX: what about exeName.hi-boot?
-- build executables
unless (null (cSources exeBi)) $ do
info verbosity "Building C Sources."
sequence_
[ do let opts = (componentCcGhcOptions verbosity lbi exeBi clbi
exeDir filename) `mappend` mempty {
ghcOptDynamic = toFlag (withDynExe lbi),
ghcOptProfilingMode = toFlag (withProfExe lbi)
}
odir = fromFlag (ghcOptObjDir opts)
createDirectoryIfMissingVerbose verbosity True odir
runGhcProg opts
| filename <- cSources exeBi]
srcMainFile <- findFile (exeDir : hsSourceDirs exeBi) modPath
let cObjs = map (`replaceExtension` objExtension) (cSources exeBi)
let vanillaOpts = (componentGhcOptions verbosity lbi exeBi clbi exeDir)
baseOpts = (componentGhcOptions verbosity lbi exeBi clbi exeDir)
`mappend` mempty {
ghcOptMode = toFlag GhcModeMake,
ghcOptInputFiles = [exeDir </> x | x <- cObjs]
++ [srcMainFile],
ghcOptLinkOptions = PD.ldOptions exeBi,
ghcOptLinkLibs = extraLibs exeBi,
ghcOptLinkLibPath = extraLibDirs exeBi,
ghcOptLinkFrameworks = PD.frameworks exeBi
ghcOptInputFiles = [srcMainFile]
}
exeOpts | withProfExe lbi = vanillaOpts `mappend` mempty {
staticOpts = baseOpts `mappend` mempty {
ghcOptDynamic = toFlag False
}
profOpts = baseOpts `mappend` mempty {
ghcOptProfilingMode = toFlag True,
ghcOptHiSuffix = toFlag "p_hi",
ghcOptObjSuffix = toFlag "p_o",
ghcOptExtra = ghcProfOptions exeBi
}
| withDynExe lbi = vanillaOpts `mappend` mempty {
dynOpts = baseOpts `mappend` mempty {
ghcOptDynamic = toFlag True,
ghcOptHiSuffix = toFlag "dyn_hi",
ghcOptObjSuffix = toFlag "dyn_o",
ghcOptExtra = ghcSharedOptions exeBi
}
| otherwise = vanillaOpts
compileOpts | withProfExe lbi = profOpts
| withDynExe lbi = dynOpts
| otherwise = staticOpts
linkOpts = compileOpts `mappend` mempty {
ghcOptLinkOptions = PD.ldOptions exeBi,
ghcOptLinkLibs = extraLibs exeBi,
ghcOptLinkLibPath = extraLibDirs exeBi,
ghcOptLinkFrameworks = PD.frameworks exeBi,
ghcOptInputFiles = [exeDir </> x | x <- cObjs]
}
-- For building exe's for profiling that use TH we actually
-- have to build twice, once without profiling and the again
......@@ -872,9 +868,27 @@ buildExe verbosity _pkg_descr lbi
-- be loaded up and run by the compiler.
when ((withProfExe lbi || withDynExe lbi) &&
EnableExtension TemplateHaskell `elem` allExtensions exeBi) $
runGhcProg vanillaOpts { ghcOptNoLink = toFlag True }
runGhcProg compileOpts { ghcOptNoLink = toFlag True }
--TODO: do we also need to play the static vs dynamic games here?
runGhcProg compileOpts { ghcOptNoLink = toFlag True }
runGhcProg exeOpts { ghcOptOutputFile = toFlag (targetDir </> exeNameReal) }
-- build any C sources
unless (null (cSources exeBi)) $ do
info verbosity "Building C Sources..."
sequence_
[ do let opts = (componentCcGhcOptions verbosity lbi exeBi clbi
exeDir filename) `mappend` mempty {
ghcOptDynamic = toFlag (withDynExe lbi),
ghcOptProfilingMode = toFlag (withProfExe lbi)
}
odir = fromFlag (ghcOptObjDir opts)
createDirectoryIfMissingVerbose verbosity True odir
runGhcProg opts
| filename <- cSources exeBi]
-- link:
runGhcProg linkOpts { ghcOptOutputFile = toFlag (targetDir </> exeNameReal) }
-- | Filter the "-threaded" flag when profiling as it does not
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment