seL4/haskell/Setup.hs
Gerwin Klein 2d4d520c77 haskell: removed Lyrebird target
Consolidating to one simulator to get simulator builds running again. The
source setup is still for multiple potential targets so it remains reasonably
easy to add different architectures like x86 to the Haskell model if needed.
2014-12-11 16:03:10 +11:00

134 lines
4.2 KiB
Haskell

#!/usr/bin/env runhaskell
{-# LANGUAGE ViewPatterns #-}
--
-- Copyright 2014, General Dynamics C4 Systems
--
-- This software may be distributed and modified according to the terms of
-- the GNU General Public License version 2. Note that NO WARRANTY is provided.
-- See "LICENSE_GPLv2.txt" for details.
--
-- @TAG(GD_GPL)
--
module Main where
import Control.Applicative((<$>))
import Distribution.Simple
import Distribution.PackageDescription
import System.Directory
import Distribution.PackageDescription.Parse
import Distribution.Verbosity
import qualified Distribution.ModuleName
import Distribution.Simple.Setup
import System.Process
import System.Exit
import System.Environment(getArgs)
import Data.List(isPrefixOf, find)
import Control.Monad(unless, liftM)
targets =
[ ("arm-qemu", ("ARM", "QEmu")) ]
bootModules =
[ "Kernel/CSpace"
, "Kernel/Thread"
, "Kernel/FaultHandler"
, "Kernel/VSpace"
, "Kernel/Init"
, "Model/PSpace"
, "Object/TCB"
, "Object/CNode"
, "Object/ObjectType"
]
platformModules =
[ "Machine.Hardware"
]
archModules =
[ "API.Types"
, "API.Invocation"
, "Kernel.VSpace"
, "Kernel.Thread"
, "Object.ObjectType"
, "Object.Structures"
, "Object.Interrupt"
, "Object.Instances"
, "Object.TCB"
, "Model.StateData"
, "Machine.RegisterSet"
, "Machine.Hardware"
]
targetModules arch platform =
(map (\a -> "SEL4." ++ a ++ "." ++ arch) archModules) ++
(map (\a -> "SEL4." ++ a ++ "." ++ arch_platform) platformModules)
where arch_platform = arch ++ "." ++ platform
ghcOptions arch platform =
[ "-DTARGET=" ++ arch
, "-DTARGET_" ++ arch
, "-DPLATFORM=" ++ platform
, "-DPLATFORM_" ++ platform
]
bootFiles = map moduleToLHSName bootModules
where
moduleToLHSName f = "src/SEL4/" ++
(map (\a -> if a == '.' then '/' else a) f) ++ ".lhs"
main :: IO ()
main = do
args <- getArgs
let targetPrefix = "--with-target="
let targetArg = find (targetPrefix `isPrefixOf`) args
let targetName = liftM (drop (length targetPrefix)) targetArg
let args' = filter (not . isPrefixOf targetPrefix) args
let hooks = simpleUserHooks {
preBuild = \args flags -> do
generateHSBoot
(preBuild simpleUserHooks) args flags,
readDesc = do
cabalfile <- generateTempCabalFile "SEL4.cabal" targetName
v <- readPackageDescription normal $ cabalfile
removeFile cabalfile
return $ Just v
}
defaultMainWithHooksArgs hooks args'
printKnownTargets :: IO ()
printKnownTargets = do
putStrLn "Recognised targets are:"
mapM_ (putStrLn.('\t':).fst) targets
generateTempCabalFile :: String -> Maybe String -> IO String
generateTempCabalFile fn targetName = do
case (do name <- targetName
(name, (arch, platform)) <- find ((==name).fst) targets
return (name, arch, platform)) of
Nothing -> do
putStrLn "Please specify a target: --with-target=<target>"
printKnownTargets
fail "No target"
Just (name, arch, platform) -> do
lns <- fmap lines $ readFile fn
writeFile (fn ++ "." ++ name) $ unlines (concatMap (f arch platform) lns)
return (fn ++ "." ++ name)
where f arch platform (span (== ' ') -> (length -> indentation, str)) | "$TARGET-SPECIFIC-STUFF" `isPrefixOf` str = generateArchSpecificLines arch platform indentation
f _ _ x = [x]
generateArchSpecificLines :: String -> String -> Int -> [String]
generateArchSpecificLines arch platform indentation =
[replicate indentation ' ' ++ "other-modules:" ++ unwords (targetModules arch platform)
,replicate indentation ' ' ++ "cpp-options:" ++ unwords (ghcOptions arch platform)]
generateHSBoot :: IO ()
generateHSBoot = mapM_ generateHSBoot' bootFiles
where
generateHSBoot' n = do
putStrLn ("Generating boot file for " ++ n)
r <- system ("perl mkhsboot.pl -l <" ++ n ++ " >"
++ n ++ "-boot")
unless (r == ExitSuccess) $ error "Couldn't generate boot file"