Main.hs 23 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.Package
10
import Distribution.System
Ian Lynagh's avatar
Ian Lynagh committed
11 12 13
import Distribution.Simple
import Distribution.Simple.Configure
import Distribution.Simple.LocalBuildInfo
14
import Distribution.Simple.GHC
Ian Lynagh's avatar
Ian Lynagh committed
15
import Distribution.Simple.Program
Ian Lynagh's avatar
Ian Lynagh committed
16
import Distribution.Simple.Program.HcPkg
17
import Distribution.Simple.Setup (ConfigFlags(configStripLibs), fromFlag, toFlag)
18
import Distribution.Simple.Utils (defaultPackageDesc, writeFileAtomic, toUTF8)
Ian Lynagh's avatar
Ian Lynagh committed
19
import Distribution.Simple.Build (writeAutogenFiles)
Ian Lynagh's avatar
Ian Lynagh committed
20
import Distribution.Simple.Register
Ian Lynagh's avatar
Ian Lynagh committed
21 22 23 24 25
import Distribution.Text
import Distribution.Verbosity
import qualified Distribution.InstalledPackageInfo as Installed
import qualified Distribution.Simple.PackageIndex as PackageIndex

zudov's avatar
zudov committed
26
import Control.Exception (bracket)
pcapriotti's avatar
pcapriotti committed
27
import Control.Monad
ian@well-typed.com's avatar
ian@well-typed.com committed
28
import qualified Data.ByteString.Lazy.Char8 as BS
29
import Data.List
Ian Lynagh's avatar
Ian Lynagh committed
30 31
import Data.Maybe
import System.IO
32
import System.Directory (setCurrentDirectory, getCurrentDirectory, doesFileExist)
Ian Lynagh's avatar
Ian Lynagh committed
33
import System.Environment
34
import System.Exit      (exitWith, ExitCode(..))
Ian Lynagh's avatar
Ian Lynagh committed
35 36 37
import System.FilePath

main :: IO ()
38 39
main = do hSetBuffering stdout LineBuffering
          args <- getArgs
Ian Lynagh's avatar
Ian Lynagh committed
40
          case args of
ian@well-typed.com's avatar
ian@well-typed.com committed
41 42
              "hscolour" : dir : distDir : args' ->
                  runHsColour dir distDir args'
43 44
              "check" : dir : [] ->
                  doCheck dir
ian@well-typed.com's avatar
ian@well-typed.com committed
45 46
              "copy" : dir : distDir
                     : strip : myDestDir : myPrefix : myLibdir : myDocdir
47
                     : ghcLibWays : args' ->
ian@well-typed.com's avatar
ian@well-typed.com committed
48 49
                  doCopy dir distDir
                         strip myDestDir myPrefix myLibdir myDocdir
50
                         ("dyn" `elem` words ghcLibWays)
51
                         args'
ian@well-typed.com's avatar
ian@well-typed.com committed
52
              "register" : dir : distDir : ghc : ghcpkg : topdir
53 54
                         : myDestDir : myPrefix : myLibdir : myDocdir
                         : relocatableBuild : args' ->
ian@well-typed.com's avatar
ian@well-typed.com committed
55
                  doRegister dir distDir ghc ghcpkg topdir
56 57
                             myDestDir myPrefix myLibdir myDocdir
                             relocatableBuild args'
58 59
              "configure" : dir : distDir : dll0Modules : config_args ->
                  generate dir distDir dll0Modules config_args
60 61
              "sdist" : dir : distDir : [] ->
                  doSdist dir distDir
62 63
              ["--version"] ->
                  defaultMainArgs ["--version"]
Ian Lynagh's avatar
Ian Lynagh committed
64 65 66 67 68 69
              _ -> 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>...",
70
     "        ghc-cabal hscolour <distdir> <directory> <args>..."]
Ian Lynagh's avatar
Ian Lynagh committed
71

72
die :: [String] -> IO a
Ian Lynagh's avatar
Ian Lynagh committed
73 74 75 76 77
die errs = do mapM_ (hPutStrLn stderr) errs
              exitWith (ExitFailure 1)

withCurrentDirectory :: FilePath -> IO a -> IO a
withCurrentDirectory directory io
zudov's avatar
zudov committed
78 79
 = bracket (getCurrentDirectory) (setCurrentDirectory)
           (const (setCurrentDirectory directory >> io))
Ian Lynagh's avatar
Ian Lynagh committed
80 81 82 83 84 85 86

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

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
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

