forked from haskell/haskeline
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Setup.hs
126 lines (113 loc) · 4.48 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
{-# LANGUAGE CPP #-}
import Distribution.System
import Distribution.Verbosity
import Distribution.PackageDescription
import Distribution.Simple
import Distribution.Simple.Program
import Distribution.Simple.Setup
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Utils
import Distribution.Simple.PackageIndex
import qualified Distribution.InstalledPackageInfo as Installed
import System.IO
import System.Exit
import System.Directory
import Control.Exception
import Control.Monad(when)
main :: IO ()
main = defaultMainWithHooks myHooks
myHooks :: UserHooks
myHooks
| buildOS == Windows = simpleUserHooks
| otherwise = simpleUserHooks {
confHook = \genericDescript flags -> do
warnIfNotTerminfo flags
lbi <- confHook simpleUserHooks genericDescript flags
let pkgDescr = localPkgDescr lbi
let Just lib = library pkgDescr
let bi = libBuildInfo lib
bi' <- maybeSetLibiconv flags bi lbi
return lbi {localPkgDescr = pkgDescr {
library = Just lib {
libBuildInfo = bi'}}}
}
warnIfNotTerminfo flags = when (not (hasFlagSet flags (FlagName "terminfo")))
$ mapM_ putStrLn
[ "*** Warning: running on POSIX but not building the terminfo backend. ***"
, "You may need to install the terminfo package manually, e.g. with"
, "\"cabal install terminfo\"; or, use \"-fterminfo\" when configuring or"
, "installing this package."
,""
]
hasFlagSet :: ConfigFlags -> FlagName -> Bool
hasFlagSet cflags flag = Just True == lookup flag (configConfigurationsFlags cflags)
-- Test whether compiling a c program that links against libiconv needs -liconv.
-- (Not needed for ghc>=7.4.1, even for the legacy POSIX backend, since
-- the base library always links against iconv .)
maybeSetLibiconv :: ConfigFlags -> BuildInfo -> LocalBuildInfo -> IO BuildInfo
#if __GLASGOW_HASKELL__ >= 704
maybeSetLibiconv _ bi _ = return bi
#else
maybeSetLibiconv flags bi lbi = do
let biWithIconv = addIconv bi
let verb = fromFlag (configVerbosity flags)
if hasFlagSet flags (FlagName "libiconv")
then do
putStrLn "Using -liconv."
return biWithIconv
else do
putStr "checking whether to use -liconv... "
hFlush stdout
worksWithout <- tryCompile iconv_prog bi lbi verb
if worksWithout
then do
putStrLn "not needed."
return bi
else do
worksWith <- tryCompile iconv_prog biWithIconv lbi verb
if worksWith
then do
putStrLn "using -liconv."
return biWithIconv
else error "Unable to link against the iconv library."
tryCompile :: String -> BuildInfo -> LocalBuildInfo -> Verbosity -> IO Bool
tryCompile program bi lbi verb = handle processExit $ handle processException $ do
tempDir <- getTemporaryDirectory
withTempFile tempDir ".c" $ \fname cH ->
withTempFile tempDir "" $ \execName oH -> do
hPutStr cH program
hClose cH
hClose oH
-- TODO take verbosity from the args.
rawSystemProgramStdoutConf verb gccProgram (withPrograms lbi)
(fname : "-o" : execName : args)
return True
where
processException :: IOException -> IO Bool
processException e = return False
processExit = return . (==ExitSuccess)
-- Mimicing Distribution.Simple.Configure
deps = topologicalOrder (installedPkgs lbi)
args = concat
[ ccOptions bi
, cppOptions bi
, ldOptions bi
-- --extra-include-dirs and --extra-lib-dirs are included
-- in the below fields.
-- Also sometimes a dependency like rts points to a nonstandard
-- include/lib directory where iconv can be found.
, map ("-I" ++) (includeDirs bi ++ concatMap Installed.includeDirs deps)
, map ("-L" ++) (extraLibDirs bi ++ concatMap Installed.libraryDirs deps)
, map ("-l" ++) (extraLibs bi)
]
addIconv :: BuildInfo -> BuildInfo
addIconv bi = bi {extraLibs = "iconv" : extraLibs bi}
iconv_prog :: String
iconv_prog = unlines $
[ "#include <iconv.h>"
, "int main(void) {"
, " iconv_t t = iconv_open(\"UTF-8\", \"UTF-8\");"
, " return 0;"
, "}"
]
#endif