Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Convert ghc option construction to use an options record

Using a structured representation of the ghc options rather
than [String] makes it easier to share and reuse the code
for building sets of ghc options, which makes it easier to
add code for calling ghci.

This is based on Sam Anklesaria's GSoC work on "cabal repl"
  • Loading branch information...
commit 5f50fb1e156d911584b588ec5f1e2a704f3d3a6d 1 parent 52a69ff
@dcoutts dcoutts authored
View
1  Cabal/Cabal.cabal
@@ -98,6 +98,7 @@ Library
Distribution.Simple.Program.Ar,
Distribution.Simple.Program.Builtin,
Distribution.Simple.Program.Db,
+ Distribution.Simple.Program.GHC,
Distribution.Simple.Program.HcPkg,
Distribution.Simple.Program.Hpc,
Distribution.Simple.Program.Ld,
View
366 Cabal/Distribution/Simple/GHC.hs
@@ -66,9 +66,7 @@ module Distribution.Simple.GHC (
installLib, installExe,
libAbiHash,
registerPackage,
- ghcOptions,
- ghcVerbosityOptions,
- ghcPackageDbOptions,
+ componentGhcOptions,
ghcLibDir,
) where
@@ -94,8 +92,9 @@ import Distribution.Package
import qualified Distribution.ModuleName as ModuleName
import Distribution.Simple.Program
( Program(..), ConfiguredProgram(..), ProgramConfiguration, ProgArg
- , ProgramLocation(..), rawSystemProgram, rawSystemProgramConf
+ , ProgramLocation(..), rawSystemProgram
, rawSystemProgramStdout, rawSystemProgramStdoutConf
+ , getProgramInvocationOutput
, requireProgramVersion, requireProgram, getProgramOutput
, userMaybeSpecifyPath, programPath, lookupProgram, addKnownProgram
, ghcProgram, ghcPkgProgram, hsc2hsProgram
@@ -104,10 +103,12 @@ import Distribution.Simple.Program
import qualified Distribution.Simple.Program.HcPkg as HcPkg
import qualified Distribution.Simple.Program.Ar as Ar
import qualified Distribution.Simple.Program.Ld as Ld
+import Distribution.Simple.Program.GHC
+import Distribution.Simple.Setup (toFlag, fromFlag)
import Distribution.Simple.Compiler
( CompilerFlavor(..), CompilerId(..), Compiler(..), compilerVersion
, OptimisationLevel(..), PackageDB(..), PackageDBStack
- , Flag, languageToFlags, extensionsToFlags )
+ , Flag )
import Distribution.Version
( Version(..), anyVersion, orLaterVersion )
import Distribution.System
@@ -120,7 +121,7 @@ import Language.Haskell.Extension (Language(..), Extension(..), KnownExtension(.
import Control.Monad ( unless, when, liftM )
import Data.Char ( isSpace )
import Data.List
-import Data.Maybe ( catMaybes )
+import Data.Maybe ( catMaybes, fromMaybe )
import Data.Monoid ( Monoid(..) )
import System.Directory
( removeFile, getDirectoryContents, doesFileExist
@@ -588,7 +589,6 @@ buildLib :: Verbosity -> PackageDescription -> LocalBuildInfo
buildLib verbosity pkg_descr lbi lib clbi = do
let pref = buildDir lbi
pkgid = packageId pkg_descr
- runGhcProg = rawSystemProgramConf verbosity ghcProgram (withPrograms lbi)
ifVanillaLib forceVanilla = when (forceVanilla || withVanillaLib lbi)
ifProfLib = when (withProfLib lbi)
ifSharedLib = when (withSharedLib lbi)
@@ -596,6 +596,9 @@ buildLib verbosity pkg_descr lbi lib clbi = do
comp = compiler lbi
ghcVersion = compilerVersion comp
+ (ghcProg, _) <- requireProgram verbosity ghcProgram (withPrograms lbi)
+ let runGhcProg = runGHC verbosity ghcProg
+
libBi <- hackThreadedFlag verbosity
comp (withProfLib lbi) (libBuildInfo lib)
@@ -605,39 +608,51 @@ buildLib verbosity pkg_descr lbi lib clbi = do
createDirectoryIfMissingVerbose verbosity True libTargetDir
-- TODO: do we need to put hs-boot files into place for mutually recurive modules?
- let ghcArgs =
- "--make"
- : ["-package-name", display pkgid ]
- ++ constructGHCCmdLine lbi libBi clbi libTargetDir verbosity
- ++ map display (libModules lib)
- ghcArgsProf = ghcArgs
- ++ ["-prof",
- "-hisuf", "p_hi",
- "-osuf", "p_o"
- ]
- ++ ghcProfOptions libBi
- ghcArgsShared = ghcArgs
- ++ ["-dynamic",
- "-hisuf", "dyn_hi",
- "-osuf", "dyn_o", "-fPIC"
- ]
- ++ ghcSharedOptions libBi
+ let baseOpts = componentGhcOptions verbosity lbi libBi clbi libTargetDir
+ vanillaOpts = baseOpts {
+ ghcOptMode = toFlag GhcModeMake,
+ ghcOptPackageName = toFlag pkgid,
+ ghcOptInputModules = libModules lib
+ }
+
+ profOpts = vanillaOpts {
+ ghcOptProfilingMode = toFlag True,
+ ghcOptHiSuffix = toFlag "p_hi",
+ ghcOptObjSuffix = toFlag "p_o",
+ ghcOptExtra = ghcProfOptions libBi
+ }
+
+ sharedOpts = vanillaOpts {
+ ghcOptDynamic = toFlag True,
+ ghcOptFPic = toFlag True,
+ ghcOptHiSuffix = toFlag "dyn_hi",
+ ghcOptObjSuffix = toFlag "dyn_o",
+ ghcOptExtra = ghcSharedOptions libBi
+ }
+
unless (null (libModules lib)) $
- do ifVanillaLib forceVanillaLib (runGhcProg ghcArgs)
- ifProfLib (runGhcProg ghcArgsProf)
- ifSharedLib (runGhcProg ghcArgsShared)
+ do ifVanillaLib forceVanillaLib (runGhcProg vanillaOpts)
+ ifProfLib (runGhcProg profOpts)
+ ifSharedLib (runGhcProg sharedOpts)
-- build any C sources
unless (null (cSources libBi)) $ do
info verbosity "Building C Sources..."
- sequence_ [do let (odir,args) = constructCcCmdLine lbi libBi clbi pref
- filename verbosity
- False
- (withProfLib lbi)
- createDirectoryIfMissingVerbose verbosity True odir
- runGhcProg args
- ifSharedLib (runGhcProg (args ++ ["-fPIC", "-osuf dyn_o"]))
- | filename <- cSources libBi]
+ sequence_
+ [ do let vanillaCcOpts = (componentCcGhcOptions verbosity lbi
+ libBi clbi pref filename) {
+ ghcOptProfilingMode = toFlag (withProfLib lbi)
+ }
+ sharedCcOpts = vanillaOpts {
+ ghcOptFPic = toFlag True,
+ ghcOptDynamic = toFlag True,
+ ghcOptObjSuffix = toFlag "dyn_o"
+ }
+ odir = fromFlag (ghcOptObjDir vanillaCcOpts)
+ createDirectoryIfMissingVerbose verbosity True odir
+ runGhcProg vanillaCcOpts
+ ifSharedLib (runGhcProg sharedCcOpts)
+ | filename <- cSources libBi]
-- link:
info verbosity "Linking..."
@@ -708,20 +723,23 @@ buildLib verbosity pkg_descr lbi lib clbi = do
-- with the dependencies spelled out as -package arguments
-- and ghc invokes the linker with the proper library paths
ghcSharedLinkArgs =
- [ "-no-auto-link-packages",
- "-shared",
- "-dynamic",
- "-o", sharedLibFilePath ]
- -- For dynamic libs, Mac OS/X needs to know the install location
- -- at build time.
- ++ (if buildOS == OSX
- then ["-dylib-install-name", sharedLibInstallPath]
- else [])
- ++ dynamicObjectFiles
- ++ ["-package-name", display pkgid ]
- ++ ghcPackageFlags lbi clbi
- ++ ["-l"++extraLib | extraLib <- extraLibs libBi]
- ++ ["-L"++extraLibDir | extraLibDir <- extraLibDirs libBi]
+ mempty {
+ ghcOptShared = toFlag True,
+ ghcOptDynamic = toFlag True,
+ ghcOptInputFiles = dynamicObjectFiles,
+ ghcOptOutputFile = toFlag sharedLibFilePath,
+ -- For dynamic libs, Mac OS/X needs to know the install location
+ -- at build time.
+ ghcOptDylibName = if buildOS == OSX
+ then toFlag sharedLibInstallPath
+ else mempty,
+ ghcOptPackageName = toFlag pkgid,
+ ghcOptNoAutoLinkPackages = toFlag True,
+ ghcOptPackageDBs = withPackageDB lbi,
+ ghcOptPackages = componentPackageDeps clbi,
+ ghcOptLinkLibs = extraLibs libBi,
+ ghcOptLinkLibPath = extraLibDirs libBi
+ }
ifVanillaLib False $ do
(arProg, _) <- requireProgram verbosity arProgram (withPrograms lbi)
@@ -749,7 +767,9 @@ buildExe :: Verbosity -> PackageDescription -> LocalBuildInfo
buildExe verbosity _pkg_descr lbi
exe@Executable { exeName = exeName', modulePath = modPath } clbi = do
let pref = buildDir lbi
- runGhcProg = rawSystemProgramConf verbosity ghcProgram (withPrograms lbi)
+
+ (ghcProg, _) <- requireProgram verbosity ghcProgram (withPrograms lbi)
+ let runGhcProg = runGHC verbosity ghcProg
exeBi <- hackThreadedFlag verbosity
(compiler lbi) (withProfExe lbi) (buildInfo exe)
@@ -768,47 +788,56 @@ buildExe verbosity _pkg_descr lbi
-- build executables
unless (null (cSources exeBi)) $ do
info verbosity "Building C Sources."
- sequence_ [do let (odir,args) = constructCcCmdLine lbi exeBi clbi
- exeDir filename verbosity
- (withDynExe lbi) (withProfExe lbi)
- createDirectoryIfMissingVerbose verbosity True odir
- runGhcProg args
- | filename <- cSources exeBi]
+ sequence_
+ [ do let opts = (componentCcGhcOptions verbosity lbi exeBi clbi
+ exeDir filename) {
+ 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 binArgs linkExe dynExe profExe =
- "--make"
- : (if linkExe
- then ["-o", targetDir </> exeNameReal]
- else ["-c"])
- ++ constructGHCCmdLine lbi exeBi clbi exeDir verbosity
- ++ [exeDir </> x | x <- cObjs]
- ++ [srcMainFile]
- ++ ["-optl" ++ opt | opt <- PD.ldOptions exeBi]
- ++ ["-l"++lib | lib <- extraLibs exeBi]
- ++ ["-L"++libDir | libDir <- extraLibDirs exeBi]
- ++ concat [["-framework", f] | f <- PD.frameworks exeBi]
- ++ if dynExe
- then ["-dynamic"]
- else []
- ++ if profExe
- then ["-prof",
- "-hisuf", "p_hi",
- "-osuf", "p_o"
- ] ++ ghcProfOptions exeBi
- else []
-
+ let vanillaOpts = (componentGhcOptions verbosity lbi exeBi clbi exeDir) {
+ ghcOptMode = toFlag GhcModeMake,
+ ghcOptInputFiles = [exeDir </> x | x <- cObjs]
+ ++ [srcMainFile],
+ ghcOptLinkOptions = PD.ldOptions exeBi,
+ ghcOptLinkLibs = extraLibs exeBi,
+ ghcOptLinkLibPath = extraLibDirs exeBi,
+ ghcOptLinkFrameworks = PD.frameworks exeBi
+ }
+
+ dynamicOpts = vanillaOpts {
+ ghcOptDynamic = toFlag True,
+ ghcOptExtra = ghcSharedOptions exeBi
+ }
+
+ exeOpts | withDynExe lbi = dynamicOpts
+ | otherwise = vanillaOpts
+
+ exeProfOpts = exeOpts {
+ ghcOptProfilingMode = toFlag True,
+ ghcOptHiSuffix = toFlag "p_hi",
+ ghcOptObjSuffix = toFlag "p_o",
+ ghcOptExtra = ghcProfOptions exeBi,
+ ghcOptNoLink = toFlag True
+ }
-- For building exe's for profiling that use TH we actually
-- have to build twice, once without profiling and the again
-- with profiling. This is because the code that TH needs to
-- run at compile time needs to be the vanilla ABI so it can
-- be loaded up and run by the compiler.
- when (withProfExe lbi && EnableExtension TemplateHaskell `elem` allExtensions exeBi)
- (runGhcProg (binArgs False (withDynExe lbi) False))
+ when (withProfExe lbi &&
+ EnableExtension TemplateHaskell `elem` allExtensions exeBi) $
+ runGhcProg exeProfOpts { ghcOptNoLink = toFlag True }
+
+ runGhcProg exeOpts { ghcOptOutputFile = toFlag (targetDir </> exeNameReal) }
- runGhcProg (binArgs True (withDynExe lbi) (withProfExe lbi))
-- | Filter the "-threaded" flag when profiling as it does not
-- work with ghc-6.8 and older.
@@ -858,116 +887,75 @@ libAbiHash verbosity pkg_descr lbi lib clbi = do
(compiler lbi) (withProfLib lbi) (libBuildInfo lib)
let
ghcArgs =
- "--abi-hash"
- : ["-package-name", display (packageId pkg_descr) ]
- ++ constructGHCCmdLine lbi libBi clbi (buildDir lbi) verbosity
- ++ map display (exposedModules lib)
+ (componentGhcOptions verbosity lbi libBi clbi (buildDir lbi)) {
+ ghcOptMode = toFlag GhcModeAbiHash,
+ ghcOptPackageName = toFlag (packageId pkg_descr),
+ ghcOptInputModules = exposedModules lib
+ }
--
- rawSystemProgramStdoutConf verbosity ghcProgram (withPrograms lbi) ghcArgs
-
-
-constructGHCCmdLine
- :: LocalBuildInfo
- -> BuildInfo
- -> ComponentLocalBuildInfo
- -> FilePath
- -> Verbosity
- -> [String]
-constructGHCCmdLine lbi bi clbi odir verbosity =
- ghcVerbosityOptions verbosity
- -- Unsupported extensions have already been checked by configure
- ++ ghcOptions lbi bi clbi odir
-
-ghcVerbosityOptions :: Verbosity -> [String]
-ghcVerbosityOptions verbosity
- | verbosity >= deafening = ["-v"]
- | verbosity >= normal = []
- | otherwise = ["-w", "-v0"]
-
-ghcOptions :: LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo
- -> FilePath -> [String]
-ghcOptions lbi bi clbi odir
- = ["-hide-all-packages"]
- ++ ["-fbuilding-cabal-package" | ghcVer >= Version [6,11] [] ]
- ++ ghcPackageDbOptions (withPackageDB lbi)
- ++ ["-split-objs" | splitObjs lbi ]
- ++ ["-i"]
- ++ ["-i" ++ odir]
- ++ ["-i" ++ l | l <- nub (hsSourceDirs bi)]
- ++ ["-i" ++ autogenModulesDir lbi]
- ++ ["-I" ++ autogenModulesDir lbi]
- ++ ["-I" ++ odir]
- ++ ["-I" ++ dir | dir <- PD.includeDirs bi]
- ++ ["-optP" ++ opt | opt <- cppOptions bi]
- ++ [ "-optP-include", "-optP"++ (autogenModulesDir lbi </> cppHeaderName) ]
- ++ [ "-#include \"" ++ inc ++ "\"" | ghcVer < Version [6,11] []
- , inc <- PD.includes bi ]
- ++ [ "-odir", odir, "-hidir", odir ]
- ++ concat [ ["-stubdir", odir] | ghcVer >= Version [6,8] [] ]
- ++ ghcPackageFlags lbi clbi
- ++ (case withOptimization lbi of
- NoOptimisation -> []
- NormalOptimisation -> ["-O"]
- MaximumOptimisation -> ["-O2"])
- ++ hcOptions GHC bi
- ++ languageToFlags (compiler lbi) (defaultLanguage bi)
- ++ extensionsToFlags (compiler lbi) (usedExtensions bi)
- where
- ghcVer = compilerVersion (compiler lbi)
-
-ghcPackageFlags :: LocalBuildInfo -> ComponentLocalBuildInfo -> [String]
-ghcPackageFlags lbi clbi
- | ghcVer >= Version [6,11] []
- = concat [ ["-package-id", display ipkgid]
- | (ipkgid, _) <- componentPackageDeps clbi ]
-
- | otherwise = concat [ ["-package", display pkgid]
- | (_, pkgid) <- componentPackageDeps clbi ]
- where
- ghcVer = compilerVersion (compiler lbi)
-
-ghcPackageDbOptions :: PackageDBStack -> [String]
-ghcPackageDbOptions dbstack = case dbstack of
- (GlobalPackageDB:UserPackageDB:dbs) -> concatMap specific dbs
- (GlobalPackageDB:dbs) -> "-no-user-package-conf"
- : concatMap specific dbs
- _ -> ierror
+ (ghcProg, _) <- requireProgram verbosity ghcProgram (withPrograms lbi)
+ getProgramInvocationOutput verbosity (ghcInvocation ghcProg ghcArgs)
+
+
+componentGhcOptions :: Verbosity -> LocalBuildInfo
+ -> BuildInfo -> ComponentLocalBuildInfo -> FilePath
+ -> GhcOptions
+componentGhcOptions verbosity lbi bi clbi odir =
+ mempty {
+ ghcOptVerbosity = toFlag verbosity,
+ ghcOptHideAllPackages = toFlag True,
+ ghcOptCabal = toFlag True,
+ ghcOptPackageDBs = withPackageDB lbi,
+ ghcOptPackages = componentPackageDeps clbi,
+ ghcOptSplitObjs = toFlag (splitObjs lbi),
+ ghcOptSourcePathClear = toFlag True,
+ ghcOptSourcePath = [odir] ++ nub (hsSourceDirs bi)
+ ++ [autogenModulesDir lbi],
+ ghcOptCppIncludePath = [autogenModulesDir lbi, odir]
+ ++ PD.includeDirs bi,
+ ghcOptCppOptions = cppOptions bi,
+ ghcOptCppIncludes = [autogenModulesDir lbi </> cppHeaderName],
+ ghcOptFfiIncludes = PD.includes bi,
+ ghcOptObjDir = toFlag odir,
+ ghcOptHiDir = toFlag odir,
+ ghcOptStubDir = toFlag odir,
+ ghcOptOptimisation = toGhcOptimisation (withOptimization lbi),
+ ghcOptExtra = hcOptions GHC bi,
+ ghcOptLanguage = toFlag (fromMaybe Haskell98 (defaultLanguage bi)),
+ -- Unsupported extensions have already been checked by configure
+ ghcOptExtensions = usedExtensions bi,
+ ghcOptExtensionMap = compilerExtensions (compiler lbi)
+ }
+ where
+ toGhcOptimisation NoOptimisation = mempty --TODO perhaps override?
+ toGhcOptimisation NormalOptimisation = toFlag GhcNormalOptimisation
+ toGhcOptimisation MaximumOptimisation = toFlag GhcMaximumOptimisation
+
+
+componentCcGhcOptions :: Verbosity -> LocalBuildInfo
+ -> BuildInfo -> ComponentLocalBuildInfo
+ -> FilePath -> FilePath
+ -> GhcOptions
+componentCcGhcOptions verbosity lbi bi clbi pref filename =
+ mempty {
+ ghcOptVerbosity = toFlag verbosity,
+ ghcOptMode = toFlag GhcModeCompile,
+ ghcOptInputFiles = [filename],
+
+ ghcOptCppIncludePath = odir : PD.includeDirs bi,
+ ghcOptPackageDBs = withPackageDB lbi,
+ ghcOptPackages = componentPackageDeps clbi,
+ ghcOptCcOptions = PD.ccOptions bi
+ ++ case withOptimization lbi of
+ NoOptimisation -> []
+ _ -> ["-O2"],
+ ghcOptObjDir = toFlag odir
+ }
where
- specific (SpecificPackageDB db) = [ "-package-conf", db ]
- specific _ = ierror
- ierror = error ("internal error: unexpected package db stack: " ++ show dbstack)
-
-constructCcCmdLine :: LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo
- -> FilePath -> FilePath -> Verbosity -> Bool -> Bool
- ->(FilePath,[String])
-constructCcCmdLine lbi bi clbi pref filename verbosity dynamic profiling
- = let odir | compilerVersion (compiler lbi) >= Version [6,4,1] [] = pref
- | otherwise = pref </> takeDirectory filename
- -- ghc 6.4.1 fixed a bug in -odir handling
- -- for C compilations.
- in
- (odir,
- ghcCcOptions lbi bi clbi odir
- ++ (if verbosity >= deafening then ["-v"] else [])
- ++ ["-c",filename]
- -- Note: When building with profiling enabled, we pass the -prof
- -- option to ghc here when compiling C code, so that the PROFILING
- -- macro gets defined. The macro is used in ghc's Rts.h in the
- -- definitions of closure layouts (Closures.h).
- ++ ["-dynamic" | dynamic]
- ++ ["-prof" | profiling])
-
-ghcCcOptions :: LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo
- -> FilePath -> [String]
-ghcCcOptions lbi bi clbi odir
- = ["-I" ++ dir | dir <- odir : PD.includeDirs bi]
- ++ ghcPackageDbOptions (withPackageDB lbi)
- ++ ghcPackageFlags lbi clbi
- ++ ["-optc" ++ opt | opt <- PD.ccOptions bi]
- ++ (case withOptimization lbi of
- NoOptimisation -> []
- _ -> ["-optc-O2"])
- ++ ["-odir", odir]
+ odir | compilerVersion (compiler lbi) >= Version [6,4,1] [] = pref
+ | otherwise = pref </> takeDirectory filename
+ -- ghc 6.4.0 had a bug in -odir handling for C compilations.
+
mkGHCiLibName :: PackageIdentifier -> String
mkGHCiLibName lib = "HS" ++ display lib <.> "o"
View
92 Cabal/Distribution/Simple/Haddock.hs
@@ -59,7 +59,8 @@ import Distribution.PackageDescription as PD
, Library(..), hasLibs, Executable(..) )
import Distribution.Simple.Compiler
( Compiler(..), compilerVersion )
-import Distribution.Simple.GHC ( ghcLibDir )
+import Distribution.Simple.GHC ( componentGhcOptions, ghcLibDir )
+import Distribution.Simple.Program.GHC ( GhcOptions(..), renderGhcOptions )
import Distribution.Simple.Program
( ConfiguredProgram(..), requireProgramVersion
, rawSystemProgram, rawSystemProgramStdout
@@ -68,7 +69,7 @@ import Distribution.Simple.PreProcess (ppCpp', ppUnlit
, PPSuffixHandler, runSimplePreProcessor
, preprocessComponent)
import Distribution.Simple.Setup
- ( defaultHscolourFlags, Flag(..), flagToMaybe, fromFlag
+ ( defaultHscolourFlags, Flag(..), toFlag, flagToMaybe, flagToList, fromFlag
, HaddockFlags(..), HscolourFlags(..) )
import Distribution.Simple.Build (initialBuildSteps)
import Distribution.Simple.InstallDirs (InstallDirs(..), PathTemplateEnv, PathTemplate,
@@ -93,7 +94,6 @@ import Distribution.Simple.Utils
, createDirectoryIfMissingVerbose, withTempFile, copyFileVerbose
, withTempDirectory
, findFileWithExtension, findFile )
-import Distribution.Simple.GHC (ghcOptions)
import Distribution.Text
( display, simpleParse )
@@ -129,7 +129,7 @@ data HaddockArgs = HaddockArgs {
argOutputDir :: Directory, -- ^ where to generate the documentation.
argTitle :: Flag String, -- ^ page's title, required.
argPrologue :: Flag String, -- ^ prologue text, required.
- argGhcFlags :: [String], -- ^ additional flags to pass to ghc for haddock-2
+ argGhcOptions :: Flag (GhcOptions, Version), -- ^ additional flags to pass to ghc for haddock-2
argGhcLibDir :: Flag FilePath, -- ^ to find the correct ghc, required by haddock-2.
argTargets :: [FilePath] -- ^ modules to process.
}
@@ -305,45 +305,51 @@ fromLibrary :: Verbosity
-> LocalBuildInfo -> Library -> ComponentLocalBuildInfo
-> Maybe PathTemplate -- ^ template for html location
-> IO HaddockArgs
-fromLibrary verbosity tmp lbi lib clbi htmlTemplate =
- do inFiles <- map snd `fmap` getLibSourceFiles lbi lib
- ifaceArgs <- getInterfaces verbosity lbi clbi htmlTemplate
- return $ ifaceArgs {
- argHideModules = (mempty,otherModules $ bi),
- argGhcFlags = ghcOptions lbi bi clbi (buildDir lbi)
- -- Noooooooooo!!!!!111
- -- haddock stomps on our precious .hi
- -- and .o files. Workaround by telling
- -- haddock to write them elsewhere.
- ++ [ "-odir", tmp, "-hidir", tmp
- , "-stubdir", tmp ],
- argTargets = inFiles
- }
- where
- bi = libBuildInfo lib
+fromLibrary verbosity tmp lbi lib clbi htmlTemplate = do
+ inFiles <- map snd `fmap` getLibSourceFiles lbi lib
+ ifaceArgs <- getInterfaces verbosity lbi clbi htmlTemplate
+ return ifaceArgs {
+ argHideModules = (mempty,otherModules $ bi),
+ argGhcOptions = toFlag ((componentGhcOptions normal lbi bi clbi (buildDir lbi)) {
+ -- Noooooooooo!!!!!111
+ -- haddock stomps on our precious .hi
+ -- and .o files. Workaround by telling
+ -- haddock to write them elsewhere.
+ ghcOptObjDir = toFlag tmp,
+ ghcOptHiDir = toFlag tmp,
+ ghcOptStubDir = toFlag tmp
+ },ghcVersion),
+ argTargets = inFiles
+ }
+ where
+ bi = libBuildInfo lib
+ ghcVersion = compilerVersion (compiler lbi)
fromExecutable :: Verbosity
-> FilePath
-> LocalBuildInfo -> Executable -> ComponentLocalBuildInfo
-> Maybe PathTemplate -- ^ template for html location
-> IO HaddockArgs
-fromExecutable verbosity tmp lbi exe clbi htmlTemplate =
- do inFiles <- map snd `fmap` getExeSourceFiles lbi exe
- ifaceArgs <- getInterfaces verbosity lbi clbi htmlTemplate
- return $ ifaceArgs {
- argGhcFlags = ghcOptions lbi bi clbi (buildDir lbi)
- -- Noooooooooo!!!!!111
- -- haddock stomps on our precious .hi
- -- and .o files. Workaround by telling
- -- haddock to write them elsewhere.
- ++ [ "-odir", tmp, "-hidir", tmp
- , "-stubdir", tmp ],
- argOutputDir = Dir (exeName exe),
- argTitle = Flag (exeName exe),
- argTargets = inFiles
- }
- where
- bi = buildInfo exe
+fromExecutable verbosity tmp lbi exe clbi htmlTemplate = do
+ inFiles <- map snd `fmap` getExeSourceFiles lbi exe
+ ifaceArgs <- getInterfaces verbosity lbi clbi htmlTemplate
+ return ifaceArgs {
+ argGhcOptions = toFlag ((componentGhcOptions normal lbi bi clbi (buildDir lbi)) {
+ -- Noooooooooo!!!!!111
+ -- haddock stomps on our precious .hi
+ -- and .o files. Workaround by telling
+ -- haddock to write them elsewhere.
+ ghcOptObjDir = toFlag tmp,
+ ghcOptHiDir = toFlag tmp,
+ ghcOptStubDir = toFlag tmp
+ }, ghcVersion),
+ argOutputDir = Dir (exeName exe),
+ argTitle = Flag (exeName exe),
+ argTargets = inFiles
+ }
+ where
+ bi = buildInfo exe
+ ghcVersion = compilerVersion (compiler lbi)
getInterfaces :: Verbosity
-> LocalBuildInfo
@@ -384,7 +390,7 @@ runHaddock verbosity confHaddock args = do
renderArgs :: Verbosity
-> Version
-> HaddockArgs
- -> (([[Char]], FilePath) -> IO a)
+ -> (([String], FilePath) -> IO a)
-> IO a
renderArgs verbosity version args k = do
createDirectoryIfMissingVerbose verbosity True outputDir
@@ -409,7 +415,7 @@ renderArgs verbosity version args k = do
pkgid = arg argPackageName
arg f = fromFlag $ f args
-renderPureArgs :: Version -> HaddockArgs -> [[Char]]
+renderPureArgs :: Version -> HaddockArgs -> [String]
renderPureArgs version args = concat
[
(:[]) . (\f -> "--dump-interface="++ unDir (argOutputDir args) </> f)
@@ -429,7 +435,9 @@ renderPureArgs version args = concat
(:[]).("--odir="++) . unDir . argOutputDir $ args,
(:[]).("--title="++) . (bool (++" (internal documentation)") id (getAny $ argIgnoreExports args))
. fromFlag . argTitle $ args,
- bool id (const []) isVersion2 . map ("--optghc=" ++) . argGhcFlags $ args,
+ [ "--optghc=" ++ opt | isVersion2
+ , (opts, ghcVersion) <- flagToList (argGhcOptions args)
+ , opt <- renderGhcOptions ghcVersion opts ],
maybe [] (\l -> ["-B"++l]) $ guard isVersion2 >> flagToMaybe (argGhcLibDir args), -- error if isVersion2 and Nothing?
argTargets $ args
]
@@ -616,7 +624,7 @@ instance Monoid HaddockArgs where
argOutputDir = mempty,
argTitle = mempty,
argPrologue = mempty,
- argGhcFlags = mempty,
+ argGhcOptions = mempty,
argGhcLibDir = mempty,
argTargets = mempty
}
@@ -634,7 +642,7 @@ instance Monoid HaddockArgs where
argOutputDir = mult argOutputDir,
argTitle = mult argTitle,
argPrologue = mult argPrologue,
- argGhcFlags = mult argGhcFlags,
+ argGhcOptions = mult argGhcOptions,
argGhcLibDir = mult argGhcLibDir,
argTargets = mult argTargets
}
View
449 Cabal/Distribution/Simple/Program/GHC.hs
@@ -0,0 +1,449 @@
+module Distribution.Simple.Program.GHC (
+ GhcOptions(..),
+ GhcMode(..),
+ GhcOptimisation(..),
+
+ ghcInvocation,
+ renderGhcOptions,
+
+ runGHC,
+
+ ) where
+
+import Distribution.Package
+import Distribution.ModuleName
+import Distribution.Simple.Compiler hiding (Flag)
+import Distribution.Simple.Setup (Flag(..), flagToMaybe, fromFlagOrDefault, flagToList)
+--import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Program.Types
+import Distribution.Simple.Program.Run
+import Distribution.Text
+import Distribution.Verbosity
+import Distribution.Version
+import Language.Haskell.Extension ( Language(..), Extension(..) )
+
+import Data.Monoid
+
+
+-- | A structured set of GHC options/flags
+--
+data GhcOptions = GhcOptions {
+
+ -- | The major mode for the ghc invocation.
+ ghcOptMode :: Flag GhcMode,
+
+ -- | Any extra options to pass directly to ghc. These go at the end and hence
+ -- override other stuff.
+ ghcOptExtra :: [String],
+
+ -- | Extra default flags to pass directly to ghc. These go at the beginning
+ -- and so can be overridden by other stuff.
+ ghcOptExtraDefault :: [String],
+
+ -----------------------
+ -- Inputs and outputs
+
+ -- | The main input files; could be .hs, .hi, .c, .o, depending on mode.
+ ghcOptInputFiles :: [FilePath],
+
+ -- | The names of input Haskell modules, mainly for @--make@ mode.
+ ghcOptInputModules :: [ModuleName],
+
+ -- | Location for output file; the @ghc -o@ flag.
+ ghcOptOutputFile :: Flag FilePath,
+
+ -- | Search path for Haskell source files; the @ghc -i@ flag.
+ ghcOptSourcePathClear :: Flag Bool,
+
+ -- | Search path for Haskell source files; the @ghc -i@ flag.
+ ghcOptSourcePath :: [FilePath],
+
+ -------------
+ -- Packages
+
+ -- | The package name the modules will belong to; the @ghc -package-name@ flag
+ ghcOptPackageName :: Flag PackageId,
+
+ -- | GHC package databases to use, the @ghc -package-conf@ flag
+ ghcOptPackageDBs :: PackageDBStack,
+
+ -- | The GHC packages to use. For compatability with old and new ghc, this
+ -- requires both the short and long form of the package id;
+ -- the @ghc -package@ or @ghc -package-id@ flags.
+ ghcOptPackages :: [(InstalledPackageId, PackageId)],
+
+ -- | Start with a clean package set; the @ghc -hide-all-packages@ flag
+ ghcOptHideAllPackages :: Flag Bool,
+
+ -- | Don't automatically link in Haskell98 etc; the @ghc -no-auto-link-packages@ flag.
+ ghcOptNoAutoLinkPackages :: Flag Bool,
+
+ -----------------
+ -- Linker stuff
+
+ -- | Names of libraries to link in; the @ghc -l@ flag.
+ ghcOptLinkLibs :: [FilePath],
+
+ -- | Search path for libraries to link in; the @ghc -L@ flag.
+ ghcOptLinkLibPath :: [FilePath],
+
+ -- | Options to pass through to the linker; the @ghc -optl@ flag.
+ ghcOptLinkOptions :: [String],
+
+ -- | OSX only: frameworks to link in; the @ghc -framework@ flag.
+ ghcOptLinkFrameworks :: [String],
+
+ -- | Don't do the link step, useful in make mode; the @ghc -no-link@ flag.
+ ghcOptNoLink :: Flag Bool,
+
+ --------------------
+ -- C and CPP stuff
+
+ -- | Options to pass through to the C compiler; the @ghc -optc@ flag.
+ ghcOptCcOptions :: [String],
+
+ -- | Options to pass through to CPP; the @ghc -optP@ flag.
+ ghcOptCppOptions :: [String],
+
+ -- | Search path for CPP includes like header files; the @ghc -I@ flag.
+ ghcOptCppIncludePath :: [FilePath],
+
+ -- | Extra header files to include at CPP stage; the @ghc -optP-include@ flag.
+ ghcOptCppIncludes :: [FilePath],
+
+ -- | Extra header files to include for old-style FFI; the @ghc -#include@ flag.
+ ghcOptFfiIncludes :: [FilePath],
+
+ ----------------------------
+ -- Language and extensions
+
+ -- | The base language; the @ghc -XHaskell98@ or @-XHaskell2010@ flag.
+ ghcOptLanguage :: Flag Language,
+
+ -- | The language extensions; the @ghc -X@ flag.
+ ghcOptExtensions :: [Extension],
+
+ -- | A GHC version-dependent mapping of extensions to flags. This must be
+ -- set to be able to make use of the 'ghcOptExtensions'.
+ ghcOptExtensionMap :: [(Extension, String)],
+
+ ----------------
+ -- Compilation
+
+ -- | What optimisation level to use; the @ghc -O@ flag.
+ ghcOptOptimisation :: Flag GhcOptimisation,
+
+ -- | Compile in profiling mode; the @ghc -prof@ flag.
+ ghcOptProfilingMode :: Flag Bool,
+
+ -- | Use the \"split object files\" feature; the @ghc -split-objs@ flag.
+ ghcOptSplitObjs :: Flag Bool,
+
+ ----------------
+ -- GHCi
+
+ -- | Extra GHCi startup scripts; the @-ghci-script@ flag
+ ghcOptGHCiScripts :: [FilePath],
+
+ ------------------------
+ -- Redirecting outputs
+
+ ghcOptHiSuffix :: Flag String,
+ ghcOptObjSuffix :: Flag String,
+ ghcOptHiDir :: Flag FilePath,
+ ghcOptObjDir :: Flag FilePath,
+ ghcOptStubDir :: Flag FilePath,
+
+ --------------------
+ -- Dynamic linking
+
+ ghcOptDynamic :: Flag Bool,
+ ghcOptShared :: Flag Bool,
+ ghcOptFPic :: Flag Bool,
+ ghcOptDylibName :: Flag String,
+
+ ---------------
+ -- Misc flags
+
+ -- | Get GHC to be quiet or verbose with what it's doing; the @ghc -v@ flag.
+ ghcOptVerbosity :: Flag Verbosity,
+
+ -- | Let GHC know that it is Cabal that's calling it.
+ -- Modifies some of the GHC error messages.
+ ghcOptCabal :: Flag Bool
+
+} deriving Show
+
+
+data GhcMode = GhcModeCompile -- ^ @ghc -c@
+ | GhcModeLink -- ^ @ghc@
+ | GhcModeMake -- ^ @ghc --make@
+ | GhcModeInteractive -- ^ @ghci@ \/ @ghc --interactive@
+ | GhcModeAbiHash -- ^ @ghc --abi-hash@
+-- | GhcModeDepAnalysis -- ^ @ghc -M@
+-- | GhcModeEvaluate -- ^ @ghc -e@
+ deriving (Show, Eq)
+
+data GhcOptimisation = GhcNoOptimisation -- ^ @-O0@
+ | GhcNormalOptimisation -- ^ @-O@
+ | GhcMaximumOptimisation -- ^ @-O2@
+ | GhcSpecialOptimisation String -- ^ e.g. @-Odph@
+ deriving (Show, Eq)
+
+
+runGHC :: Verbosity -> ConfiguredProgram -> GhcOptions -> IO ()
+runGHC verbosity ghcProg opts = do
+ runProgramInvocation verbosity (ghcInvocation ghcProg opts)
+
+
+ghcInvocation :: ConfiguredProgram -> GhcOptions -> ProgramInvocation
+ghcInvocation ConfiguredProgram { programVersion = Nothing } _ =
+ error "ghcInvocation: the programVersion must not be Nothing"
+ghcInvocation prog@ConfiguredProgram { programVersion = Just ver } opts =
+ programInvocation prog (renderGhcOptions ver opts)
+
+
+renderGhcOptions :: Version -> GhcOptions -> [String]
+renderGhcOptions (Version ver _) opts =
+ concat
+ [ case flagToMaybe (ghcOptMode opts) of
+ Nothing -> []
+ Just GhcModeCompile -> ["-c"]
+ Just GhcModeLink -> []
+ Just GhcModeMake -> ["--make"]
+ Just GhcModeInteractive -> ["--interactive"]
+ Just GhcModeAbiHash -> ["--abi-hash"]
+-- Just GhcModeDepAnalysis -> ["-M"]
+-- Just GhcModeEvaluate -> ["-e", expr]
+
+ , flags ghcOptExtraDefault
+
+ , [ "-no-link" | flagBool ghcOptNoLink ]
+
+ ---------------
+ -- Misc flags
+
+ , maybe [] verbosityOpts (flagToMaybe (ghcOptVerbosity opts))
+
+ , [ "-fbuilding-cabal-package" | flagBool ghcOptCabal, ver >= [6,11] ]
+
+ ----------------
+ -- Compilation
+
+ , case flagToMaybe (ghcOptOptimisation opts) of
+ Nothing -> []
+ Just GhcNoOptimisation -> ["-O0"]
+ Just GhcNormalOptimisation -> ["-O"]
+ Just GhcMaximumOptimisation -> ["-O2"]
+ Just (GhcSpecialOptimisation s) -> ["-O" ++ s] -- eg -Odph
+
+ , [ "-prof" | flagBool ghcOptProfilingMode ]
+
+ , [ "-split-objs" | flagBool ghcOptSplitObjs ]
+
+ --------------------
+ -- Dynamic linking
+
+ , [ "-shared" | flagBool ghcOptShared ]
+ , [ "-dynamic" | flagBool ghcOptDynamic ]
+ , [ "-fPIC" | flagBool ghcOptFPic ]
+
+ , concat [ ["-dylib-install-name", libname] | libname <- flag ghcOptDylibName ]
+
+ ------------------------
+ -- Redirecting outputs
+
+ , concat [ ["-osuf", suf] | suf <- flag ghcOptObjSuffix ]
+ , concat [ ["-hisuf", suf] | suf <- flag ghcOptHiSuffix ]
+ , concat [ ["-odir", dir] | dir <- flag ghcOptObjDir ]
+ , concat [ ["-hidir", dir] | dir <- flag ghcOptHiDir ]
+ , concat [ ["-stubdir", dir] | dir <- flag ghcOptStubDir, ver >= [6,8] ]
+
+ -----------------------
+ -- Source search path
+
+ , [ "-i" | flagBool ghcOptSourcePathClear ]
+ , [ "-i" ++ dir | dir <- flags ghcOptSourcePath ]
+
+ --------------------
+ -- C and CPP stuff
+
+ , [ "-I" ++ dir | dir <- flags ghcOptCppIncludePath ]
+ , [ "-optP" ++ opt | opt <- flags ghcOptCppOptions ]
+ , concat [ [ "-optP-include", "-optP" ++ inc] | inc <- flags ghcOptCppIncludes ]
+ , [ "-#include \"" ++ inc ++ "\"" | inc <- flags ghcOptFfiIncludes, ver < [6,11] ]
+ , [ "-optc" ++ opt | opt <- flags ghcOptCcOptions ]
+
+ -----------------
+ -- Linker stuff
+
+ , [ "-optl" ++ opt | opt <- flags ghcOptLinkOptions ]
+ , ["-l" ++ lib | lib <- flags ghcOptLinkLibs ]
+ , ["-L" ++ dir | dir <- flags ghcOptLinkLibPath ]
+ , concat [ ["-framework", fmwk] | fmwk <- flags ghcOptLinkFrameworks ]
+
+ -------------
+ -- Packages
+
+ , concat [ ["-package-name", display pkgid] | pkgid <- flag ghcOptPackageName ]
+
+ , [ "-hide-all-packages" | flagBool ghcOptHideAllPackages ]
+ , [ "-no-auto-link-packages" | flagBool ghcOptNoAutoLinkPackages ]
+
+ , packageDbArgs (flags ghcOptPackageDBs)
+
+ , concat $ if ver >= [6,11]
+ then [ ["-package-id", display ipkgid] | (ipkgid,_) <- flags ghcOptPackages ]
+ else [ ["-package", display pkgid] | (_,pkgid) <- flags ghcOptPackages ]
+
+ ----------------------------
+ -- Language and extensions
+
+ , [ "-X" ++ display lang | lang <- flag ghcOptLanguage ]
+
+ , [ case lookup ext (ghcOptExtensionMap opts) of
+ Just arg -> arg
+ Nothing -> error $ "renderGhcOptions: " ++ display ext
+ ++ " not present in ghcOptExtensionMap."
+ | ext <- ghcOptExtensions opts ]
+
+ ----------------
+ -- GHCi
+
+ , concat [ [ "-ghci-script", script ] | script <- flags ghcOptGHCiScripts
+ , ver >= [7,2] ]
+
+ ---------------
+ -- Inputs
+
+ , [ display modu | modu <- flags ghcOptInputModules ]
+ , ghcOptInputFiles opts
+
+ , concat [ [ "-o", out] | out <- flag ghcOptOutputFile ]
+
+ ---------------
+ -- Extra
+
+ , ghcOptExtra opts
+
+ ]
+
+
+ where
+ flag flg = flagToList (flg opts)
+ flags flg = flg opts
+ flagBool flg = fromFlagOrDefault False (flg opts)
+
+
+verbosityOpts :: Verbosity -> [String]
+verbosityOpts verbosity
+ | verbosity >= deafening = ["-v"]
+ | verbosity >= normal = []
+ | otherwise = ["-w", "-v0"]
+
+
+packageDbArgs :: PackageDBStack -> [String]
+packageDbArgs dbstack = case dbstack of
+ (GlobalPackageDB:UserPackageDB:dbs) -> concatMap specific dbs
+ (GlobalPackageDB:dbs) -> "-no-user-package-conf"
+ : concatMap specific dbs
+ _ -> ierror
+ where
+ specific (SpecificPackageDB db) = [ "-package-conf", db ]
+ specific _ = ierror
+ ierror = error $ "internal error: unexpected package db stack: "
+ ++ show dbstack
+
+
+-- -----------------------------------------------------------------------------
+-- Boilerplate Monoid instance for GhcOptions
+
+instance Monoid GhcOptions where
+ mempty = GhcOptions {
+ ghcOptMode = mempty,
+ ghcOptExtra = mempty,
+ ghcOptExtraDefault = mempty,
+ ghcOptInputFiles = mempty,
+ ghcOptInputModules = mempty,
+ ghcOptOutputFile = mempty,
+ ghcOptSourcePathClear = mempty,
+ ghcOptSourcePath = mempty,
+ ghcOptPackageName = mempty,
+ ghcOptPackageDBs = mempty,
+ ghcOptPackages = mempty,
+ ghcOptHideAllPackages = mempty,
+ ghcOptNoAutoLinkPackages = mempty,
+ ghcOptLinkLibs = mempty,
+ ghcOptLinkLibPath = mempty,
+ ghcOptLinkOptions = mempty,
+ ghcOptLinkFrameworks = mempty,
+ ghcOptNoLink = mempty,
+ ghcOptCcOptions = mempty,
+ ghcOptCppOptions = mempty,
+ ghcOptCppIncludePath = mempty,
+ ghcOptCppIncludes = mempty,
+ ghcOptFfiIncludes = mempty,
+ ghcOptLanguage = mempty,
+ ghcOptExtensions = mempty,
+ ghcOptExtensionMap = mempty,
+ ghcOptOptimisation = mempty,
+ ghcOptProfilingMode = mempty,
+ ghcOptSplitObjs = mempty,
+ ghcOptGHCiScripts = mempty,
+ ghcOptHiSuffix = mempty,
+ ghcOptObjSuffix = mempty,
+ ghcOptHiDir = mempty,
+ ghcOptObjDir = mempty,
+ ghcOptStubDir = mempty,
+ ghcOptDynamic = mempty,
+ ghcOptShared = mempty,
+ ghcOptFPic = mempty,
+ ghcOptDylibName = mempty,
+ ghcOptVerbosity = mempty,
+ ghcOptCabal = mempty
+ }
+ mappend a b = GhcOptions {
+ ghcOptMode = combine ghcOptMode,
+ ghcOptExtra = combine ghcOptExtra,
+ ghcOptExtraDefault = combine ghcOptExtraDefault,
+ ghcOptInputFiles = combine ghcOptInputFiles,
+ ghcOptInputModules = combine ghcOptInputModules,
+ ghcOptOutputFile = combine ghcOptOutputFile,
+ ghcOptSourcePathClear = combine ghcOptSourcePathClear,
+ ghcOptSourcePath = combine ghcOptSourcePath,
+ ghcOptPackageName = combine ghcOptPackageName,
+ ghcOptPackageDBs = combine ghcOptPackageDBs,
+ ghcOptPackages = combine ghcOptPackages,
+ ghcOptHideAllPackages = combine ghcOptHideAllPackages,
+ ghcOptNoAutoLinkPackages = combine ghcOptNoAutoLinkPackages,
+ ghcOptLinkLibs = combine ghcOptLinkLibs,
+ ghcOptLinkLibPath = combine ghcOptLinkLibPath,
+ ghcOptLinkOptions = combine ghcOptLinkOptions,
+ ghcOptLinkFrameworks = combine ghcOptLinkFrameworks,
+ ghcOptNoLink = combine ghcOptNoLink,
+ ghcOptCcOptions = combine ghcOptCcOptions,
+ ghcOptCppOptions = combine ghcOptCppOptions,
+ ghcOptCppIncludePath = combine ghcOptCppIncludePath,
+ ghcOptCppIncludes = combine ghcOptCppIncludes,
+ ghcOptFfiIncludes = combine ghcOptFfiIncludes,
+ ghcOptLanguage = combine ghcOptLanguage,
+ ghcOptExtensions = combine ghcOptExtensions,
+ ghcOptExtensionMap = combine ghcOptExtensionMap,
+ ghcOptOptimisation = combine ghcOptOptimisation,
+ ghcOptProfilingMode = combine ghcOptProfilingMode,
+ ghcOptSplitObjs = combine ghcOptSplitObjs,
+ ghcOptGHCiScripts = combine ghcOptGHCiScripts,
+ ghcOptHiSuffix = combine ghcOptHiSuffix,
+ ghcOptObjSuffix = combine ghcOptObjSuffix,
+ ghcOptHiDir = combine ghcOptHiDir,
+ ghcOptObjDir = combine ghcOptObjDir,
+ ghcOptStubDir = combine ghcOptStubDir,
+ ghcOptDynamic = combine ghcOptDynamic,
+ ghcOptShared = combine ghcOptShared,
+ ghcOptFPic = combine ghcOptFPic,
+ ghcOptDylibName = combine ghcOptDylibName,
+ ghcOptVerbosity = combine ghcOptVerbosity,
+ ghcOptCabal = combine ghcOptCabal
+ }
+ where
+ combine field = field a `mappend` field b
Please sign in to comment.
Something went wrong with that request. Please try again.