Merge branch 'darcs' into master
[git-darcs-import.git] / Setup.hs
blob9a6b8534cc95b7ee88b4abf2b45f605ce86d4adf
1 #!/usr/bin/runhaskell
2 import Distribution.Franchise
3 import Data.Char ( isDigit )
4 import Control.Monad ( msum )
5 import System.Directory ( removeFile, getDirectoryContents, doesFileExist )
7 true_version = "2.1.0"
9 configure = do version true_version
10 defineAs "PACKAGE_VERSION" (show true_version)
11 ghcFlags ["-threaded","-Wall","-O2","-funbox-strict-fields"]
12 define "_REENTRANT"
14 checkWindows
15 define "HAVE_SYSTEM_POSIX"
17 checkLib "z" "zlib.h" "gzopen(\"hello\", \"r\")"
18 `catchC` \_ ->
19 do requireModule "Codec.Compression.GZip"
20 define "HAVE_HASKELL_ZLIB"
21 checkHTTP
23 not `fmap` amLittleEndian >>= replace "@BIGENDIAN@"
25 -- These are default values
26 replace "@USE_COLOR@" True
27 replace "@sysconfdir@" "/etc"
28 replace "@datadir@" "/usr/local/share"
30 do checkHeader "siginfo.h"
31 putS "Found siginfo.h"
32 define "HAVE_SIGINFO_H"
33 `catchC` \_ -> return ()
35 replace "@USE_MMAP@" True
36 replace "@SENDMAIL@" (Literal "/usr/sbin/sendmail")
37 replace "@HAVE_SENDMAIL@" True
38 replace "@GHC_SEPARATOR@" '/'
40 -- check if we can link with mapi library
41 -- WARNING: this check may be broken
42 have_mapi <- (do checkLib "mapi32" "windows.h" "MAPISendMail()"
43 return True) `catchC` \_ -> return False
44 replace "@HAVE_MAPI@" have_mapi
46 replace "@DIFF@" (Literal "diff")
48 createFile "src/Autoconf.lhs"
50 warnSlowHttp
52 darcs = do extra_cfiles <- checkWindows
53 addTarget context
54 build' CanModifyState "src/Context.hs"
55 addTarget releaseVersion
56 build' CanModifyState "src/ThisVersion.lhs"
57 let cfiles = ["src/atomic_create.c","src/fpstring.c",
58 "src/c_compat.c","src/hscurl.c","src/maybe_relink.c",
59 "src/hslibwww.c","src/umask.c","src/Crypt/sha2.c"]
60 ++extra_cfiles
61 d <- executable "darcs" "src/darcs.lhs" cfiles
63 texDocs <- buildTexDocs cfiles
64 return d
66 main = build options configure darcs
68 options = [ -- configureFlag defines flags coupled with actions to take
69 -- when configuring, if the flag is present. By contrast,
70 -- configureUnlessFlag defines actions to take when configuring
71 -- if the flag is *not* present. When building and no
72 -- reconfigure is needed (because Setup.hs hasn't been
73 -- modified), these flags are all ignored.
74 configureFlag "with-bytestring" "use bytestring package"
75 (do requireModule "Data.ByteString"
76 define "HAVE_BYTESTRING"),
77 configureFlag "with-static-libs" "link with static versions of libraries"
78 (do ldFlags ["-static"]
79 addExtraData "STATIC" ""),
80 configureUnlessFlag "without-libwww" "do not use libwww" checkLibWWW,
81 configureUnlessFlag "without-libcurl" "do not use libcurl" checkCurl,
82 configureFlag "with-type-witnesses" "for gadt type witnesses"
83 (do define "GADT_WITNESSES"
84 ghcFlags ["-fglasgow-exts"]),
85 configureUnlessFlag "without-haskeline" "do not use haskeline, even if it is present" $
86 withModuleExporting "System.Console.Haskeline"
87 "runInputT, defaultSettings, getInputLine, handleDyn"
88 "runInputT defaultSettings (getInputLine \"prompt: \") :: IO (Maybe String)"
89 $ define "HAVE_HASKELINE",
90 configureUnlessFlag "without-curses" "don't use libcurses" $
91 withLib "curses" "term.h" "tgetnum(\"foobar\")" $
92 define "HAVE_CURSES",
93 -- flag and unlessFlag describe flags that have effect even
94 -- when we are not configuring, which may override the
95 -- configured value.
96 flag "disable-color" "do not use ansi color escapes"
97 (replace "@USE_COLOR@" False),
98 unlessFlag "disable-Werror" "don't fail on warnings" $ ghcFlags ["-Werror"]
101 context = (["src/Context.hs"] :< ["_darcs/hashed_inventory"])
102 |<- defaultRule { make = const makeContext }
103 where makeContext =
104 do c <- systemOut "darcs" ["changes","--context"]
105 `catchC` \_ -> return "unknown context"
106 io $ writeFile "src/Context.hs" "module Context where\n"
107 io $ appendFile "src/Context.hs" "context :: String\n"
108 io $ appendFile "src/Context.hs" ("context = "++show c++"\n")
109 io $ appendFile "src/Context.hs" "\n"
111 data Literal = Literal String
112 instance Show Literal where
113 showsPrec _ (Literal x) = showString x
115 releaseVersion =
116 ["src/ThisVersion.lhs","doc/index.html"]
117 :< ["_darcs/hashed_inventory", "src/ThisVersion.lhs.in",
118 "doc/index.html.in", extraData "version"]
119 |<- defaultRule { make = const findReleaseVersion }
120 where findReleaseVersion =
121 do patches' <- systemOut "darcs"
122 ["changes","--from-tag",true_version,"--count"]
123 `catchC` \_ -> return "-1"
124 ((patches'',_):_) <- return $ reads patches' ++ [(-1,"")]
125 let patches = if patches'' > 0 then patches'' - 1 else patches''
126 Just state =
127 if patches == 0
128 then msum [niceVersion "pre" "prerelease" true_version,
129 niceVersion "rc" "release candidate" true_version,
130 isRelease true_version,
131 Just "tag"]
132 else if patches > 1
133 then Just $ "+ "++show patches++" patches"
134 else if patches < 0
135 then Just "unknown"
136 else Just $ "+ "++show patches++" patch"
137 xxx <- systemOut "darcs" ["changes","-t","'^[0-9\\.]+\\$", "--reverse"]
138 `catchC` \_ -> return ""
139 let lastrelease = case map words $ lines xxx of
140 ((_:zzz:_):_) -> zzz
141 _ -> "unknown"
142 replace "VERSION" true_version
143 replace "RELEASE" lastrelease
144 replace "STATE" state
145 replace "@DARCS_VERSION_STATE@" (Literal state)
146 replace "@DARCS_VERSION@" (Literal true_version)
147 createFile "doc/index.html"
148 createFile "src/ThisVersion.lhs"
149 -- Various extra files we generate...
150 createFile "darcs.cabal"
151 createFile "release/darcs.spec"
152 createFile "tools/cgi/darcs.cgi"
153 createFile "tools/cgi/README"
154 createFile "tools/cgi/cgi.conf"
156 niceVersion _ _ "" = Nothing
157 niceVersion x n y
158 | take (length x) y == x &&
159 all isDigit (drop (length x) y) = Just $ n++" "++drop (length x) y
160 niceVersion "" _ _ = Nothing
161 niceVersion x n (_:y) = niceVersion x n y
162 isRelease x = if all (\c -> isDigit c || c == '.') x
163 then Just "release"
164 else Nothing
166 checkLibWWW = unlessC (haveExtraData "HAVE_LIBCURL") $
167 unlessC (haveExtraData "HAVE_LIBWWW") $ -- avoid running this twice!
168 do io $ putStr "Checking for libwww... "
169 do systemOut "libwww-config" ["--version"]
170 define "HAVE_LIBWWW"
171 lds <- systemOut "libwww-config" ["--libs"]
172 ldFlags $ words lds
173 cfs <- systemOut "libwww-config" ["--cflags"]
174 cFlags $ words cfs
175 define "HAVE_LIBWWW"
176 cFlags ["-DHAVE_LIBWWW"]
177 addExtraData "HAVE_LIBWWW" ""
178 putS "found."
179 `catchC` \_ -> putS "not found."
181 checkCurl = unlessC (haveExtraData "HAVE_LIBWWW") $
182 unlessC (haveExtraData "HAVE_LIBCURL") $ -- avoid running this twice!
183 do io $ putStr "Checking for libcurl... "
184 curlconfig <-findProgram "curl-config" []
185 ver <- systemOut curlconfig ["--version"]
186 amstatic <- haveExtraData "STATIC"
187 lds <- if amstatic
188 then do define "CURL_STATICLIB"
189 systemOut curlconfig ["--static-libs"]
190 else systemOut curlconfig ["--libs"]
191 ldFlags $ words lds
192 cfs <- systemOut curlconfig ["--cflags"]
193 cFlags $ words cfs
194 define "HAVE_CURL"
195 putS $ "yes, "++filter (/= '\n') ver
196 io $ putStr "Checking whether libcurl actually works... "
197 checkLib "curl" "curl/curl.h" "curl_global_init(0)"
198 -- check whether we've got curl_multi_timeout...
199 do checkLib "curl" "curl/curl.h" "curl_multi_timeout(1,2)"
200 define "CURL_MULTI_TIMEOUT"
201 `catchC` \_ -> return ()
202 vernumstr <- systemOut curlconfig ["--vernum"]
203 let vernum = read ("0x0"++vernumstr) :: Int
204 minver = 0x071200 -- 7.18.0 has working buggy pipelining
205 goodver = 0x071301 -- 7.19.1 has bug-free pipelining
206 if vernum < minver
207 then putS "Curl pipelining requires libcurl version >= 7.18.0"
208 else do define "CURL_PIPELINING"
209 if vernum < goodver
210 then do putS "Curl pipelining in this version is buggy with http proxies."
211 putS "WARNING: Not enabling http pipelining by default!"
212 else do define "CURL_PIPELINING_DEFAULT"
213 addExtraData "HAVE_LIBCURL" ""
214 `catchC` \_ -> putS "libcurl not found"
216 checkHTTP = do havehttp <- lookForModule "Network.HTTP"
217 if havehttp
218 then do define "HAVE_HTTP"
219 replace "@HAVE_HTTP@" True
220 else do putS "Network.HTTP not found"
221 replace "@HAVE_HTTP@" False
223 warnSlowHttp =
224 do havefast <- or `fmap` mapM isDefined ["HAVE_LIBWWW", "HAVE_LIBCURL"]
225 havehttp <- isDefined "HAVE_HTTP"
226 case (havefast, havehttp) of
227 (True,_) -> return ()
228 (_,True) -> do putS "WARNING: http access will be slow."
229 putS " To get faster http, install libcurl or libwww."
230 (_,_) -> do x <- findProgram "wget" ["curl"]
231 putS $ "WARNING: http access will use the external program "++x
232 putS " This will be very slow. For faster http, install libcurl, "
233 putS " libwww or the http Haskell package."
234 `catchC` \_ ->
235 do putS "WARNING: There is no way for darcs to access files over http!"
236 putS " To allow darcs to access files over http, please install"
237 putS " either libcurl, libwww, the http Haskell package, or wget"
238 putS " or curl."
241 pureTexSources = ["src/features.tex", "src/switching.tex",
242 "src/configuring_darcs.tex", "src/gpl.tex",
243 "src/building_darcs.tex", "src/best_practices.tex",
244 "src/formats.tex"]
246 buildTexDocs cfiles =
247 do findProgram "pdflatex" []
248 preproc <- privateExecutable "preproc" "src/preproc.hs" cfiles
249 addTarget $ ["src/darcs_print.pdf"] :< ["src/darcs_print.tex"] |<-
250 defaultRule { make = \_ -> do cd "src"
251 system "pdflatex" ["darcs_print"] }
252 addTarget $ ["src/darcs_print.tex"] :< (preproc:pureTexSources) |<-
253 defaultRule { make = \_ -> do x <- systemOut "./preproc" ["darcs.lhs"]
254 io $ writeFile "src/darcs_print.tex" x }
255 return ["src/darcs_print.pdf"]
256 `catchC` \_ -> do putS "WARNING: Couldn't find pdflatex, can't build docs"
257 return []
260 checkWindows = do amwin <- amInWindows
261 if amwin then do putV "apparently we're on windows..."
262 replace "@USE_MMAP@" False
263 define "WIN32"
264 ghcFlags ["-isrc/win32","-Isrc/win32"]
265 systemOut "hsc2hs" ["src/win32/System/Posix/Files.hsc"]
266 systemOut "hsc2hs" ["src/win32/System/Posix/IO.hsc"]
267 return ["src/win32/CtrlC_stub.o"]
268 else do putV "apparently we're not on windows..."
269 return []