hubris-0.0.2: Language/Ruby/Hubris/GHCBuild.hs
module Language.Ruby.Hubris.GHCBuild (ghcBuild, defaultGHCOptions, GHCOptions(..)) where
import Config
import Debug.Trace
import DynFlags
import GHC
import GHC.Paths
import Outputable
import StringBuffer
import System.Process
import Control.Monad(forM_)
import System.IO(hPutStr, hClose, openTempFile)
import System( exitWith, system)
import System.Exit
import Includes (extraIncludeDirs) -- this is generated by Cabal
newtype GHCOptions = GHCOptions { strict :: Bool }
defaultGHCOptions = GHCOptions { strict = True }
type Filename = String
genHaskellFile :: String -> IO String
genHaskellFile code = do (name, handle) <- openTempFile "/tmp" "hubris_XXXXX.hs"
hPutStr handle code
hClose handle
return name
-- sh = showSDoc . ppr
-- this one's a bit tricky: we _could_ use the GHC api, but i don't care too much.
-- let's keep it simple.
--
-- ok, new plan: handling it the filthy way is awful.
--
-- We do need rshim.o, but it's packaged in the hubris lib, with any luck.
ghcBuild :: Filename -> String -> String -> [Filename] -> [Filename] -> [String]-> IO (Maybe (ExitCode,String))
ghcBuild libFile immediateSource modName extra_sources c_sources args =
do -- putStrLn ("modname is " ++ modName)
-- let c_wrapper = modName ++ ".aux.o"
-- eesh, this is awful...
-- doOrDie $ System.system("gcc -c -I/opt/local/include/ruby-1.9.1 -o " ++ c_wrapper ++ " " ++ unwords c_sources)
haskellSrcFile <- genHaskellFile immediateSource
noisySystem ghc $ ["--make", "-shared", "-dynamic", "-o", libFile, "-optl-Wl,-rpath," ++ libdir,
"-lHSrts-ghc" ++ Config.cProjectVersion, haskellSrcFile] ++
map ("-I"++) extraIncludeDirs
++ extra_sources ++ c_sources ++ args
-- defaultErrorHandler defaultDynFlags $ do
-- res <- runGhc (Just libdir) $ do
-- dflags <- getSessionDynFlags
-- (newflags, leftovers, warnings) <- GHC.parseDynamicFlags dflags
-- $ map noLoc $ [ "-shared", "-o",libFile,"-optl-Wl,-rpath," ++ libdir,
-- "-lHSrts-ghc" ++ Config.cProjectVersion]
-- trace ("left2: " ++ sh leftovers) $ trace ("warns2: " ++ (sh warnings)) $ setSessionDynFlags newflags
-- forM_ (haskellSrcFile:extra_sources) (\file -> guessTarget file Nothing >>= addTarget)
-- load LoadAllTargets
-- -- doOrDie $ System.system("ld -dylib -flat_namespace -o " ++ libFile ++ " " ++ unwords ["foo"++ libFile, c_wrapper])
-- print res
-- return (case res of
-- Succeeded -> True
-- _ -> False)
noisySystem :: String -> [String] -> IO (Maybe (ExitCode, String))
noisySystem cmd args =
do putStrLn $ unwords (cmd:args)
(errCode, out, err) <- readProcessWithExitCode cmd args ""
return $ if (errCode == ExitSuccess)
then Nothing
else Just (errCode, unlines ["output: " ++ out, "error: " ++ err])
-- doOrDie :: IO ExitCode -> IO ()
-- doOrDie action = do res <- action
-- case res of
-- ExitSuccess -> return ()
-- i -> exitWith i