GHC.hs 19 KB
Newer Older
1 2 3 4
module Distribution.Simple.Program.GHC (
    GhcOptions(..),
    GhcMode(..),
    GhcOptimisation(..),
5
    GhcDynLinkMode(..),
6 7 8 9 10 11 12 13 14

    ghcInvocation,
    renderGhcOptions,

    runGHC,

  ) where

import Distribution.Package
15
import Distribution.PackageDescription hiding (Flag)
16 17
import Distribution.ModuleName
import Distribution.Simple.Compiler hiding (Flag)
18 19
import Distribution.Simple.Setup    ( Flag(..), flagToMaybe, fromFlagOrDefault,
                                      flagToList )
20 21 22 23
import Distribution.Simple.Program.Types
import Distribution.Simple.Program.Run
import Distribution.Text
import Distribution.Verbosity
24
import Distribution.Utils.NubList (NubListR, fromNubListR)
25
import Distribution.Version
26
import Language.Haskell.Extension   ( Language(..), Extension(..) )
27

28
import qualified Data.Map as M
29
import Data.Monoid
30
import Data.List ( intercalate )
31 32 33 34 35 36 37 38 39 40

-- | 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.
41
  ghcOptExtra         :: NubListR String,
42 43 44

  -- | Extra default flags to pass directly to ghc. These go at the beginning
  -- and so can be overridden by other stuff.
45
  ghcOptExtraDefault  :: NubListR String,
46 47 48 49 50

  -----------------------
  -- Inputs and outputs

  -- | The main input files; could be .hs, .hi, .c, .o, depending on mode.
51
  ghcOptInputFiles    :: NubListR FilePath,
52 53

  -- | The names of input Haskell modules, mainly for @--make@ mode.
54
  ghcOptInputModules  :: NubListR ModuleName,
55 56 57 58

  -- | Location for output file; the @ghc -o@ flag.
  ghcOptOutputFile    :: Flag FilePath,

59 60 61 62
  -- | Location for dynamic output file in 'GhcStaticAndDynamic' mode;
  -- the @ghc -dyno@ flag.
  ghcOptOutputDynFile :: Flag FilePath,

