-
Notifications
You must be signed in to change notification settings - Fork 0
/
Setup.hs
140 lines (109 loc) · 4.5 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
{-# LANGUAGE NamedFieldPuns #-}
import Control.Applicative
import Control.Arrow
import Control.Monad
import Data.Maybe
import Distribution.Verbosity
import Distribution.Simple
import Distribution.Simple.Setup
import Distribution.Simple.Program.Builtin
import Distribution.Simple.Program.Run
import Distribution.Simple.Program.Db
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.GHC
import Distribution.Simple.Utils
import Distribution.Simple.Build
import Distribution.Simple.Install
import Distribution.Simple.Configure
import Distribution.PackageDescription
import System.FilePath
import System.IO
main = defaultMainWithHooks $ simpleUserHooks {
buildHook = myBuildHook,
preBuild = myPreBuild,
instHook = myInst,
copyHook = myCopy
}
-- Set loader buildability to false since we're building that ourselfs
myPreBuild args flags = return $ buildableHBI "rts-loader" False
myBuildHook pd lbi uh flags = do
buildLoaderExecutable pd lbi flags
-- gah Cabal throws an error if there are no buildable components
unless (null $ allBuildInfo pd) $
(buildHook simpleUserHooks) pd lbi uh flags
buildLoaderExecutable pd lbi flags = do
let distPref = fromFlag (buildDistPref flags)
verbosity = fromFlag (buildVerbosity flags)
(ghc, _) <- requireProgram verbosity ghcProgram (withPrograms lbi)
(gcc, _) <- requireProgram verbosity gccProgram (withPrograms lbi)
ghcInfo <- getGhcInfo verbosity ghc
let [Executable {exeName=exeName', modulePath}] =
filter ((== "rts-loader") . exeName) $ executables pd
targetDir = buildDir lbi </> exeName'
exeDir = targetDir </> (exeName' ++ "-tmp")
createDirectoryIfMissingVerbose verbosity True targetDir
createDirectoryIfMissingVerbose verbosity True exeDir
let Just libDir = lookup "LibDir" ghcInfo
includes = [libDir </> "include"]
includeOpts = map ("-I"++) includes
libs = ["dl"]
libOpts = map ("-l"++) libs
opts = [ "-std=gnu99"
, "-o", targetDir </> exeName'
]
++ includeOpts
++ libOpts
++ [modulePath]
gccInvokation = programInvocation gcc opts
runProgramInvocation verbosity gccInvokation
myInst = myInstOrCopy instHook installVerbosity
myCopy = myInstOrCopy copyHook copyVerbosity
myInstOrCopy :: (UserHooks
-> PackageDescription
-> LocalBuildInfo
-> UserHooks
-> flags
-> IO ())
-> (flags -> Distribution.Simple.Setup.Flag Verbosity)
-> PackageDescription
-> LocalBuildInfo
-> UserHooks
-> flags
-> IO ()
myInstOrCopy hook verbosity pd lbi hooks flags = do
let [exe] = filter ((=="rts-loader") . exeName) (executables pd)
Just install_dir =
lookup "x-install-dir" $ customFieldsBI $ buildInfo exe
libexec = fromPathTemplate $ libexecdir (installDirTemplates lbi)
install_dir' = toPathTemplate $ substLibexecdir libexec install_dir
lbi_libexec = modifyInstallDirTemplates (setBindir install_dir') lbi
hbi_only_exe = disableAllInstallComponentsExcept pd "rts-loader"
hbi_not_exe = buildableHBI "rts-loader" False
pd_only_exe = updatePackageDescription hbi_only_exe pd
pd_not_exe = updatePackageDescription hbi_not_exe pd
distPref <- findDistPrefOrDefault (copyDistPref defaultCopyFlags)
let copyFlags = defaultCopyFlags { copyDistPref = toFlag distPref
, copyVerbosity = verbosity flags
}
install pd_only_exe lbi_libexec copyFlags
(hook simpleUserHooks) pd_not_exe lbi hooks flags
where
modifyInstallDirTemplates f lbi =
lbi { installDirTemplates = f (installDirTemplates lbi) }
setBindir bindir' inst_dirs =
inst_dirs { bindir = bindir' }
substLibexecdirComp libexec "$libexecdir" = libexec
substLibexecdirComp _ comp = comp
substLibexecdir libexec = onSplitPath $
map (substLibexecdirComp libexec . dropTrailingPathSeparator)
onSplitPath f p = joinPath $ f (splitPath p)
buildableHBI pkg build =
(Nothing, [(pkg, setBuildable build)])
setBuildable build = emptyBuildInfo { buildable = build }
disableAllInstallComponentsExcept pd except =
let lib = (const (setBuildable False)) <$> library pd
exes = [ (exeName exe, setBuildable (exeName exe == except))
| exe <- executables pd
]
in
(lib, exes)