summaryrefslogtreecommitdiff
path: root/libraries/ghc-prim/Setup.hs
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ghc-prim/Setup.hs')
-rw-r--r--libraries/ghc-prim/Setup.hs88
1 files changed, 88 insertions, 0 deletions
diff --git a/libraries/ghc-prim/Setup.hs b/libraries/ghc-prim/Setup.hs
new file mode 100644
index 0000000000..5bb17e2392
--- /dev/null
+++ b/libraries/ghc-prim/Setup.hs
@@ -0,0 +1,88 @@
+
+-- We need to do some ugly hacks here because of GHC magic
+
+module Main (main) where
+
+import Control.Monad
+import Data.List
+import Data.Maybe
+import Distribution.PackageDescription
+import Distribution.Simple
+import Distribution.Simple.LocalBuildInfo
+import Distribution.Simple.Program
+import Distribution.Simple.Utils
+import Distribution.Text
+import System.Cmd
+import System.FilePath
+import System.Exit
+import System.Directory
+
+main :: IO ()
+main = do let hooks = simpleUserHooks {
+ regHook = addPrimModule
+ $ regHook simpleUserHooks,
+ buildHook = build_primitive_sources
+ $ buildHook simpleUserHooks,
+ haddockHook = addPrimModuleForHaddock
+ $ build_primitive_sources
+ $ haddockHook simpleUserHooks }
+ defaultMainWithHooks hooks
+
+type Hook a = PackageDescription -> LocalBuildInfo -> UserHooks -> a -> IO ()
+
+addPrimModule :: Hook a -> Hook a
+addPrimModule f pd lbi uhs x =
+ do let -- I'm not sure which one of these we actually need to change.
+ -- It seems bad that there are two.
+ pd' = addPrimModuleToPD pd
+ lpd = addPrimModuleToPD (localPkgDescr lbi)
+ lbi' = lbi { localPkgDescr = lpd }
+ f pd' lbi' uhs x
+
+addPrimModuleForHaddock :: Hook a -> Hook a
+addPrimModuleForHaddock f pd lbi uhs x =
+ do let pc = withPrograms lbi
+ pc' = userSpecifyArgs "haddock" ["GHC/Prim.hs"] pc
+ lbi' = lbi { withPrograms = pc' }
+ f pd lbi' uhs x
+
+addPrimModuleToPD :: PackageDescription -> PackageDescription
+addPrimModuleToPD pd =
+ case library pd of
+ Just lib ->
+ let ems = fromJust (simpleParse "GHC.Prim") : exposedModules lib
+ lib' = lib { exposedModules = ems }
+ in pd { library = Just lib' }
+ Nothing ->
+ error "Expected a library, but none found"
+
+build_primitive_sources :: Hook a -> Hook a
+build_primitive_sources f pd lbi uhs x
+ = do when (compilerFlavor (compiler lbi) == GHC) $ do
+ let genprimopcode = joinPath ["..", "..", "utils",
+ "genprimopcode", "genprimopcode"]
+ primops = joinPath ["..", "..", "compiler", "prelude",
+ "primops.txt"]
+ primhs = joinPath ["GHC", "Prim.hs"]
+ primopwrappers = joinPath ["GHC", "PrimopWrappers.hs"]
+ primhs_tmp = addExtension primhs "tmp"
+ primopwrappers_tmp = addExtension primopwrappers "tmp"
+ maybeExit $ system (genprimopcode ++ " --make-haskell-source < "
+ ++ primops ++ " > " ++ primhs_tmp)
+ maybeUpdateFile primhs_tmp primhs
+ maybeExit $ system (genprimopcode ++ " --make-haskell-wrappers < "
+ ++ primops ++ " > " ++ primopwrappers_tmp)
+ maybeUpdateFile primopwrappers_tmp primopwrappers
+ f pd lbi uhs x
+
+-- Replace a file only if the new version is different from the old.
+-- This prevents make from doing unnecessary work after we run 'setup makefile'
+maybeUpdateFile :: FilePath -> FilePath -> IO ()
+maybeUpdateFile source target = do
+ r <- rawSystem "cmp" ["-s" {-quiet-}, source, target]
+ case r of
+ ExitSuccess -> removeFile source
+ ExitFailure _ -> do exists <- doesFileExist target
+ when exists $ removeFile target
+ renameFile source target
+