63 64
  -- | Start with an empty search path for Haskell source files;
  -- the @ghc -i@ flag (@-i@ on it's own with no path argument).
65 66 67
  ghcOptSourcePathClear :: Flag Bool,

  -- | Search path for Haskell source files; the @ghc -i@ flag.
68
  ghcOptSourcePath    :: NubListR FilePath,
69 70 71 72

  -------------
  -- Packages

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
73 74
  -- | The package key the modules will belong to; the @ghc -this-package-key@
  -- flag.
75
  ghcOptPackageKey   :: Flag PackageKey,
76

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
77
  -- | GHC package databases to use, the @ghc -package-conf@ flag.
78 79 80 81 82
  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.
83 84
  ghcOptPackages      ::
    NubListR (InstalledPackageId, PackageId, ModuleRenaming),
85 86 87 88

  -- | Start with a clean package set; the @ghc -hide-all-packages@ flag
  ghcOptHideAllPackages :: Flag Bool,

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
89 90
  -- | Don't automatically link in Haskell98 etc; the @ghc
  -- -no-auto-link-packages@ flag.
91 92
  ghcOptNoAutoLinkPackages :: Flag Bool,

93 94 95
  -- | What packages are implementing the signatures
  ghcOptSigOf :: [(ModuleName, (PackageKey, ModuleName))],

96 97 98 99
  -----------------
  -- Linker stuff

  -- | Names of libraries to link in; the @ghc -l@ flag.
100
  ghcOptLinkLibs      :: NubListR FilePath,
101 102

  -- | Search path for libraries to link in; the @ghc -L@ flag.
103
  ghcOptLinkLibPath  :: NubListR FilePath,
104 105

  -- | Options to pass through to the linker; the @ghc -optl@ flag.
106
  ghcOptLinkOptions   :: NubListR String,
107 108

  -- | OSX only: frameworks to link in; the @ghc -framework@ flag.
109
  ghcOptLinkFrameworks :: NubListR String,
110 111 112 113

  -- | Don't do the link step, useful in make mode; the @ghc -no-link@ flag.
  ghcOptNoLink :: Flag Bool,

Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
114 115
  -- | Don't link in the normal RTS @main@ entry point; the @ghc -no-hs-main@
  -- flag.
116 117
  ghcOptLinkNoHsMain :: Flag Bool,

118 119 120 121
  --------------------
  -- C and CPP stuff

  -- | Options to pass through to the C compiler; the @ghc -optc@ flag.
122
  ghcOptCcOptions     :: NubListR String,
123 124

  -- | Options to pass through to CPP; the @ghc -optP@ flag.
125
  ghcOptCppOptions    :: NubListR String,
126 127

  -- | Search path for CPP includes like header files; the @ghc -I@ flag.
128
  ghcOptCppIncludePath :: NubListR FilePath,
129 130

  -- | Extra header files to include at CPP stage; the @ghc -optP-include@ flag.
131
  ghcOptCppIncludes    :: NubListR FilePath,
132 133

  -- | Extra header files to include for old-style FFI; the @ghc -#include@ flag.
134
  ghcOptFfiIncludes    :: NubListR FilePath,
135 136 137 138 139 140 141 142

  ----------------------------
  -- Language and extensions

  -- | The base language; the @ghc -XHaskell98@ or @-XHaskell2010@ flag.
  ghcOptLanguage      :: Flag Language,

  -- | The language extensions; the @ghc -X@ flag.
143
  ghcOptExtensions    :: NubListR Extension,
144 145 146

  -- | A GHC version-dependent mapping of extensions to flags. This must be
  -- set to be able to make use of the 'ghcOptExtensions'.
147
  ghcOptExtensionMap    :: M.Map Extension String,
148 149 150 151 152 153 154 155 156 157 158 159 160

  ----------------
  -- 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,

161
  -- | Run N jobs simultaneously (if possible).
162
  ghcOptNumJobs       :: Flag (Maybe Int),
163

164 165 166
  -- | Enable coverage analysis; the @ghc -fhpc -hpcdir@ flags.
  ghcOptHPCDir        :: Flag FilePath,

167 168 169 170
  ----------------
  -- GHCi

  -- | Extra GHCi startup scripts; the @-ghci-script@ flag
171
  ghcOptGHCiScripts    :: NubListR FilePath,
172 173 174 175 176 177

  ------------------------
  -- Redirecting outputs

  ghcOptHiSuffix      :: Flag String,
  ghcOptObjSuffix     :: Flag String,
178 179
  ghcOptDynHiSuffix   :: Flag String,   -- ^ only in 'GhcStaticAndDynamic' mode
  ghcOptDynObjSuffix  :: Flag String,   -- ^ only in 'GhcStaticAndDynamic' mode
180 181
  ghcOptHiDir         :: Flag FilePath,
  ghcOptObjDir        :: Flag FilePath,
182
  ghcOptOutputDir     :: Flag FilePath,
183 184 185 186 187
  ghcOptStubDir       :: Flag FilePath,

  --------------------
  -- Dynamic linking

188
  ghcOptDynLinkMode   :: Flag GhcDynLinkMode,
189 190 191
  ghcOptShared        :: Flag Bool,
  ghcOptFPic          :: Flag Bool,
  ghcOptDylibName     :: Flag String,
192
  ghcOptNoRPath       :: Flag Bool, -- ^ Don't embed any runtime paths.
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221

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

222 223 224 225 226
data GhcDynLinkMode = GhcStaticOnly       -- ^ @-static@
                    | GhcDynamicOnly      -- ^ @-dynamic@
                    | GhcStaticAndDynamic -- ^ @-static -dynamic-too@
 deriving (Show, Eq)

227

228 229 230
runGHC :: Verbosity -> ConfiguredProgram -> Compiler -> GhcOptions -> IO ()
runGHC verbosity ghcProg comp opts = do
  runProgramInvocation verbosity (ghcInvocation ghcProg comp opts)
231 232


233 234 235
ghcInvocation :: ConfiguredProgram -> Compiler -> GhcOptions -> ProgramInvocation
ghcInvocation prog comp opts =
    programInvocation prog (renderGhcOptions comp opts)
236 237


238 239 240 241 242 243
renderGhcOptions :: Compiler -> GhcOptions -> [String]
renderGhcOptions comp opts
  | compilerFlavor comp /= GHC =
    error $ "Distribution.Simple.Program.GHC.renderGhcOptions: "
    ++ "compiler flavor must be 'GHC'!"
  | otherwise =
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
  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 ]

