summaryrefslogtreecommitdiff
path: root/compiler/Setup.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/Setup.hs')
-rw-r--r--compiler/Setup.hs129
1 files changed, 129 insertions, 0 deletions
diff --git a/compiler/Setup.hs b/compiler/Setup.hs
new file mode 100644
index 0000000000..d7c5ed2b04
--- /dev/null
+++ b/compiler/Setup.hs
@@ -0,0 +1,129 @@
+{-# LANGUAGE RecordWildCards #-}
+module Main where
+
+import Distribution.Simple
+import Distribution.Simple.BuildPaths
+import Distribution.Types.LocalBuildInfo
+import Distribution.Verbosity
+import Distribution.Simple.Program
+
+import System.IO
+import System.Process
+import System.Directory
+import System.FilePath
+import Control.Monad
+import Data.Char
+import GHC.ResponseFile
+
+main :: IO ()
+main = defaultMainWithHooks ghcHooks
+ where
+ ghcHooks = simpleUserHooks
+ { buildHook = \pd lbi uh bf -> do
+ ghcAutogen lbi
+ buildHook simpleUserHooks pd lbi uh bf
+ }
+
+-- Mapping from primop-*.hs-incl file to command
+primopIncls :: [(String,String)]
+primopIncls =
+ [ ("primop-data-decl.hs-incl" , "--data-decl")
+ , ("primop-tag.hs-incl" , "--primop-tag")
+ , ("primop-list.hs-incl" , "--primop-list")
+ , ("primop-has-side-effects.hs-incl" , "--has-side-effects")
+ , ("primop-out-of-line.hs-incl" , "--out-of-line")
+ , ("primop-commutable.hs-incl" , "--commutable")
+ , ("primop-code-size.hs-incl" , "--code-size")
+ , ("primop-can-fail.hs-incl" , "--can-fail")
+ , ("primop-strictness.hs-incl" , "--strictness")
+ , ("primop-fixity.hs-incl" , "--fixity")
+ , ("primop-primop-info.hs-incl" , "--primop-primop-info")
+ , ("primop-vector-uniques.hs-incl" , "--primop-vector-uniques")
+ , ("primop-vector-tys.hs-incl" , "--primop-vector-tys")
+ , ("primop-vector-tys-exports.hs-incl", "--primop-vector-tys-exports")
+ , ("primop-vector-tycons.hs-incl" , "--primop-vector-tycons")
+ , ("primop-docs.hs-incl" , "--wired-in-docs")
+ ]
+
+ghcAutogen :: LocalBuildInfo -> IO ()
+ghcAutogen lbi@LocalBuildInfo{..} = do
+ -- Get compiler/ root directory from the cabal file
+ let Just compilerRoot = takeDirectory <$> pkgDescrFile
+
+ -- Require the necessary programs
+ (gcc ,withPrograms) <- requireProgram normal gccProgram withPrograms
+ (ghc ,withPrograms) <- requireProgram normal ghcProgram withPrograms
+ (ghcPkg,withPrograms) <- requireProgram normal ghcPkgProgram withPrograms
+
+ -- Get compiler settings
+ settings <- read <$> getProgramOutput normal ghc ["--info"]
+ rtsInclude <- filter (not . isSpace)
+ <$> getProgramOutput normal ghcPkg ["--simple-output","--expand-pkgroot","field","rts","include-dirs"]
+
+ -- Write primop-*.hs-incl
+ let hsCppOpts = case lookup "Haskell CPP flags" settings of
+ Just fs -> unescapeArgs fs
+ Nothing -> []
+ primopsTxtPP = compilerRoot </> "GHC/Builtin/primops.txt.pp"
+ cppOpts = hsCppOpts ++ ["-P","-x","c"]
+ cppIncludes = map ("-I"++) [compilerRoot, rtsInclude]
+ -- Preprocess primops.txt.pp
+ primopsStr <- getProgramOutput normal gcc (cppOpts ++ cppIncludes ++ [primopsTxtPP])
+ -- Call genprimopcode to generate *.hs-incl
+ forM_ primopIncls $ \(file,command) -> do
+ contents <- readProcess "genprimopcode" [command] primopsStr
+ writeFile (buildDir </> file) contents
+
+ -- Write GHC.Platform.Constants
+ let platformConstantsPath = autogenPackageModulesDir lbi </> "GHC/Platform/Constants.hs"
+ targetOS = case lookup "target os" settings of
+ Nothing -> error "no target os in settings"
+ Just os -> os
+ createDirectoryIfMissing True (takeDirectory platformConstantsPath)
+ callProcess "deriveConstants" ["--gen-haskell-type","-o",platformConstantsPath,"--target-os",targetOS]
+
+ -- Write GHC.Settings.Config
+ let configHsPath = autogenPackageModulesDir lbi </> "GHC/Settings/Config.hs"
+ configHs = generateConfigHs settings
+ createDirectoryIfMissing True (takeDirectory configHsPath)
+ writeFile configHsPath configHs
+
+
+generateConfigHs :: [(String,String)] -> String
+generateConfigHs settings = either error id $ do
+ let getSetting k = case lookup k settings of
+ Nothing -> Left (show k ++ " not found in settings")
+ Just v -> Right v
+ buildPlatform <- getSetting "Host platform"
+ hostPlatform <- getSetting "Target platform"
+ cProjectName <- getSetting "Project name"
+ cBooterVersion <- getSetting "Project version"
+ return $ unlines
+ [ "module GHC.Settings.Config"
+ , " ( module GHC.Version"
+ , " , cBuildPlatformString"
+ , " , cHostPlatformString"
+ , " , cProjectName"
+ , " , cBooterVersion"
+ , " , cStage"
+ , " ) where"
+ , ""
+ , "import GHC.Prelude"
+ , ""
+ , "import GHC.Version"
+ , ""
+ , "cBuildPlatformString :: String"
+ , "cBuildPlatformString = " ++ show buildPlatform
+ , ""
+ , "cHostPlatformString :: String"
+ , "cHostPlatformString = " ++ show hostPlatform
+ , ""
+ , "cProjectName :: String"
+ , "cProjectName = " ++ show cProjectName
+ , ""
+ , "cBooterVersion :: String"
+ , "cBooterVersion = " ++ show cBooterVersion
+ , ""
+ , "cStage :: String"
+ , "cStage = show (2 :: Int)"
+ ]