module DDC.Build.Builder
( BuilderConfig (..)
, BuilderHost (..)
, Builder (..)
, BuilderResult (..)
, builders
, determineDefaultBuilder
, determineDefaultBuilderHost)
where
import DDC.Build.Platform
import DDC.Base.Pretty hiding ((</>))
import Data.List
import System.FilePath
import System.Exit hiding (die)
import System.Process
import qualified DDC.Core.Salt.Platform as Llvm
data BuilderConfig
= BuilderConfig
{
builderConfigBaseSrcDir :: FilePath
, builderConfigBaseLibDir :: FilePath
, builderConfigLibFile :: FilePath -> FilePath -> FilePath }
data BuilderHost
= BuilderHost
{ builderHostLlvmVersion :: String }
data Builder
= Builder
{
builderName :: String
, buildHost :: Platform
, buildTarget :: Platform
, buildSpec :: Llvm.Platform
, buildBaseSrcDir :: FilePath
, buildBaseLibDir :: FilePath
, buildCC :: FilePath -> FilePath -> IO ()
, buildLlc :: FilePath -> FilePath -> IO ()
, buildLlvmVersion :: String
, buildAs :: FilePath -> FilePath -> IO ()
, buildLdExe :: [FilePath] -> FilePath -> IO ()
, buildLdLibStatic :: [FilePath] -> FilePath -> IO ()
, buildLdLibShared :: [FilePath] -> FilePath -> IO () }
data BuilderResult
= BuilderSuccess
| BuilderCanceled
| BuilderFailed
deriving (Show, Eq)
instance Show Builder where
show builder
= "Builder " ++ show (builderName builder)
instance Pretty Builder where
ppr builder
= vcat
[ text "Builder Name : " <> text (builderName builder)
, empty
, text "Host Platform"
, indent 1 $ ppr $ buildHost builder
, empty
, text "Target Platform"
, indent 1 $ ppr $ buildTarget builder
, empty
, text "LLVM Target Spec"
, indent 1 $ ppr $ buildSpec builder ]
builders :: BuilderConfig -> BuilderHost -> [Builder]
builders config host
= [ builder_X8632_Darwin config host Nothing
, builder_X8664_Darwin config host Nothing
, builder_X8632_Linux config host
, builder_X8664_Linux config host
, builder_PPC32_Linux config host ]
determineDefaultBuilder :: BuilderConfig -> IO (Maybe Builder)
determineDefaultBuilder config
= do mPlatform <- determineHostPlatform
mHost <- determineDefaultBuilderHost
case (mPlatform, mHost) of
(Just (Platform ArchX86_32 (OsDarwin mVersion)), Just host)
-> return $ Just (builder_X8632_Darwin config host mVersion)
(Just (Platform ArchX86_64 (OsDarwin mVersion)), Just host)
-> return $ Just (builder_X8664_Darwin config host mVersion)
(Just (Platform ArchX86_32 OsLinux), Just host)
-> return $ Just (builder_X8632_Linux config host)
(Just (Platform ArchX86_64 OsLinux), Just host)
-> return $ Just (builder_X8664_Linux config host)
(Just (Platform ArchPPC_32 OsLinux), Just host)
-> return $ Just (builder_PPC32_Linux config host)
(Just (Platform ArchX86_32 OsCygwin), Just host)
-> return $ Just (builder_X8632_Cygwin config host)
(Just (Platform ArchX86_32 OsMingw), Just host)
-> return $ Just (builder_X8632_Mingw config host)
_ -> return Nothing
determineDefaultBuilderHost :: IO (Maybe BuilderHost)
determineDefaultBuilderHost
= do
mStrLlvmVersion <- determineHostLlvmVersion Nothing
case mStrLlvmVersion of
Nothing
-> return Nothing
Just strLlvmVersion
-> return $ Just $ BuilderHost
{ builderHostLlvmVersion = strLlvmVersion }
builder_X8632_Darwin config host mVersion
= Builder
{ builderName = "x86_32-darwin"
, buildHost = Platform ArchX86_32 (OsDarwin mVersion)
, buildTarget = Platform ArchX86_32 (OsDarwin mVersion)
, buildSpec = Llvm.platform32
, buildBaseSrcDir = builderConfigBaseSrcDir config
, buildBaseLibDir = builderConfigBaseLibDir config
, buildLlvmVersion = builderHostLlvmVersion host
, buildLlc
= \llFile sFile
-> doCmd "LLVM compiler" [(2, BuilderCanceled)]
[ "opt -O3"
, llFile
, "| llc -O3 -march=x86 -relocation-model=pic"
, "-o", sFile ]
, buildCC
= \cFile oFile
-> doCmd "C compiler" [(2, BuilderCanceled)]
[ "cc -Werror -std=c99 -O3 -m32"
, "-c", cFile
, "-o", oFile
, "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"
, "-I" ++ builderConfigBaseSrcDir config </> "sea/primitive" ]
, buildAs
= \sFile oFile
-> doCmd "assembler" [(2, BuilderCanceled)]
[ "llvm-mc -arch x86 -filetype=obj"
, case mVersion of
Nothing -> ""
Just (major, _minor, _patch)
-> "-triple=x86-apple-macosx10." ++ show (major 4)
, "-o", oFile
, sFile ]
, buildLdExe
= \oFiles binFile
-> doCmd "linker" [(2, BuilderCanceled)]
[ "cc -m32 -Wl,-dead_strip"
, "-o", binFile
, intercalate " " oFiles
, builderConfigBaseLibDir config
</> builderConfigLibFile config
"libddc-runtime.a"
"libddc-runtime.dylib" ]
, buildLdLibStatic
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ ["ar r", libFile] ++ oFiles
, buildLdLibShared
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ [ "cc -m32 -dynamiclib -undefined dynamic_lookup"
, "-o", libFile ] ++ oFiles
}
builder_X8664_Darwin config host mVersion
= Builder
{ builderName = "x86_64-darwin"
, buildHost = Platform ArchX86_64 (OsDarwin mVersion)
, buildTarget = Platform ArchX86_64 (OsDarwin mVersion)
, buildSpec = Llvm.platform64
, buildBaseSrcDir = builderConfigBaseSrcDir config
, buildBaseLibDir = builderConfigBaseLibDir config
, buildLlvmVersion = builderHostLlvmVersion host
, buildLlc
= \llFile sFile
-> doCmd "LLVM compiler" [(2, BuilderCanceled)]
[ "opt -O3"
, llFile
, "| llc -O3 -march=x86-64 -relocation-model=pic"
, "-o", sFile ]
, buildCC
= \cFile oFile
-> doCmd "C compiler" [(2, BuilderCanceled)]
[ "cc -Werror -std=c99 -O3 -m64"
, "-c", cFile
, "-o", oFile
, "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"
, "-I" ++ builderConfigBaseSrcDir config </> "sea/primitive" ]
, buildAs
= \sFile oFile
-> doCmd "assembler" [(2, BuilderCanceled)]
[ "llvm-mc -filetype=obj"
, case mVersion of
Nothing -> ""
Just (major, _minor, _patch)
-> "-triple=x86_64-apple-macosx10." ++ show (major 4)
, "-o", oFile
, sFile ]
, buildLdExe
= \oFiles binFile
-> doCmd "linker" [(2, BuilderCanceled)]
[ "cc -m64 -Wl,-dead_strip"
, "-o", binFile
, intercalate " " oFiles
, builderConfigBaseLibDir config
</> builderConfigLibFile config
"libddc-runtime.a"
"libddc-runtime.dylib" ]
, buildLdLibStatic
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ ["ar r", libFile] ++ oFiles
, buildLdLibShared
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ [ "cc -m64 -dynamiclib -undefined dynamic_lookup"
, "-o", libFile ] ++ oFiles
}
builder_X8632_Linux config host
= Builder
{ builderName = "x86_32-linux"
, buildHost = Platform ArchX86_32 OsLinux
, buildTarget = Platform ArchX86_32 OsLinux
, buildSpec = Llvm.platform32
, buildBaseSrcDir = builderConfigBaseSrcDir config
, buildBaseLibDir = builderConfigBaseLibDir config
, buildLlvmVersion = builderHostLlvmVersion host
, buildLlc
= \llFile sFile
-> doCmd "LLVM compiler" [(2, BuilderCanceled)]
[ "llc -O3 -march=x86 -relocation-model=pic"
, llFile
, "-o", sFile ]
, buildCC
= \cFile oFile
-> doCmd "C compiler" [(2, BuilderCanceled)]
[ "gcc -Werror -std=c99 -O3 -m32 -fPIC"
, "-c", cFile
, "-o", oFile
, "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"
, "-I" ++ builderConfigBaseSrcDir config </> "sea/primitive" ]
, buildAs
= \sFile oFile
-> doCmd "assembler" [(2, BuilderCanceled)]
[ "as --32"
, "-o", oFile
, sFile ]
, buildLdExe
= \oFiles binFile
-> doCmd "linker" [(2, BuilderCanceled)]
[ "gcc -m32"
, "-o", binFile
, intercalate " " oFiles
, builderConfigBaseLibDir config
</> builderConfigLibFile config
"libddc-runtime.a"
"libddc-runtime.so" ]
, buildLdLibStatic
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ ["ar r", libFile] ++ oFiles
, buildLdLibShared
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ [ "gcc -shared", "-o", libFile ] ++ oFiles
}
builder_X8664_Linux config host
= Builder
{ builderName = "x86_64-linux"
, buildHost = Platform ArchX86_64 OsLinux
, buildTarget = Platform ArchX86_64 OsLinux
, buildSpec = Llvm.platform64
, buildBaseSrcDir = builderConfigBaseSrcDir config
, buildBaseLibDir = builderConfigBaseLibDir config
, buildLlvmVersion = builderHostLlvmVersion host
, buildLlc
= \llFile sFile
-> doCmd "LLVM compiler" [(2, BuilderCanceled)]
[ "llc -O3 -march=x86-64 -relocation-model=pic"
, llFile
, "-o", sFile ]
, buildCC
= \cFile oFile
-> doCmd "C compiler" [(2, BuilderCanceled)]
[ "gcc -Werror -std=c99 -O3 -m64 -fPIC"
, "-c", cFile
, "-o", oFile
, "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"
, "-I" ++ builderConfigBaseSrcDir config </> "sea/primitive" ]
, buildAs
= \sFile oFile
-> doCmd "assembler" [(2, BuilderCanceled)]
[ "as --64"
, "-o", oFile
, sFile ]
, buildLdExe
= \oFiles binFile
-> doCmd "linker" [(2, BuilderCanceled)]
[ "gcc -m64"
, "-o", binFile
, intercalate " " oFiles
, builderConfigBaseLibDir config
</> builderConfigLibFile config
"libddc-runtime.a"
"libddc-runtime.so" ]
, buildLdLibStatic
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ ["ar r", libFile] ++ oFiles
, buildLdLibShared
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ [ "gcc -shared", "-o", libFile ] ++ oFiles
}
builder_PPC32_Linux config host
= Builder
{ builderName = "ppc32-linux"
, buildHost = Platform ArchPPC_32 OsLinux
, buildTarget = Platform ArchPPC_32 OsLinux
, buildSpec = Llvm.platform32
, buildBaseSrcDir = builderConfigBaseSrcDir config
, buildBaseLibDir = builderConfigBaseLibDir config
, buildLlvmVersion = builderHostLlvmVersion host
, buildLlc
= \llFile sFile
-> doCmd "LLVM compiler" [(2, BuilderCanceled)]
[ "llc -O3 -march=ppc32 -relocation-model=pic"
, llFile
, "-o", sFile ]
, buildCC
= \cFile oFile
-> doCmd "C compiler" [(2, BuilderCanceled)]
[ "gcc -Werror -std=c99 -O3 -m32"
, "-c", cFile
, "-o", oFile
, "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"
, "-I" ++ builderConfigBaseSrcDir config </> "sea/primitive" ]
, buildAs
= \sFile oFile
-> doCmd "assembler" [(2, BuilderCanceled)]
[ "as"
, "-o", oFile
, sFile ]
, buildLdExe
= \oFiles binFile
-> doCmd "linker" [(2, BuilderCanceled)]
[ "gcc -m32"
, "-o", binFile
, intercalate " " $ map normalise oFiles
, builderConfigBaseLibDir config
</> builderConfigLibFile config
"libddc-runtime.a"
"libddc-runtime.so" ]
, buildLdLibStatic
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ ["ar r", libFile] ++ oFiles
, buildLdLibShared
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ [ "gcc -shared", "-o", libFile ] ++ oFiles
}
builder_X8632_Cygwin config host
= Builder
{ builderName = "x86_32-cygwin"
, buildHost = Platform ArchX86_32 OsCygwin
, buildTarget = Platform ArchX86_32 OsCygwin
, buildSpec = Llvm.platform32
, buildBaseSrcDir = builderConfigBaseSrcDir config
, buildBaseLibDir = builderConfigBaseLibDir config
, buildLlvmVersion = builderHostLlvmVersion host
, buildLlc
= \llFile sFile
-> doCmd "LLVM compiler" [(2, BuilderCanceled)]
[ "llc -O3 -march=x86 "
, normalise llFile
, "-o", normalise sFile ]
, buildCC
= \cFile oFile
-> doCmd "C compiler" [(2, BuilderCanceled)]
[ "gcc-4 -Werror -std=c99 -O3 -m32"
, "-c", cFile
, "-o", oFile
, "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"
, "-I" ++ builderConfigBaseSrcDir config </> "sea/primitive" ]
, buildAs
= \sFile oFile
-> doCmd "assembler" [(2, BuilderCanceled)]
[ "as --32"
, "-o", normalise oFile
, normalise sFile ]
, buildLdExe
= \oFiles binFile
-> doCmd "linker" [(2, BuilderCanceled)]
[ "gcc-4 -m32"
, "-o", normalise binFile
, intercalate " " $ map normalise oFiles
, normalise $ builderConfigBaseLibDir config
</> "libddc-runtime.a" ]
, buildLdLibStatic
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ ["ar r", libFile] ++ oFiles
, buildLdLibShared
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ [ "gcc -shared", "-o", libFile ] ++ oFiles
}
builder_X8632_Mingw config host
= Builder
{ builderName = "x86_32-mingw"
, buildHost = Platform ArchX86_32 OsMingw
, buildTarget = Platform ArchX86_32 OsMingw
, buildSpec = Llvm.platform32
, buildBaseSrcDir = builderConfigBaseSrcDir config
, buildBaseLibDir = builderConfigBaseLibDir config
, buildLlvmVersion = builderHostLlvmVersion host
, buildLlc
= \llFile sFile
-> doCmd "LLVM compiler" [(2, BuilderCanceled)]
[ "llc -O3 -march=x86 "
, normalise llFile
, "-o", normalise sFile ]
, buildCC
= \cFile oFile
-> doCmd "C compiler" [(2, BuilderCanceled)]
[ "gcc -Werror -std=c99 -O3 -m32"
, "-c", cFile
, "-o", oFile
, "-I" ++ builderConfigBaseSrcDir config </> "sea/runtime"
, "-I" ++ builderConfigBaseSrcDir config </> "sea/primitive" ]
, buildAs
= \sFile oFile
-> doCmd "assembler" [(2, BuilderCanceled)]
[ "as --32"
, "-o", normalise oFile
, normalise sFile ]
, buildLdExe
= \oFiles binFile
-> doCmd "linker" [(2, BuilderCanceled)]
[ "gcc -m32"
, "-o", normalise binFile
, intercalate " " $ map normalise oFiles
, normalise $ builderConfigBaseLibDir config
</> "libddc-runtime.a" ]
, buildLdLibStatic
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ ["ar r", libFile] ++ oFiles
, buildLdLibShared
= \oFiles libFile
-> doCmd "linker" [(2, BuilderCanceled)]
$ [ "gcc -shared", "-o", libFile ] ++ oFiles
}
doCmd :: String
-> [(Int, BuilderResult)]
-> [String]
-> IO ()
doCmd thing exitCodeMeanings cmdParts
= do
code <- system cmd
case code of
ExitSuccess
-> return ()
ExitFailure c
| Just meaning <- lookup c exitCodeMeanings
-> case meaning of
BuilderSuccess -> return ()
BuilderCanceled -> exitWith $ ExitFailure 2
BuilderFailed -> die c
| otherwise -> die c
where cmd = unwords cmdParts
die c = error
$ unlines
[ "System command failed when invoking external " ++ thing ++ "."
, " Command was: " ++ cmd
, " Exit code: " ++ show c ]