111 112 113 114 115 116
doCheck :: FilePath -> IO ()
doCheck directory
 = withCurrentDirectory directory
 $ do let verbosity = normal
      gpdFile <- defaultPackageDesc verbosity
      gpd <- readPackageDescription verbosity gpdFile
117 118 119
      case filter isFailure $ checkPackage gpd Nothing of
          []   -> return ()
          errs -> mapM_ print errs >> exitWith (ExitFailure 1)
120
    where isFailure (PackageDistSuspicious {}) = False
121
          isFailure (PackageDistSuspiciousWarn {}) = False
122 123
          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
doCopy :: FilePath -> FilePath
130
       -> FilePath -> FilePath -> FilePath -> FilePath -> FilePath -> Bool
131 132
       -> [String]
       -> IO ()
ian@well-typed.com's avatar
ian@well-typed.com committed
133
doCopy directory distDir
134
       strip myDestDir myPrefix myLibdir myDocdir withSharedLibs
ian@well-typed.com's avatar
ian@well-typed.com committed
135
       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
                     | packageName pd == PackageName "ghc-prim" =
Edward Z. Yang's avatar
Edward Z. Yang committed
153 154
                        case libraries pd of
                        [lib] ->
Ian Lynagh's avatar
Ian Lynagh committed
155 156 157
                            let ghcPrim = fromJust (simpleParse "GHC.Prim")
                                ems = filter (ghcPrim /=) (exposedModules lib)
                                lib' = lib { exposedModules = ems }
Edward Z. Yang's avatar
Edward Z. Yang committed
158 159
                            in pd { libraries = [lib'] }
                        [] ->
Ian Lynagh's avatar
Ian Lynagh committed
160
                            error "Expected a library, but none found"
Edward Z. Yang's avatar
Edward Z. Yang committed
161 162
                        _ ->
                            error "Expected a single library, but multiple found"
Ian Lynagh's avatar
Ian Lynagh committed
163
                     | otherwise = pd
164
                in f pd' lbi us flags
165
      modHook relocatableBuild f pd lbi us flags
Ian Lynagh's avatar
Ian Lynagh committed
166
       = do let verbosity = normal
167 168 169 170 171
                idts = updateInstallDirTemplates relocatableBuild
                                                 myPrefix myLibdir myDocdir
                                                 (installDirTemplates lbi)
                progs = withPrograms lbi
                stripProgram' = stripProgram {
172
                    programFindLocation = \_ _ -> return (Just (strip,[])) }
173 174 175 176

            progs' <- configureProgram verbosity stripProgram' progs
            let lbi' = lbi {
                               withPrograms = progs',
177
                               installDirTemplates = idts,
178 179
                               configFlags = cfg,
                               stripLibs = fromFlag (configStripLibs cfg),
180
                               withSharedLib = withSharedLibs
181
                           }
182 183 184 185 186 187 188

                -- This hack allows to interpret the "strip"
                -- command-line argument being set to ':' to signify
                -- disabled library stripping
                cfg | strip == ":" = (configFlags lbi) { configStripLibs = toFlag False }
                    | otherwise    = configFlags lbi

189 190 191 192 193 194
            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
195
doRegister directory distDir ghc ghcpkg topdir
196
           myDestDir myPrefix myLibdir myDocdir
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
           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
217
                progs = withPrograms lbi
218
                ghcpkgconf = topdir </> "package.conf.d"
pcapriotti's avatar
pcapriotti committed
219
                ghcProgram' = ghcProgram {
220
                    programPostConf = \_ cp -> return cp { programDefaultArgs = ["-B" ++ topdir] },
221
                    programFindLocation = \_ _ -> return (Just (ghc,[])) }
pcapriotti's avatar
pcapriotti committed
222
                ghcPkgProgram' = ghcPkgProgram {
223 224 225
                    programPostConf = \_ cp -> return cp { programDefaultArgs =
                                                                ["--global-package-db", ghcpkgconf]
                                                                ++ ["--force" | not (null myDestDir) ] },
226
                    programFindLocation = \_ _ -> return (Just (ghcpkg,[])) }
pcapriotti's avatar
pcapriotti committed
227 228
                configurePrograms ps conf = foldM (flip (configureProgram verbosity)) conf ps

229
            progs' <- configurePrograms [ghcProgram', ghcPkgProgram'] progs
