module Development.Shake.Language.C.Target.NaCl (
pepper
, canary
, target
, Config(..)
, toolChain
, finalize
, translate
, Executable(..)
, Program(..)
, mk_nmf
) where
import Development.Shake
import Development.Shake.FilePath
import Data.Version (Version(..))
import Development.Shake.Language.C hiding (Arch)
import qualified Development.Shake.Language.C.Target as C
import Development.Shake.Language.C.ToolChain
import qualified Development.Shake.Language.C.Host as Host
import Development.Shake.Language.C.Label
pepper :: Int -> Version
pepper apiVersion = Version [apiVersion] []
canary :: Version
canary = Version [] ["canary"]
target :: Target
target = Target Pepper (Platform "pepper") LLVM_IR
hostString :: String
hostString =
case Host.os of
Host.Linux -> "linux"
Host.OSX -> "mac"
Host.Windows -> "win"
data Config = Debug | Release deriving (Eq, Show)
toolChain :: FilePath
-> Version
-> Config
-> Target
-> ToolChain
toolChain sdk sdkVersion config t =
set variant LLVM
$ set toolDirectory (Just (platformDir </> "toolchain" </> hostString ++ "_" ++ "pnacl" </> "bin"))
$ set toolPrefix "pnacl-"
$ set compilerCommand "clang"
$ set archiverCommand "ar"
$ set archiver (\tc flags inputs output -> do
need inputs
command_ [] (tool tc archiverCommand)
$ ["cr"]
++ get archiverFlags flags
++ [output]
++ inputs
command_ [] (toolFromString tc "ranlib") [output]
)
$ set linkerCommand "clang++"
$ set defaultBuildFlags
( return $
append systemIncludes [includeDir]
. append userIncludes [includeDir]
. append systemIncludes [includeDir </> "pnacl"]
. append libraryPath [platformDir </> "lib" </> "pnacl" </> show config] )
$ defaultToolChain
where
platformDir =
sdk
</> platformName (targetPlatform t)
++ "_"
++ case versionTags sdkVersion of
["canary"] -> "canary"
_ -> show $ head (versionBranch sdkVersion)
includeDir = platformDir </> "include"
finalize :: ToolChain
-> FilePath
-> FilePath
-> Action ()
finalize tc input output = do
need [input]
command_ [] (toolFromString tc "finalize")
["-o", output, input]
translate :: ToolChain -> C.Arch -> FilePath -> FilePath -> Action ()
translate tc arch input output = do
let archName =
case arch of
X86 I686 -> "i686"
X86 X86_64 -> "x86-64"
Arm Armv7 -> "armv7"
_ -> error $ "Unsupported architecture: " ++ show arch
need [input]
command_ [] (toolFromString tc "finalize")
["-arch", archName, "-o", output, input]
data Executable = Executable {
executablePath :: FilePath
, optimizationLevel :: Maybe Int
} deriving (Eq, Show)
data Program = Program {
pnaclTranslate :: Executable
, pnaclDebug :: Maybe Executable
} deriving (Eq, Show)
mk_nmf :: Program
-> FilePath
-> Action ()
mk_nmf program output = do
need $ [executablePath (pnaclTranslate program)]
++ maybe [] ((:[]).executablePath) (pnaclDebug program)
writeFileChanged output . unlines $ [
"{"
, " \"program\": {"
, " \"portable\": {"
]
++ entry "pnacl-translate" (pnaclTranslate program)
++ maybe [] (\e -> [","] ++ entry "pnacl-debug" e) (pnaclDebug program)
++
[ " }"
, " }"
, "}"
]
where
entry what prog = [
" \"" ++ what ++ "\": {"
, " \"url\": \"" ++ makeRelative (takeDirectory output) (executablePath prog) ++ "\""
] ++ maybe [] (\n ->
[" , \"optlevel\": " ++ show n]) (optimizationLevel prog)
++
[ " }" ]