280 281 282
  , case flagToMaybe (ghcOptHPCDir opts) of
      Nothing -> []
      Just hpcdir -> ["-fhpc", "-hpcdir", hpcdir]
283

284
  , if parmakeSupported comp
285 286 287
    then case ghcOptNumJobs opts of
      NoFlag  -> []
      Flag n  -> ["-j" ++ maybe "" show n]
288
    else []
289

290 291 292 293
  --------------------
  -- Dynamic linking

  , [ "-shared"  | flagBool ghcOptShared  ]
294 295 296 297 298
  , case flagToMaybe (ghcOptDynLinkMode opts) of
      Nothing                  -> []
      Just GhcStaticOnly       -> ["-static"]
      Just GhcDynamicOnly      -> ["-dynamic"]
      Just GhcStaticAndDynamic -> ["-static", "-dynamic-too"]
299 300 301 302 303 304 305 306 307
  , [ "-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  ]
308 309
  , concat [ ["-dynosuf", suf] | suf <- flag ghcOptDynObjSuffix ]
  , concat [ ["-dynhisuf",suf] | suf <- flag ghcOptDynHiSuffix  ]
310
  , concat [ ["-outputdir", dir] | dir <- flag ghcOptOutputDir, ver >= [6,10] ]
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
  , 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 ]
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
326 327 328 329
  , concat [ [ "-optP-include", "-optP" ++ inc]
           | inc <- flags ghcOptCppIncludes ]
  , [ "-#include \"" ++ inc ++ "\""
    | inc <- flags ghcOptFfiIncludes, ver < [6,11] ]
330 331 332 333 334 335 336 337 338
  , [ "-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 ]
339
  , [ "-no-hs-main"  | flagBool ghcOptLinkNoHsMain ]
340
  , [ "-dynload deploy" | flagBool ghcOptNoRPath ]
341 342 343 344

  -------------
  -- Packages

345 346 347 348
  , concat [ [if packageKeySupported comp
                then "-this-package-key"
                else "-package-name", display pkgid]
             | pkgid <- flag ghcOptPackageKey ]
349 350 351 352

  , [ "-hide-all-packages"     | flagBool ghcOptHideAllPackages ]
  , [ "-no-auto-link-packages" | flagBool ghcOptNoAutoLinkPackages ]

353
  , packageDbArgs version (ghcOptPackageDBs opts)
354

355 356 357 358 359 360 361 362 363
  , if null (ghcOptSigOf opts)
        then []
        else "-sig-of"
             : intercalate "," (map (\(n,(p,m)) -> display n ++ " is "
                                                ++ display p ++ ":"
                                                ++ display m)
                                    (ghcOptSigOf opts))
             : []

364
  , concat $ if ver >= [6,11]
365 366
      then let space "" = ""
               space xs = ' ' : xs
Mikhail Glushenkov's avatar
Mikhail Glushenkov committed
367 368 369 370
           in [ ["-package-id", display ipkgid ++ space (display rns)]
              | (ipkgid,_,rns) <- flags ghcOptPackages ]
      else [ ["-package",    display  pkgid]
           | (_,pkgid,_)  <- flags ghcOptPackages ]
371 372 373 374

  ----------------------------
  -- Language and extensions

375 376 377
  , if ver >= [7]
    then [ "-X" ++ display lang | lang <- flag ghcOptLanguage ]
    else []
378

379
  , [ case M.lookup ext (ghcOptExtensionMap opts) of
380
        Just arg -> arg
381 382
        Nothing  -> error $ "Distribution.Simple.Program.GHC.renderGhcOptions: "
                          ++ display ext ++ " not present in ghcOptExtensionMap."
383
    | ext <- flags ghcOptExtensions ]
384 385 386 387 388 389 390 391 392 393 394

  ----------------
  -- GHCi

  , concat [ [ "-ghci-script", script ] | script <- flags  ghcOptGHCiScripts
                                        , ver >= [7,2] ]

  ---------------
  -- Inputs

  , [ display modu | modu <- flags ghcOptInputModules ]
395
  , flags ghcOptInputFiles
396

397 398
  , concat [ [ "-o",    out] | out <- flag ghcOptOutputFile ]
  , concat [ [ "-dyno", out] | out <- flag ghcOptOutputDynFile ]
399 400 401 402

  ---------------
  -- Extra

403
  , flags ghcOptExtra
404 405 406 407 408 409

  ]


  where
    flag     flg = flagToList (flg opts)