230
            instInfos <- dump (hcPkgInfo progs') verbosity GlobalPackageDB
231
            let installedPkgs' = PackageIndex.fromList instInfos
232
            let lbi' = lbi {
Ian Lynagh's avatar
Ian Lynagh committed
233
                               installedPkgs = installedPkgs',
234
                               installDirTemplates = idts,
Ian Lynagh's avatar
Ian Lynagh committed
235 236 237 238
                               withPrograms = progs'
                           }
            f pd lbi' us flags

239 240 241 242 243 244 245 246 247 248 249 250 251
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,
252
          libsubdir = toPathTemplate "$libname",
253 254 255 256 257 258 259
          docdir    = toPathTemplate $
                          if relocatableBuild
                          then "$topdir/../doc/html/libraries/$pkgid"
                          else (myDocdir </> "$pkgid"),
          htmldir   = toPathTemplate "$docdir"
      }

260 261 262
-- 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.
263 264 265
mangleIPI :: FilePath -> FilePath -> LocalBuildInfo
          -> Installed.InstalledPackageInfo -> Installed.InstalledPackageInfo
mangleIPI "compiler" "stage2" lbi ipi
266
 | isWindows =
267 268 269 270 271 272 273 274
    -- Cabal currently only ever installs ONE Haskell library, c.f.
    -- the code in Cabal.Distribution.Simple.Register.  If it
    -- ever starts installing more we'll have to find the
    -- library that's too big and split that.
    let [old_hslib] = Installed.hsLibraries ipi
    in ipi {
        Installed.hsLibraries = [old_hslib, old_hslib ++ "-0"]
    }
275 276 277
    where isWindows = case hostPlatform lbi of
                      Platform _ Windows -> True
                      _                  -> False
278
mangleIPI _ _ _ ipi = ipi
279

280 281
generate :: FilePath -> FilePath -> String -> [String] -> IO ()
generate directory distdir dll0Modules config_args
Ian Lynagh's avatar
Ian Lynagh committed
282
 = withCurrentDirectory directory
Ian Lynagh's avatar
Ian Lynagh committed
283
 $ do let verbosity = normal
Ian Lynagh's avatar
Ian Lynagh committed
284 285 286
      -- 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
287
      withArgs (["configure", "--distdir", distdir, "--ipid", "$pkg-$version"] ++ config_args)
288
               runDefaultMain
Ian Lynagh's avatar
Ian Lynagh committed
289

290 291
      lbi <- getPersistBuildConfig distdir
      let pd0 = localPkgDescr lbi
292 293

      writePersistBuildConfig distdir lbi
Ian Lynagh's avatar
Ian Lynagh committed
294 295

      hooked_bi <-
Ian Lynagh's avatar
Ian Lynagh committed
296
           if (buildType pd0 == Just Configure) || (buildType pd0 == Just Custom)
Ian Lynagh's avatar
Ian Lynagh committed
297 298 299 300 301 302 303 304 305 306 307
           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
Edward Z. Yang's avatar
Edward Z. Yang committed
308 309
      withAllComponentsInBuildOrder pd lbi $ \_ clbi ->
        writeAutogenFiles verbosity pd lbi clbi
Ian Lynagh's avatar
Ian Lynagh committed
310 311

      -- generate inplace-pkg-config
ian@well-typed.com's avatar
ian@well-typed.com committed
312 313
      withLibLBI pd lbi $ \lib clbi ->
          do cwd <- getCurrentDirectory
314
             let ipid = mkUnitId (display (packageId pd))
ian@well-typed.com's avatar
ian@well-typed.com committed
315
             let installedPkgInfo = inplaceInstalledPackageInfo cwd distdir
316
                                        pd (AbiHash "") lib lbi clbi
317
                 final_ipi = mangleIPI directory distdir lbi $ installedPkgInfo {
318 319
                                 Installed.installedUnitId = ipid,
                                 Installed.compatPackageKey = display (packageId pd),
ian@well-typed.com's avatar
ian@well-typed.com committed
320 321 322 323
                                 Installed.haddockHTMLs = []
                             }
                 content = Installed.showInstalledPackageInfo final_ipi ++ "\n"
             writeFileAtomic (distdir </> "inplace-pkg-config") (BS.pack $ toUTF8 content)
Ian Lynagh's avatar
Ian Lynagh committed
324 325

      let
326
          comp = compiler lbi
Ian Lynagh's avatar
Ian Lynagh committed
327 328
          libBiModules lib = (libBuildInfo lib, libModules lib)
          exeBiModules exe = (buildInfo exe, ModuleName.main : exeModules exe)
