Main.hs 22.5 KB
Newer Older
Ian Lynagh's avatar
Ian Lynagh committed
1 2 3 4 5

module Main (main) where

import qualified Distribution.ModuleName as ModuleName
import Distribution.PackageDescription
6
import Distribution.PackageDescription.Check hiding (doesFileExist)
Ian Lynagh's avatar
Ian Lynagh committed
7 8
import Distribution.PackageDescription.Configuration
import Distribution.PackageDescription.Parse
9
import Distribution.System
Ian Lynagh's avatar
Ian Lynagh committed
10 11 12 13
import Distribution.Simple
import Distribution.Simple.Configure
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Program
Ian Lynagh's avatar
Ian Lynagh committed
14
import Distribution.Simple.Program.HcPkg
15
import Distribution.Simple.Utils (defaultPackageDesc, writeFileAtomic, toUTF8)
Ian Lynagh's avatar
Ian Lynagh committed
16
import Distribution.Simple.Build (writeAutogenFiles)
Ian Lynagh's avatar
Ian Lynagh committed
17
import Distribution.Simple.Register
Ian Lynagh's avatar
Ian Lynagh committed
18 19 20 21 22
import Distribution.Text
import Distribution.Verbosity
import qualified Distribution.InstalledPackageInfo as Installed
import qualified Distribution.Simple.PackageIndex as PackageIndex

pcapriotti's avatar
pcapriotti committed
23
import Control.Monad
ian@well-typed.com's avatar
ian@well-typed.com committed
24
import qualified Data.ByteString.Lazy.Char8 as BS
25
import Data.List
Ian Lynagh's avatar
Ian Lynagh committed
26 27 28 29 30 31 32 33
import Data.Maybe
import System.IO
import System.Directory
import System.Environment
import System.Exit
import System.FilePath

main :: IO ()
34 35
main = do hSetBuffering stdout LineBuffering
          args <- getArgs
Ian Lynagh's avatar
Ian Lynagh committed
36
          case args of
ian@well-typed.com's avatar
ian@well-typed.com committed
37 38
              "hscolour" : dir : distDir : args' ->
                  runHsColour dir distDir args'
39 40
              "check" : dir : [] ->
                  doCheck dir
ian@well-typed.com's avatar
ian@well-typed.com committed
41 42
              "copy" : dir : distDir
                     : strip : myDestDir : myPrefix : myLibdir : myDocdir
43
                     : args' ->
ian@well-typed.com's avatar
ian@well-typed.com committed
44 45
                  doCopy dir distDir
                         strip myDestDir myPrefix myLibdir myDocdir
46
                         args'
ian@well-typed.com's avatar
ian@well-typed.com committed
47
              "register" : dir : distDir : ghc : ghcpkg : topdir
48 49
                         : myDestDir : myPrefix : myLibdir : myDocdir
                         : relocatableBuild : args' ->
ian@well-typed.com's avatar
ian@well-typed.com committed
50
                  doRegister dir distDir ghc ghcpkg topdir
51 52
                             myDestDir myPrefix myLibdir myDocdir
                             relocatableBuild args'
53 54
              "configure" : dir : distDir : dll0Modules : config_args ->
                  generate dir distDir dll0Modules config_args
55 56
              "sdist" : dir : distDir : [] ->
                  doSdist dir distDir
57 58
              ["--version"] ->
                  defaultMainArgs ["--version"]
Ian Lynagh's avatar
Ian Lynagh committed
59 60 61 62 63 64
              _ -> die syntax_error

syntax_error :: [String]
syntax_error =
    ["syntax: ghc-cabal configure <configure-args> -- <distdir> <directory>...",
     "        ghc-cabal install <ghc-pkg> <directory> <distdir> <destdir> <prefix> <args>...",
65
     "        ghc-cabal hscolour <distdir> <directory> <args>..."]
Ian Lynagh's avatar
Ian Lynagh committed
66

67
die :: [String] -> IO a
Ian Lynagh's avatar
Ian Lynagh committed
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
die errs = do mapM_ (hPutStrLn stderr) errs
              exitWith (ExitFailure 1)