410
    flags    flg = fromNubListR . flg $ opts
411 412
    flagBool flg = fromFlagOrDefault False (flg opts)

413
    version@(Version ver _) = compilerVersion comp
414 415 416 417 418 419 420 421

verbosityOpts :: Verbosity -> [String]
verbosityOpts verbosity
  | verbosity >= deafening = ["-v"]
  | verbosity >= normal    = []
  | otherwise              = ["-w", "-v0"]


422 423
packageDbArgs :: Version -> PackageDBStack -> [String]
packageDbArgs (Version ver _) dbstack = case dbstack of
424
  (GlobalPackageDB:UserPackageDB:dbs) -> concatMap specific dbs
425
  (GlobalPackageDB:dbs)               -> ("-no-user-" ++ packageDbFlag)
426 427 428
                                       : concatMap specific dbs
  _ -> ierror
  where
429
    specific (SpecificPackageDB db) = [ '-':packageDbFlag , db ]
430 431 432 433
    specific _ = ierror
    ierror     = error $ "internal error: unexpected package db stack: "
                      ++ show dbstack

434 435 436 437 438 439
    packageDbFlag
      | ver < [7,5]
      = "package-conf"
      | otherwise
      = "package-db"

440 441 442 443 444 445 446 447 448 449 450 451

-- -----------------------------------------------------------------------------
-- Boilerplate Monoid instance for GhcOptions

