-
Notifications
You must be signed in to change notification settings - Fork 10
/
Setup.hs
147 lines (127 loc) · 5.77 KB
/
Setup.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
{-# OPTIONS_GHC -Wall #-}
module Main (main) where
import Control.Monad
import Distribution.Simple
import Distribution.Verbosity
import Distribution.Simple.Setup
import Distribution.Simple.Utils ( rawSystemExit
, installOrdinaryFile
, notice
)
import Distribution.PackageDescription ( GenericPackageDescription(..)
, PackageDescription(..)
, BuildInfo(..)
, HookedBuildInfo
, emptyBuildInfo
, updatePackageDescription
)
import Distribution.Simple.LocalBuildInfo ( LocalBuildInfo(..)
, InstallDirs(..)
, absoluteInstallDirs
)
import System.Directory
import System.Exit
import System.FilePath
import System.IO
import System.Process
------------------------------------------------------------------------
-- Utilities
-- | Update library build infomation.
updateLibBuild :: PackageDescription -> BuildInfo -> PackageDescription
updateLibBuild pkg_desc bi = updatePackageDescription (Just bi, []) pkg_desc
-- | Get the absolute path to the build directory. This is used during the
-- cabal build so that we can direct where to install blt to during the cabal
-- build.
getBuildPath :: LocalBuildInfo -> IO FilePath
getBuildPath lcl_build_info = do
origDir <- getCurrentDirectory
return $ origDir </> buildDir lcl_build_info
-- | Generate BuildInfo that would add extra library directory.
extraLibDir :: FilePath -> BuildInfo
extraLibDir path = emptyBuildInfo { extraLibDirs = [path] }
------------------------------------------------------------------------
-- Commands for compiling and building BLT.
-- | Build libblt.
buildBLT :: Verbosity -> IO ()
buildBLT verb = do
withCurrentDirectory "libblt" $ do
-- Create config if it does not exist.
do hasConfig <- doesFileExist "config.mk"
when (hasConfig == False) $ do
rawSystemExit verb "cp" ["config.mk.example", "config.mk"]
-- print build environment
when (verb >= verbose) $ rawSystemExit verb "make" ["print"]
-- Build libblt.a
do when (verb >= verbose) $ putStrLn $ "Running make libblt.a"
exitcode <- rawSystem "make" ["all"]
when (exitcode /= ExitSuccess) $ do
hPutStrLn stderr "'make libblt.a' failed."
exitWith exitcode
-- Generate archive in libblt.a
rawSystemExit verb "ranlib" [ "libblt.a" ]
-- | Install library to specified directly.
installBLT :: Verbosity -> FilePath -> IO ()
installBLT verb dest = do
notice verb ("blt/Setup.hs@installBLT: copying libblt.a library to " ++ dest)
createDirectoryIfMissing True dest
installOrdinaryFile verb ("libblt"</>"libblt.a") ( dest </> "libblt.a" )
notice verb "blt/Setup.hs@installBLT: done."
------------------------------------------------------------------------
-- Build system hooks.
main :: IO ()
main = defaultMainWithHooks simpleUserHooks
{ confHook = doConf
, cleanHook = doClean
, postConf = postConfHook
, postInst = postInstHook
, postCopy = postCopyHook
}
doConf :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo
doConf (pkg_desc, hbi) flags =
do let verb = fromFlag (configVerbosity flags)
-- Call the default configure action
local_build_info <- confHook simpleUserHooks (pkg_desc, hbi) flags
-- Figure out where Cabal wants to build
buildPath <- getBuildPath local_build_info
-- Build BLT
buildBLT verb
-- Install 'libblt' to build directory 'buildPath' for Haskell to link against.
installBLT verb buildPath
-- Modify config to use blt path.
let p' = (localPkgDescr local_build_info) `updateLibBuild` extraLibDir buildPath
return local_build_info{ localPkgDescr = p' }
-- | Command to run after "cabal configure" command.
postConfHook :: Args -> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
postConfHook a f pkg_desc local_build_info = do
buildPath <- getBuildPath local_build_info
-- Modify config to use blt path.
let p' = pkg_desc `updateLibBuild` extraLibDir buildPath
-- Call standard postConf hook
postConf simpleUserHooks a f p' local_build_info
-- | Install BLT library after other installation occured.
postInstHook :: Args -> InstallFlags -> PackageDescription -> LocalBuildInfo -> IO ()
postInstHook args flags pkg_desc local_build_info = do
let verb = fromFlag (installVerbosity flags)
-- Get install directory.
let instDirs = absoluteInstallDirs pkg_desc local_build_info NoCopyDest
-- Install BLT library into that path.
installBLT verb (libdir instDirs)
-- Call standard postInst hook
postInst simpleUserHooks args flags pkg_desc local_build_info
-- | Install libblt library after rest of "cabal copy" command.
postCopyHook :: Args -> CopyFlags -> PackageDescription -> LocalBuildInfo -> IO ()
postCopyHook args flags pkg_desc local_build_info = do
let verb = fromFlag $ copyVerbosity flags
let instDirs = absoluteInstallDirs pkg_desc local_build_info (fromFlag (copyDest flags))
-- Install BLT
installBLT verb (libdir instDirs)
-- Call standard postCopy hook
postCopy simpleUserHooks args flags pkg_desc local_build_info
-- | Add cleanup of C++ library artifacts in addition to standard clean.
doClean :: PackageDescription -> () -> UserHooks -> CleanFlags -> IO ()
doClean p () u c = do
-- cleanup c++ library artifacts
withCurrentDirectory "libblt" $
rawSystemExit normal "make" ["clean"]
-- Clean up dist artifacts.
cleanHook simpleUserHooks p () u c