-- XXX Should use bracket
withCurrentDirectory :: FilePath -> IO a -> IO a
withCurrentDirectory directory io
 = do curDirectory <- getCurrentDirectory
      setCurrentDirectory directory
      r <- io
      setCurrentDirectory curDirectory
      return r

-- We need to use the autoconfUserHooks, as the packages that use
-- configure can create a .buildinfo file, and we need any info that
-- ends up in it.
userHooks :: UserHooks
userHooks = autoconfUserHooks

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
runDefaultMain :: IO ()
runDefaultMain
 = do let verbosity = normal
      gpdFile <- defaultPackageDesc verbosity
      gpd <- readPackageDescription verbosity gpdFile
      case buildType (flattenPackageDescription gpd) of
          Just Configure -> defaultMainWithHooks autoconfUserHooks
          -- time has a "Custom" Setup.hs, but it's actually Configure
          -- plus a "./Setup test" hook. However, Cabal is also
          -- "Custom", but doesn't have a configure script.
          Just Custom ->
              do configureExists <- doesFileExist "configure"
                 if configureExists
                     then defaultMainWithHooks autoconfUserHooks
                     else defaultMain
          -- not quite right, but good enough for us:
          _ -> defaultMain

doSdist :: FilePath -> FilePath -> IO ()
doSdist directory distDir
 = withCurrentDirectory directory
 $ withArgs (["sdist", "--builddir", distDir])
            runDefaultMain

110 111 112 113 114 115 116 117 118 119 120 121 122 123
doCheck :: FilePath -> IO ()
doCheck directory
 = withCurrentDirectory directory
 $ do let verbosity = normal
      gpdFile <- defaultPackageDesc verbosity
      gpd <- readPackageDescription verbosity gpdFile
      case partition isFailure $ checkPackage gpd Nothing of
          ([],   [])       -> return ()
          ([],   warnings) -> mapM_ print warnings
          (errs, _)        -> do mapM_ print errs
                                 exitWith (ExitFailure 1)
    where isFailure (PackageDistSuspicious {}) = False
          isFailure _ = True

124
runHsColour :: FilePath -> FilePath -> [String] -> IO ()
ian@well-typed.com's avatar
ian@well-typed.com committed
125
runHsColour directory distdir args
Ian Lynagh's avatar
Ian Lynagh committed
126
 = withCurrentDirectory directory
127
 $ defaultMainArgs ("hscolour" : "--builddir" : distdir : args)
Ian Lynagh's avatar
Ian Lynagh committed
128

129 130 131 132
doCopy :: FilePath -> FilePath
       -> FilePath -> FilePath -> FilePath -> FilePath -> FilePath
       -> [String]
       -> IO ()
ian@well-typed.com's avatar
ian@well-typed.com committed
133 134 135
doCopy directory distDir
       strip myDestDir myPrefix myLibdir myDocdir
       args
Ian Lynagh's avatar
Ian Lynagh committed
136
 = withCurrentDirectory directory $ do
137 138 139 140 141 142 143 144 145 146
     let copyArgs = ["copy", "--builddir", distDir]
                 ++ (if null myDestDir
                     then []
                     else ["--destdir", myDestDir])
                 ++ args
         copyHooks = userHooks {
                         copyHook = noGhcPrimHook
                                  $ modHook False
                                  $ copyHook userHooks
                     }
Ian Lynagh's avatar
Ian Lynagh committed
147

148 149
     defaultMainWithHooksArgs copyHooks copyArgs
    where
150 151
      noGhcPrimHook f pd lbi us flags
              = let pd'