instance Monoid GhcOptions where
  mempty = GhcOptions {
    ghcOptMode               = mempty,
    ghcOptExtra              = mempty,
    ghcOptExtraDefault       = mempty,
    ghcOptInputFiles         = mempty,
    ghcOptInputModules       = mempty,
    ghcOptOutputFile         = mempty,
452
    ghcOptOutputDynFile      = mempty,
453 454
    ghcOptSourcePathClear    = mempty,
    ghcOptSourcePath         = mempty,
455
    ghcOptPackageKey         = mempty,
456 457 458 459
    ghcOptPackageDBs         = mempty,
    ghcOptPackages           = mempty,
    ghcOptHideAllPackages    = mempty,
    ghcOptNoAutoLinkPackages = mempty,
460
    ghcOptSigOf              = mempty,
461 462 463 464 465
    ghcOptLinkLibs           = mempty,
    ghcOptLinkLibPath        = mempty,
    ghcOptLinkOptions        = mempty,
    ghcOptLinkFrameworks     = mempty,
    ghcOptNoLink             = mempty,
466
    ghcOptLinkNoHsMain       = mempty,
467 468 469 470 471 472 473 474 475 476 477
    ghcOptCcOptions          = mempty,
    ghcOptCppOptions         = mempty,
    ghcOptCppIncludePath     = mempty,
    ghcOptCppIncludes        = mempty,
    ghcOptFfiIncludes        = mempty,
    ghcOptLanguage           = mempty,
    ghcOptExtensions         = mempty,
    ghcOptExtensionMap       = mempty,
    ghcOptOptimisation       = mempty,
    ghcOptProfilingMode      = mempty,
    ghcOptSplitObjs          = mempty,
478
    ghcOptNumJobs            = mempty,
479
    ghcOptHPCDir             = mempty,
480 481 482
    ghcOptGHCiScripts        = mempty,
    ghcOptHiSuffix           = mempty,
    ghcOptObjSuffix          = mempty,
483 484
    ghcOptDynHiSuffix        = mempty,
    ghcOptDynObjSuffix       = mempty,
485 486
    ghcOptHiDir              = mempty,
    ghcOptObjDir             = mempty,
487
    ghcOptOutputDir          = mempty,
488
    ghcOptStubDir            = mempty,
489
    ghcOptDynLinkMode        = mempty,
490 491 492
    ghcOptShared             = mempty,
    ghcOptFPic               = mempty,
    ghcOptDylibName          = mempty,
493
    ghcOptNoRPath            = mempty,
494 495 496 497 498 499 500 501 502 503
    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,
504
    ghcOptOutputDynFile      = combine ghcOptOutputDynFile,
505 506
    ghcOptSourcePathClear    = combine ghcOptSourcePathClear,
    ghcOptSourcePath         = combine ghcOptSourcePath,
507
    ghcOptPackageKey         = combine ghcOptPackageKey,
508 509 510 511
    ghcOptPackageDBs         = combine ghcOptPackageDBs,
    ghcOptPackages           = combine ghcOptPackages,
    ghcOptHideAllPackages    = combine ghcOptHideAllPackages,
    ghcOptNoAutoLinkPackages = combine ghcOptNoAutoLinkPackages,
512
    ghcOptSigOf              = combine ghcOptSigOf,
513 514 515 516 517
    ghcOptLinkLibs           = combine ghcOptLinkLibs,
    ghcOptLinkLibPath        = combine ghcOptLinkLibPath,
    ghcOptLinkOptions        = combine ghcOptLinkOptions,
    ghcOptLinkFrameworks     = combine ghcOptLinkFrameworks,
    ghcOptNoLink             = combine ghcOptNoLink,
518
    ghcOptLinkNoHsMain       = combine ghcOptLinkNoHsMain,
519 520 521 522 523 524 525 526 527 528 529
    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,
530
    ghcOptNumJobs            = combine ghcOptNumJobs,
531
    ghcOptHPCDir             = combine ghcOptHPCDir,
532 533 534
    ghcOptGHCiScripts        = combine ghcOptGHCiScripts,
    ghcOptHiSuffix           = combine ghcOptHiSuffix,
    ghcOptObjSuffix          = combine ghcOptObjSuffix,
535 536
    ghcOptDynHiSuffix        = combine ghcOptDynHiSuffix,
    ghcOptDynObjSuffix       = combine ghcOptDynObjSuffix,
537 538
    ghcOptHiDir              = combine ghcOptHiDir,
    ghcOptObjDir             = combine ghcOptObjDir,
539
    ghcOptOutputDir          = combine ghcOptOutputDir,
540
    ghcOptStubDir            = combine ghcOptStubDir,
541
    ghcOptDynLinkMode        = combine ghcOptDynLinkMode,
542 543 544
    ghcOptShared             = combine ghcOptShared,
    ghcOptFPic               = combine ghcOptFPic,
    ghcOptDylibName          = combine ghcOptDylibName,
545
    ghcOptNoRPath            = combine ghcOptNoRPath,
546 547 548 549 550
    ghcOptVerbosity          = combine ghcOptVerbosity,
    ghcOptCabal              = combine ghcOptCabal
  }
    where
      combine field = field a `mappend` field b