on aa7262e help sign in
Idris-dev/src/Pkg/Package.hs
130 lines 4.7 kB history raw
1module Pkg.Package where
3import System.Process
4import System.Directory
5import System.Exit
6import System.IO
7import System.FilePath ((</>), addTrailingPathSeparator)
9import Util.System
11import Control.Monad
12import Data.List
13import Data.List.Split(splitOn)
15import Core.TT
16import Idris.REPL
17import Idris.AbsSyntax
19import Pkg.PParser
21import Paths_idris
23-- To build a package:
24-- * read the package description
25-- * check all the library dependencies exist
26-- * invoke the makefile if there is one
27-- * invoke idris on each module, with idris_opts
28-- * install everything into datadir/pname, if install flag is set
30buildPkg :: Bool -> (Bool, FilePath) -> IO ()
31buildPkg warnonly (install, fp)
32 = do pkgdesc <- parseDesc fp
33 ok <- mapM (testLib warnonly (pkgname pkgdesc)) (libdeps pkgdesc)
34 when (and ok) $
35 do make (makefile pkgdesc)
36 dir <- getCurrentDirectory
37 setCurrentDirectory $ dir </> sourcedir pkgdesc
38 case (execout pkgdesc) of
39 Nothing -> buildMods (NoREPL : Verbose : idris_opts pkgdesc)
40 (modules pkgdesc)
41 Just o -> do let exec = dir </> o
42 buildMods
43 (NoREPL : Verbose : Output exec : idris_opts pkgdesc)
44 [idris_main pkgdesc]
45 setCurrentDirectory dir
46 when install $ installPkg pkgdesc
48cleanPkg :: FilePath -> IO ()
49cleanPkg fp
50 = do pkgdesc <- parseDesc fp
51 clean (makefile pkgdesc)
52 dir <- getCurrentDirectory
53 setCurrentDirectory $ dir </> sourcedir pkgdesc
54 mapM_ rmIBC (modules pkgdesc)
55 case execout pkgdesc of
56 Nothing -> return ()
57 Just s -> do let exec = dir </> s
58 putStrLn $ "Removing " ++ exec
59 system $ "rm -f " ++ exec
60 return ()
62installPkg :: PkgDesc -> IO ()
63installPkg pkgdesc
64 = do dir <- getCurrentDirectory
65 setCurrentDirectory $ dir </> sourcedir pkgdesc
66 case (execout pkgdesc) of
67 Nothing -> mapM_ (installIBC (pkgname pkgdesc)) (modules pkgdesc)
68 Just o -> return () -- do nothing, keep executable locally, for noe
69 mapM_ (installObj (pkgname pkgdesc)) (objs pkgdesc)
71buildMods :: [Opt] -> [Name] -> IO ()
72buildMods opts ns = do let f = map (toPath . show) ns
73 idris (map Filename f ++ opts)
74 return ()
75 where toPath n = foldl1 (</>) $ splitOn "." n
77testLib :: Bool -> String -> String -> IO Bool
78testLib warn p f
79 = do d <- getDataDir
80 gcc <- getCC
81 (tmpf, tmph) <- tempfile
82 hClose tmph
83 let libtest = d </> "rts" </> "libtest.c"
84 e <- system $ gcc ++ " " ++ libtest ++ " -l" ++ f ++ " -o " ++ tmpf
85 case e of
86 ExitSuccess -> return True
87 _ -> do if warn
88 then do putStrLn $ "Not building " ++ p ++
89 " due to missing library " ++ f
90 return False
91 else fail $ "Missing library " ++ f
93rmIBC :: Name -> IO ()
94rmIBC m = do let f = toIBCFile m
95 putStrLn $ "Removing " ++ f
96 system $ "rm -f " ++ f
97 return ()
99toIBCFile (UN n) = n ++ ".ibc"
100toIBCFile (NS n ns) = foldl1 (</>) (reverse (toIBCFile n : ns))
102installIBC :: String -> Name -> IO ()
103installIBC p m = do let f = toIBCFile m
104 d <- getDataDir
105 let destdir = d </> p </> getDest m
106 putStrLn $ "Installing " ++ f ++ " to " ++ destdir
107 system $ "mkdir -p " ++ destdir
108 system $ "install " ++ f ++ " " ++ destdir
109 return ()
110 where getDest (UN n) = ""
111 getDest (NS n ns) = foldl1 (</>) (reverse (getDest n : ns))
113installObj :: String -> String -> IO ()
114installObj p o = do d <- getDataDir
115 let destdir = addTrailingPathSeparator (d </> p)
116 putStrLn $ "Installing " ++ o ++ " to " ++ destdir
117 system $ "mkdir -p " ++ destdir
118 system $ "install " ++ o ++ " " ++ destdir
119 return ()
121make :: Maybe String -> IO ()
122make Nothing = return ()
123make (Just s) = do system $ "make -f " ++ s
124 return ()
126clean :: Maybe String -> IO ()
127clean Nothing = return ()
128clean (Just s) = do system $ "make -f " ++ s ++ " clean"
129 return ()