Ian Lynagh's avatar
Ian Lynagh committed
152 153 154 155 156 157 158 159 160 161
                     | packageName pd == PackageName "ghc-prim" =
                        case library pd of
                        Just lib ->
                            let ghcPrim = fromJust (simpleParse "GHC.Prim")
                                ems = filter (ghcPrim /=) (exposedModules lib)
                                lib' = lib { exposedModules = ems }
                            in pd { library = Just lib' }
                        Nothing ->
                            error "Expected a library, but none found"
                     | otherwise = pd
162
                in f pd' lbi us flags
163
      modHook relocatableBuild f pd lbi us flags
Ian Lynagh's avatar
Ian Lynagh committed
164
       = do let verbosity = normal
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
                idts = updateInstallDirTemplates relocatableBuild
                                                 myPrefix myLibdir myDocdir
                                                 (installDirTemplates lbi)
                progs = withPrograms lbi
                stripProgram' = stripProgram {
                    programFindLocation = \_ -> return (Just strip) }

            progs' <- configureProgram verbosity stripProgram' progs
            let lbi' = lbi {
                               withPrograms = progs',
                               installDirTemplates = idts
                           }
            f pd lbi' us flags

doRegister :: FilePath -> FilePath -> FilePath -> FilePath
           -> FilePath -> FilePath -> FilePath -> FilePath -> FilePath
           -> String -> [String]
           -> IO ()
ian@well-typed.com's avatar
ian@well-typed.com committed
183
doRegister directory distDir ghc ghcpkg topdir
184
           myDestDir myPrefix myLibdir myDocdir
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
           relocatableBuildStr args
 = withCurrentDirectory directory $ do
     relocatableBuild <- case relocatableBuildStr of
                         "YES" -> return True
                         "NO"  -> return False
                         _ -> die ["Bad relocatableBuildStr: " ++
                                   show relocatableBuildStr]
     let regArgs = "register" : "--builddir" : distDir : args
         regHooks = userHooks {
                        regHook = modHook relocatableBuild
                                $ regHook userHooks
                    }

     defaultMainWithHooksArgs regHooks  regArgs
    where
      modHook relocatableBuild f pd lbi us flags
       = do let verbosity = normal
                idts = updateInstallDirTemplates relocatableBuild
                                                 myPrefix myLibdir myDocdir
                                                 (installDirTemplates lbi)
Ian Lynagh's avatar
Ian Lynagh committed
205
                progs = withPrograms lbi
206
                ghcpkgconf = topdir </> "package.conf.d"
pcapriotti's avatar
pcapriotti committed
207 208 209 210
                ghcProgram' = ghcProgram {
                    programPostConf = \_ _ -> return ["-B" ++ topdir],
                    programFindLocation = \_ -> return (Just ghc) }
                ghcPkgProgram' = ghcPkgProgram {
211
                    programPostConf = \_ _ -> return $ ["--global-package-db", ghcpkgconf]
212
                                                    ++ ["--force" | not (null myDestDir) ],
pcapriotti's avatar
pcapriotti committed
213 214 215
                    programFindLocation = \_ -> return (Just ghcpkg) }
                configurePrograms ps conf = foldM (flip (configureProgram verbosity)) conf ps

216
            progs' <- configurePrograms [ghcProgram', ghcPkgProgram'] progs
pcapriotti's avatar
pcapriotti committed
217
            let Just ghcPkgProg = lookupProgram ghcPkgProgram' progs'
Ian Lynagh's avatar
Ian Lynagh committed
218
            instInfos <- dump verbosity ghcPkgProg GlobalPackageDB
219
            let installedPkgs' = PackageIndex.fromList instInfos
ian@well-typed.com's avatar
ian@well-typed.com committed
220 221
            let updateComponentConfig (cn, clbi, deps)
                    = (cn, updateComponentLocalBuildInfo clbi, deps)
ian@well-typed.com's avatar
ian@well-typed.com committed
222 223 224 225 226 227
                updateComponentLocalBuildInfo clbi
                    = clbi {
                          componentPackageDeps =
                              [ (fixupPackageId instInfos ipid, pid)
                              | (ipid,pid) <- componentPackageDeps clbi ]
                      }
ian@well-typed.com's avatar
ian@well-typed.com committed
228
                ccs' = map updateComponentConfig (componentsConfigs lbi)
Ian Lynagh's avatar
Ian Lynagh committed
229
                lbi' = lbi {
ian@well-typed.com's avatar
ian@well-typed.com committed
230
                               componentsConfigs = ccs',