Edward Z. Yang's avatar
Edward Z. Yang committed
329
          biModuless = (map libBiModules $ libraries pd)
Ian Lynagh's avatar
Ian Lynagh committed
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
                    ++ (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 =
354
            case PackageIndex.lookupPackageName index (PackageName "rts") of
355 356 357 358 359 360 361 362 363 364
              [(_,[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
365 366
              _ -> error "No (or multiple) ghc rts package is registered!!"

367 368
          dep_ids  = map snd (externalPackageDeps lbi)
          deps     = map display dep_ids
369
          dep_direct = map (fromMaybe (error "ghc-cabal: dep_keys failed")
370
                           . PackageIndex.lookupUnitId
371 372 373 374
                                            (installedPkgs lbi)
                           . fst)
                       . externalPackageDeps
                       $ lbi
375
          dep_ipids = map (display . Installed.installedUnitId) dep_direct
376
          depLibNames
377
            | packageKeySupported comp = dep_ipids
378
            | otherwise = deps
379
          depNames = map (display . packageName) dep_ids
380

381
          transitive_dep_ids = map Installed.sourcePackageId dep_pkgs
382
          transitiveDeps = map display transitive_dep_ids
383
          transitiveDepLibNames
384
            | packageKeySupported comp = map fixupRtsLibName transitiveDeps
385
            | otherwise = transitiveDeps
386 387
          fixupRtsLibName "rts-1.0" = "rts"
          fixupRtsLibName x = x
388 389 390 391 392 393 394 395 396 397
          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
398
      wrappedIncludeDirs <- wrap $ forDeps Installed.includeDirs
399
      wrappedLibraryDirs <- wrap libraryDirs
400

Ian Lynagh's avatar
Ian Lynagh committed
401
      let variablePrefix = directory ++ '_':distdir
402 403 404
          mods      = map display modules
          otherMods = map display (otherModules bi)
          allMods = mods ++ otherMods
Ian Lynagh's avatar
Ian Lynagh committed
405
      let xs = [variablePrefix ++ "_VERSION = " ++ display (pkgVersion (package pd)),
406
                -- TODO: move inside withLibLBI
407
                variablePrefix ++ "_COMPONENT_ID = " ++ localCompatPackageKey lbi,
408 409
                variablePrefix ++ "_MODULES = " ++ unwords mods,
                variablePrefix ++ "_HIDDEN_MODULES = " ++ unwords otherMods,
410
                variablePrefix ++ "_SYNOPSIS =" ++ (unwords $ lines $ synopsis pd),
Ian Lynagh's avatar
Ian Lynagh committed
411
                variablePrefix ++ "_HS_SRC_DIRS = " ++ unwords (hsSourceDirs bi),
412
                variablePrefix ++ "_DEPS = " ++ unwords deps,
413
                variablePrefix ++ "_DEP_IPIDS = " ++ unwords dep_ipids,
414
                variablePrefix ++ "_DEP_NAMES = " ++ unwords depNames,
415
                variablePrefix ++ "_DEP_COMPONENT_IDS = " ++ unwords depLibNames,
416
                variablePrefix ++ "_TRANSITIVE_DEP_NAMES = " ++ unwords transitiveDepNames,
417
                variablePrefix ++ "_TRANSITIVE_DEP_COMPONENT_IDS = " ++ unwords transitiveDepLibNames,
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 453

      writeFileUtf8 (distdir ++ "/haddock-prologue.txt") $
454 455
          if null (description pd) then synopsis pd
                                   else description pd
456 457 458 459 460
      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
461 462
  where
     escape = foldr (\c xs -> if c == '#' then '\\':'#':xs else c:xs) []
463 464
     wrap = mapM wrap1
     wrap1 s
465 466
      | null s        = die ["Wrapping empty value"]
      | '\'' `elem` s = die ["Single quote in value to be wrapped:", s]
467 468 469
      -- 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
470 471
      | head s == ' ' = die ["Leading space in value to be wrapped:", s]
      | last s == ' ' = die ["Trailing space in value to be wrapped:", s]
472
      | otherwise     = return ("\'" ++ s ++ "\'")
473
     mkSearchPath = intercalate [searchPathSeparator]
474 475
     boolToYesNo True = "YES"
     boolToYesNo False = "NO"
476 477 478 479 480

     -- | Version of 'writeFile' that always uses UTF8 encoding
     writeFileUtf8 f txt = withFile f WriteMode $ \hdl -> do
         hSetEncoding hdl utf8
         hPutStr hdl txt