+++ /dev/null
-
-module Main (main) where
-
-import qualified Distribution.ModuleName as ModuleName
-import Distribution.PackageDescription
-import Distribution.PackageDescription.Check hiding (doesFileExist)
-import Distribution.PackageDescription.Configuration
-import Distribution.PackageDescription.Parse
-import Distribution.Simple
-import Distribution.Simple.Configure
-import Distribution.Simple.LocalBuildInfo
-import Distribution.Simple.Program
-import Distribution.Simple.Program.HcPkg
-import Distribution.Simple.Utils (defaultPackageDesc, writeFileAtomic)
-import Distribution.Simple.Build (writeAutogenFiles)
-import Distribution.Simple.Register
-import Distribution.Text
-import Distribution.Verbosity
-import qualified Distribution.InstalledPackageInfo as Installed
-import qualified Distribution.Simple.PackageIndex as PackageIndex
-
-import Data.List
-import Data.Maybe
-import System.IO
-import System.Directory
-import System.Environment
-import System.Exit
-import System.FilePath
-
-main :: IO ()
-main = do args <- getArgs
- case args of
- "hscolour" : distDir : dir : args' ->
- runHsColour distDir dir args'
- "check" : dir : [] ->
- doCheck dir
- "install" : ghc : ghcpkg : strip : topdir : directory : distDir
- : myDestDir : myPrefix : myLibdir : myDocdir
- : relocatableBuild : args' ->
- doInstall ghc ghcpkg strip topdir directory distDir
- myDestDir myPrefix myLibdir myDocdir
- relocatableBuild args'
- "configure" : args' -> case break (== "--") args' of
- (config_args, "--" : distdir : directories) ->
- mapM_ (generate config_args distdir) directories
- _ -> die syntax_error
- "sdist" : dir : distDir : [] ->
- doSdist dir distDir
- _ -> 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>...",
- " ghc-cabal hscolour <distdir> <directory> <args>..."]
-
-die :: [String] -> IO a
-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
-
-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
-
-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
-
-runHsColour :: FilePath -> FilePath -> [String] -> IO ()
-runHsColour distdir directory args
- = withCurrentDirectory directory
- $ defaultMainArgs ("hscolour" : "--builddir" : distdir : args)
-
-doInstall :: FilePath -> FilePath -> FilePath -> FilePath -> FilePath
- -> FilePath -> FilePath -> FilePath -> FilePath -> FilePath
- -> String -> [String]
- -> IO ()
-doInstall ghc ghcpkg strip topdir directory distDir
- myDestDir myPrefix myLibdir myDocdir
- relocatableBuildStr args
- = withCurrentDirectory directory $ do
- relocatableBuild <- case relocatableBuildStr of
- "YES" -> return True
- "NO" -> return False
- _ -> die ["Bad relocatableBuildStr: " ++
- show relocatableBuildStr]
- let copyArgs = ["copy", "--builddir", distDir]
- ++ (if null myDestDir
- then []
- else ["--destdir", myDestDir])
- ++ args
- regArgs = "register" : "--builddir" : distDir : args
- copyHooks = userHooks {
- copyHook = noGhcPrimHook
- $ modHook False
- $ copyHook userHooks
- }
- regHooks = userHooks {
- regHook = modHook relocatableBuild
- $ regHook userHooks
- }
-
- defaultMainWithHooksArgs copyHooks copyArgs
- defaultMainWithHooksArgs regHooks regArgs
- where
- noGhcPrimHook f pd lbi us flags
- = let pd'
- | 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
- in f pd' lbi us flags
- modHook relocatableBuild f pd lbi us flags
- = do let verbosity = normal
- idts = installDirTemplates lbi
- 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"
- }
- progs = withPrograms lbi
- ghcProg = ConfiguredProgram {
- programId = programName ghcProgram,
- programVersion = Nothing,
- programDefaultArgs = ["-B" ++ topdir],
- programOverrideArgs = [],
- programLocation = UserSpecified ghc
- }
- ghcpkgconf = topdir </> "package.conf.d"
- ghcPkgProg = ConfiguredProgram {
- programId = programName ghcPkgProgram,
- programVersion = Nothing,
- programDefaultArgs = ["--global-conf",
- ghcpkgconf]
- ++ if not (null myDestDir)
- then ["--force"]
- else [],
- programOverrideArgs = [],
- programLocation = UserSpecified ghcpkg
- }
- stripProg = ConfiguredProgram {
- programId = programName stripProgram,
- programVersion = Nothing,
- programDefaultArgs = [],
- programOverrideArgs = [],
- programLocation = UserSpecified strip
- }
- progs' = updateProgram ghcProg
- $ updateProgram ghcPkgProg
- $ updateProgram stripProg
- progs
- instInfos <- dump verbosity ghcPkgProg GlobalPackageDB
- let installedPkgs' = PackageIndex.fromList instInfos
- let mlc = libraryConfig lbi
- mlc' = case mlc of
- Just lc ->
- let cipds = componentPackageDeps lc
- cipds' = [ (fixupPackageId instInfos ipid, pid)
- | (ipid,pid) <- cipds ]
- in Just $ lc {
- componentPackageDeps = cipds'
- }
- Nothing -> Nothing
- lbi' = lbi {
- libraryConfig = mlc',
- installedPkgs = installedPkgs',
- installDirTemplates = idts',
- withPrograms = progs'
- }
- f pd lbi' us flags
-
--- 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)
- | "builtin_" `isPrefixOf` ipi = x
-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
-
-generate :: [String] -> FilePath -> FilePath -> IO ()
-generate config_args distdir directory
- = withCurrentDirectory directory
- $ do let verbosity = normal
- -- 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)
- runDefaultMain
-
- lbi <- getPersistBuildConfig distdir
- let pd0 = localPkgDescr lbi
-
- hooked_bi <-
- if (buildType pd0 == Just Configure) || (buildType pd0 == Just Custom)
- 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
- case (library pd, libraryConfig lbi) of
- (Nothing, Nothing) -> return ()
- (Just lib, Just 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 = ["../" ++ display (packageId pd)]
- }
- content = Installed.showInstalledPackageInfo final_ipi ++ "\n"
- writeFileAtomic (distdir </> "inplace-pkg-config") content
- _ -> error "Inconsistent lib components; can't happen?"
-
- let
- libBiModules lib = (libBuildInfo lib, libModules lib)
- exeBiModules exe = (buildInfo exe, ModuleName.main : exeModules exe)
- 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 =
- case PackageIndex.lookupPackageName index (PackageName "rts") of
- [(_,[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.
- _ -> error "No (or multiple) ghc rts package is registered!!"
-
- dep_ids = map snd (externalPackageDeps lbi)
-
- let variablePrefix = directory ++ '_':distdir
- let xs = [variablePrefix ++ "_VERSION = " ++ display (pkgVersion (package pd)),
- variablePrefix ++ "_MODULES = " ++ unwords (map display modules),
- variablePrefix ++ "_HIDDEN_MODULES = " ++ unwords (map display (otherModules bi)),
- variablePrefix ++ "_SYNOPSIS =" ++ synopsis pd,
- variablePrefix ++ "_HS_SRC_DIRS = " ++ unwords (hsSourceDirs bi),
- variablePrefix ++ "_DEPS = " ++ unwords (map display dep_ids),
- variablePrefix ++ "_DEP_NAMES = " ++ unwords (map (display . packageName) dep_ids),
- 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),
- variablePrefix ++ "_CMM_SRCS = $(addprefix cbits/,$(notdir $(wildcard " ++ directory ++ "/cbits/*.cmm)))",
- variablePrefix ++ "_DATA_FILES = " ++ unwords (dataFiles pd),
- -- XXX This includes things it shouldn't, like:
- -- -odir dist-bootstrapping/build
- variablePrefix ++ "_HC_OPTS = " ++ escape (unwords
- ( programDefaultArgs ghcProg
- ++ hcOptions GHC bi
- ++ extensionsToFlags (compiler lbi) (usedExtensions bi)
- ++ programOverrideArgs ghcProg)),
- variablePrefix ++ "_CC_OPTS = " ++ unwords (ccOptions bi),
- variablePrefix ++ "_CPP_OPTS = " ++ unwords (cppOptions bi),
- variablePrefix ++ "_LD_OPTS = " ++ unwords (ldOptions bi),
- variablePrefix ++ "_DEP_INCLUDE_DIRS = " ++ unwords (wrap $ forDeps Installed.includeDirs),
- variablePrefix ++ "_DEP_CC_OPTS = " ++ unwords (forDeps Installed.ccOptions),
- variablePrefix ++ "_DEP_LIB_DIRS = " ++ unwords (wrap $ forDeps Installed.libraryDirs),
- variablePrefix ++ "_DEP_EXTRA_LIBS = " ++ unwords (forDeps Installed.extraLibraries),
- variablePrefix ++ "_DEP_LD_OPTS = " ++ unwords (forDeps Installed.ldOptions),
- variablePrefix ++ "_BUILD_GHCI_LIB = " ++ boolToYesNo (withGHCiLib lbi)]
- writeFile (distdir ++ "/package-data.mk") $ unlines xs
- writeFile (distdir ++ "/haddock-prologue.txt") $
- if null (description pd) then synopsis pd
- else description pd
- where
- escape = foldr (\c xs -> if c == '#' then '\\':'#':xs else c:xs) []
- wrap = map (\s -> "\'" ++ s ++ "\'")
- boolToYesNo True = "YES"
- boolToYesNo False = "NO"