Ian Lynagh's avatar
Ian Lynagh committed
231
                               installedPkgs = installedPkgs',
232
                               installDirTemplates = idts,
Ian Lynagh's avatar
Ian Lynagh committed
233 234 235 236
                               withPrograms = progs'
                           }
            f pd lbi' us flags

237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
updateInstallDirTemplates :: Bool -> FilePath -> FilePath -> FilePath
                          -> InstallDirTemplates
                          -> InstallDirTemplates
updateInstallDirTemplates relocatableBuild myPrefix myLibdir myDocdir idts
    = idts {
          prefix    = toPathTemplate $
                          if relocatableBuild
                          then "$topdir"
                          else myPrefix,
          libdir    = toPathTemplate $
                          if relocatableBuild
                          then "$topdir"
                          else myLibdir,
          libsubdir = toPathTemplate "$pkgid",
          docdir    = toPathTemplate $
                          if relocatableBuild
                          then "$topdir/../doc/html/libraries/$pkgid"
                          else (myDocdir </> "$pkgid"),
          htmldir   = toPathTemplate "$docdir"
      }

Ian Lynagh's avatar
Ian Lynagh committed
258 259 260 261 262 263 264 265
-- The packages are built with the package ID ending in "-inplace", but
-- when they're installed they get the package hash appended. We need to
-- fix up the package deps so that they use the hash package IDs, not
-- the inplace package IDs.
fixupPackageId :: [Installed.InstalledPackageInfo]
               -> InstalledPackageId
               -> InstalledPackageId
fixupPackageId _ x@(InstalledPackageId ipi)
266
 | "builtin_" `isPrefixOf` ipi = x
Ian Lynagh's avatar
Ian Lynagh committed
267 268 269 270 271 272 273 274 275 276 277 278 279 280
fixupPackageId ipinfos (InstalledPackageId ipi)
 = case stripPrefix (reverse "-inplace") $ reverse ipi of
   Nothing ->
       error ("Installed package ID doesn't end in -inplace: " ++ show ipi)
   Just x ->
       let ipi' = reverse ('-' : x)
           f (ipinfo : ipinfos') = case Installed.installedPackageId ipinfo of
                                   y@(InstalledPackageId ipinfoid)
                                    | ipi' `isPrefixOf` ipinfoid ->
                                       y
                                   _ ->
                                       f ipinfos'
           f [] = error ("Installed package ID not registered: " ++ show ipi)
       in f ipinfos
Ian Lynagh's avatar
Ian Lynagh committed
281

282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
-- On Windows we need to split the ghc package into 2 pieces, or the
-- DLL that it makes contains too many symbols (#5987). There are
-- therefore 2 libraries, not just the 1 that Cabal assumes.
mangleLbi :: FilePath -> FilePath -> LocalBuildInfo -> LocalBuildInfo
mangleLbi "compiler" "stage2" lbi
 | isWindows =
    let ccs' = [ (cn, updateComponentLocalBuildInfo clbi, cns)
               | (cn, clbi, cns) <- componentsConfigs lbi ]
        updateComponentLocalBuildInfo clbi@(LibComponentLocalBuildInfo {})
            = let cls' = concat [ [ LibraryName n, LibraryName (n ++ "-0") ]
                                | LibraryName n <- componentLibraries clbi ]
              in clbi { componentLibraries = cls' }
        updateComponentLocalBuildInfo clbi = clbi
    in lbi { componentsConfigs = ccs' }
    where isWindows = case hostPlatform lbi of
                      Platform _ Windows -> True
                      _                  -> False
mangleLbi _ _ lbi = lbi

301 302
generate :: FilePath -> FilePath -> String -> [String] -> IO ()
generate directory distdir dll0Modules config_args
Ian Lynagh's avatar
Ian Lynagh committed
303
 = withCurrentDirectory directory
Ian Lynagh's avatar
Ian Lynagh committed
304
 $ do let verbosity = normal
Ian Lynagh's avatar
Ian Lynagh committed
305 306 307 308
      -- XXX We shouldn't just configure with the default flags
      -- XXX And this, and thus the "getPersistBuildConfig distdir" below,
      -- aren't going to work when the deps aren't built yet
      withArgs (["configure", "--distdir", distdir] ++ config_args)
309
               runDefaultMain
Ian Lynagh's avatar
Ian Lynagh committed
310

311 312 313 314 315
      lbi0 <- getPersistBuildConfig distdir
      let lbi = mangleLbi directory distdir lbi0
          pd0 = localPkgDescr lbi

      writePersistBuildConfig distdir lbi
Ian Lynagh's avatar
Ian Lynagh committed
316 317

      hooked_bi <-
Ian Lynagh's avatar
Ian Lynagh committed
318
           if (buildType pd0 == Just Configure) || (buildType pd0 == Just Custom)
Ian Lynagh's avatar
Ian Lynagh committed
319 320 321 322 323 324 325 326 327 328 329 330 331 332
           then do
              maybe_infoFile <- defaultHookedPackageDesc
              case maybe_infoFile of
                  Nothing       -> return emptyHookedBuildInfo
                  Just infoFile -> readHookedBuildInfo verbosity infoFile
           else
              return emptyHookedBuildInfo

      let pd = updatePackageDescription hooked_bi pd0

      -- generate Paths_<pkg>.hs and cabal-macros.h
      writeAutogenFiles verbosity pd lbi

      -- generate inplace-pkg-config
ian@well-typed.com's avatar
ian@well-typed.com committed
333 334 335 336 337 338 339 340 341 342 343
      withLibLBI pd lbi $ \lib clbi ->
          do cwd <- getCurrentDirectory
             let ipid = InstalledPackageId (display (packageId pd) ++ "-inplace")
             let installedPkgInfo = inplaceInstalledPackageInfo cwd distdir
                                        pd lib lbi clbi
                 final_ipi = installedPkgInfo {
                                 Installed.installedPackageId = ipid,
                                 Installed.haddockHTMLs = []
                             }
                 content = Installed.showInstalledPackageInfo final_ipi ++ "\n"
             writeFileAtomic (distdir </> "inplace-pkg-config") (BS.pack $ toUTF8 content)
Ian Lynagh's avatar
Ian Lynagh committed
344 345

      let
Ian Lynagh's avatar
Ian Lynagh committed
346 347
          libBiModules lib = (libBuildInfo lib, libModules lib)
          exeBiModules exe = (buildInfo exe, ModuleName.main : exeModules exe)
Ian Lynagh's avatar
Ian Lynagh committed
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372
          biModuless = (maybeToList $ fmap libBiModules $ library pd)
                    ++ (map exeBiModules $ executables pd)
          buildableBiModuless = filter isBuildable biModuless
              where isBuildable (bi', _) = buildable bi'
          (bi, modules) = case buildableBiModuless of
                          [] -> error "No buildable component found"
                          [biModules] -> biModules
                          _ -> error ("XXX ghc-cabal can't handle " ++
                                      "more than one buildinfo yet")
          -- XXX Another Just...
          Just ghcProg = lookupProgram ghcProgram (withPrograms lbi)

          dep_pkgs = PackageIndex.topologicalOrder (packageHacks (installedPkgs lbi))
          forDeps f = concatMap f dep_pkgs

          -- copied from Distribution.Simple.PreProcess.ppHsc2Hs
          packageHacks = case compilerFlavor (compiler lbi) of
            GHC -> hackRtsPackage
            _   -> id
          -- We don't link in the actual Haskell libraries of our
          -- dependencies, so the -u flags in the ldOptions of the rts
          -- package mean linking fails on OS X (it's ld is a tad
          -- stricter than gnu ld). Thus we remove the ldOptions for
          -- GHC's rts package:
          hackRtsPackage index =
373
            case PackageIndex.lookupPackageName index (PackageName "rts") of
374 375 376 377 378 379 380 381 382 383
              [(_,[rts])] ->
                 PackageIndex.insert rts{
                     Installed.ldOptions = [],
                     Installed.libraryDirs = filter (not . ("gcc-lib" `isSuffixOf`)) (Installed.libraryDirs rts)} index
                        -- GHC <= 6.12 had $topdir/gcc-lib in their
                        -- library-dirs for the rts package, which causes
                        -- problems when we try to use the in-tree mingw,
                        -- due to accidentally picking up the incompatible
                        -- libraries there.  So we filter out gcc-lib from
                        -- the RTS's library-dirs here.
Ian Lynagh's avatar
Ian Lynagh committed
384 385
              _ -> error "No (or multiple) ghc rts package is registered!!"

386 387 388
          dep_ids  = map snd (externalPackageDeps lbi)
          deps     = map display dep_ids
          depNames = map (display . packageName) dep_ids
389

390
          transitive_dep_ids = map Installed.sourcePackageId dep_pkgs
391 392 393 394 395 396 397 398 399 400 401
          transitiveDeps = map display transitive_dep_ids
          transitiveDepNames = map (display . packageName) transitive_dep_ids

          libraryDirs = forDeps Installed.libraryDirs
          -- The mkLibraryRelDir function is a bit of a hack.
          -- Ideally it should be handled in the makefiles instead.
          mkLibraryRelDir "rts"   = "rts/dist/build"
          mkLibraryRelDir "ghc"   = "compiler/stage2/build"
          mkLibraryRelDir "Cabal" = "libraries/Cabal/Cabal/dist-install/build"
          mkLibraryRelDir l       = "libraries/" ++ l ++ "/dist-install/build"
          libraryRelDirs = map mkLibraryRelDir transitiveDepNames
402
      wrappedIncludeDirs <- wrap $ forDeps Installed.includeDirs
403
      wrappedLibraryDirs <- wrap libraryDirs
404

Ian Lynagh's avatar
Ian Lynagh committed
405
      let variablePrefix = directory ++ '_':distdir
406 407 408
          mods      = map display modules
          otherMods = map display (otherModules bi)
          allMods = mods ++ otherMods
Ian Lynagh's avatar
Ian Lynagh committed
409
      let xs = [variablePrefix ++ "_VERSION = " ++ display (pkgVersion (package pd)),
410 411
                variablePrefix ++ "_MODULES = " ++ unwords mods,
                variablePrefix ++ "_HIDDEN_MODULES = " ++ unwords otherMods,
412
                variablePrefix ++ "_SYNOPSIS =" ++ synopsis pd,
Ian Lynagh's avatar
Ian Lynagh committed
413
                variablePrefix ++ "_HS_SRC_DIRS = " ++ unwords (hsSourceDirs bi),
414 415 416 417
                variablePrefix ++ "_DEPS = " ++ unwords deps,
                variablePrefix ++ "_DEP_NAMES = " ++ unwords depNames,
                variablePrefix ++ "_TRANSITIVE_DEPS = " ++ unwords transitiveDeps,
                variablePrefix ++ "_TRANSITIVE_DEP_NAMES = " ++ unwords transitiveDepNames,
Ian Lynagh's avatar
Ian Lynagh committed
418 419 420 421 422 423
                variablePrefix ++ "_INCLUDE_DIRS = " ++ unwords (includeDirs bi),
                variablePrefix ++ "_INCLUDES = " ++ unwords (includes bi),
                variablePrefix ++ "_INSTALL_INCLUDES = " ++ unwords (installIncludes bi),
                variablePrefix ++ "_EXTRA_LIBRARIES = " ++ unwords (extraLibs bi),
                variablePrefix ++ "_EXTRA_LIBDIRS = " ++ unwords (extraLibDirs bi),
                variablePrefix ++ "_C_SRCS  = " ++ unwords (cSources bi),
424
                variablePrefix ++ "_CMM_SRCS  := $(addprefix cbits/,$(notdir $(wildcard " ++ directory ++ "/cbits/*.cmm)))",
425
                variablePrefix ++ "_DATA_FILES = "    ++ unwords (dataFiles pd),
Ian Lynagh's avatar
Ian Lynagh committed
426 427
                -- XXX This includes things it shouldn't, like:
                -- -odir dist-bootstrapping/build
Ian Lynagh's avatar
Ian Lynagh committed
428 429
                variablePrefix ++ "_HC_OPTS = " ++ escape (unwords
                       (   programDefaultArgs ghcProg
Ian Lynagh's avatar
Ian Lynagh committed
430
                        ++ hcOptions GHC bi
431
                        ++ languageToFlags (compiler lbi) (defaultLanguage bi)
432
                        ++ extensionsToFlags (compiler lbi) (usedExtensions bi)
Ian Lynagh's avatar
Ian Lynagh committed
433
                        ++ programOverrideArgs ghcProg)),
Ian Lynagh's avatar
Ian Lynagh committed
434 435 436
                variablePrefix ++ "_CC_OPTS = "                        ++ unwords (ccOptions bi),
                variablePrefix ++ "_CPP_OPTS = "                       ++ unwords (cppOptions bi),
                variablePrefix ++ "_LD_OPTS = "                        ++ unwords (ldOptions bi),
437
                variablePrefix ++ "_DEP_INCLUDE_DIRS_SINGLE_QUOTED = " ++ unwords wrappedIncludeDirs,
Ian Lynagh's avatar
Ian Lynagh committed
438 439
                variablePrefix ++ "_DEP_CC_OPTS = "                    ++ unwords (forDeps Installed.ccOptions),
                variablePrefix ++ "_DEP_LIB_DIRS_SINGLE_QUOTED = "     ++ unwords wrappedLibraryDirs,
440
                variablePrefix ++ "_DEP_LIB_DIRS_SEARCHPATH = "        ++ mkSearchPath libraryDirs,
441
                variablePrefix ++ "_DEP_LIB_REL_DIRS = "               ++ unwords libraryRelDirs,
442
                variablePrefix ++ "_DEP_LIB_REL_DIRS_SEARCHPATH = "    ++ mkSearchPath libraryRelDirs,
Ian Lynagh's avatar
Ian Lynagh committed
443 444 445
                variablePrefix ++ "_DEP_EXTRA_LIBS = "                 ++ unwords (forDeps Installed.extraLibraries),
                variablePrefix ++ "_DEP_LD_OPTS = "                    ++ unwords (forDeps Installed.ldOptions),
                variablePrefix ++ "_BUILD_GHCI_LIB = "                 ++ boolToYesNo (withGHCiLib lbi),
446 447 448
                "",
                -- Sometimes we need to modify the automatically-generated package-data.mk
                -- bindings in a special way for the GHC build system, so allow that here:
449
                "$(eval $(" ++ directory ++ "_PACKAGE_MAGIC))"
450
                ]
Ian Lynagh's avatar
Ian Lynagh committed
451
      writeFile (distdir ++ "/package-data.mk") $ unlines xs
452
      writeFile (distdir ++ "/haddock-prologue.txt") $
453 454
          if null (description pd) then synopsis pd
                                   else description pd
455 456 457 458 459
      unless (null dll0Modules) $
          do let dll0Mods = words dll0Modules
                 dllMods = allMods \\ dll0Mods
                 dllModSets = map unwords [dll0Mods, dllMods]
             writeFile (distdir ++ "/dll-split") $ unlines dllModSets
Ian Lynagh's avatar
Ian Lynagh committed
460 461
  where
     escape = foldr (\c xs -> if c == '#' then '\\':'#':xs else c:xs) []
462 463
     wrap = mapM wrap1
     wrap1 s
464 465
      | null s        = die ["Wrapping empty value"]
      | '\'' `elem` s = die ["Single quote in value to be wrapped:", s]
466 467 468
      -- We want to be able to assume things like <space><quote> is the
      -- start of a value, so check there are no spaces in confusing
      -- positions
469 470
      | head s == ' ' = die ["Leading space in value to be wrapped:", s]
      | last s == ' ' = die ["Trailing space in value to be wrapped:", s]
471
      | otherwise     = return ("\'" ++ s ++ "\'")
472
     mkSearchPath = intercalate [searchPathSeparator]
473 474
     boolToYesNo True = "YES"
     boolToYesNo False = "NO"