Refactor paths using Context.
[hadrian.git] / src / Rules / Gmp.hs
1 module Rules.Gmp (gmpRules, gmpBuildPath, gmpObjects, gmpLibraryH) where
2
3 import Base
4 import Expression
5 import GHC
6 import Oracles.Config.Setting
7 import Rules.Actions
8 import Settings.Packages.IntegerGmp
9 import Settings.User
10 import Settings.Paths
11 import Target
12
13 gmpBase :: FilePath
14 gmpBase = "libraries/integer-gmp/gmp"
15
16 gmpContext :: Context
17 gmpContext = vanillaContext Stage1 integerGmp
18
19 gmpObjects :: FilePath
20 gmpObjects = gmpBuildPath -/- "objs"
21
22 gmpLibrary :: FilePath
23 gmpLibrary = gmpBuildPath -/- "libgmp.a"
24
25 gmpLibraryInTreeH :: FilePath
26 gmpLibraryInTreeH = gmpBuildPath -/- "include/gmp.h"
27
28 gmpLibraryH :: FilePath
29 gmpLibraryH = gmpBuildPath -/- "include/ghc-gmp.h"
30
31 gmpLibraryFakeH :: FilePath
32 gmpLibraryFakeH = gmpBase -/- "ghc-gmp.h"
33
34 gmpPatches :: [FilePath]
35 gmpPatches = (gmpBase -/-) <$> ["gmpsrc.patch", "tarball/gmp-5.0.4.patch"]
36
37 -- TODO: See Libffi.hs about removing code duplication.
38 configureEnvironment :: Action [CmdOption]
39 configureEnvironment = do
40 sequence [ builderEnv "CC" $ Gcc Stage1
41 , builderEnv "AR" Ar
42 , builderEnv "NM" Nm ]
43 where
44 builderEnv var bld = do
45 needBuilder False bld
46 path <- builderPath bld
47 return $ AddEnv var path
48
49 configureArguments :: Action [String]
50 configureArguments = do
51 hostPlatform <- setting HostPlatform
52 buildPlatform <- setting BuildPlatform
53 return [ "--enable-shared=no"
54 , "--host=" ++ hostPlatform
55 , "--build=" ++ buildPlatform]
56
57 -- TODO: we rebuild gmp every time.
58 gmpRules :: Rules ()
59 gmpRules = do
60 -- TODO: split into multiple rules
61 gmpLibraryH %> \_ -> do
62 when trackBuildSystem $ need [sourcePath -/- "Rules/Gmp.hs"]
63 liftIO $ removeFiles gmpBuildPath ["//*"]
64 createDirectory $ takeDirectory gmpLibraryH
65
66 -- We don't use system GMP on Windows. TODO: fix?
67 windows <- windowsHost
68 configMk <- readFile' $ gmpBase -/- "config.mk"
69 if not windows && any (`isInfixOf` configMk)
70 [ "HaveFrameworkGMP = YES", "HaveLibGmp = YES" ]
71 then do
72 putBuild "| GMP library/framework detected and will be used"
73 copyFile gmpLibraryFakeH gmpLibraryH
74 else do
75 putBuild "| No GMP library/framework detected; in tree GMP will be built"
76
77 -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is
78 -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents.
79 -- That's because the doc/ directory contents are under the GFDL,
80 -- which causes problems for Debian.
81 tarballs <- getDirectoryFiles "" [gmpBase -/- "tarball/gmp*.tar.bz2"]
82 when (length tarballs /= 1) $
83 putError $ "gmpRules: exactly one tarball expected"
84 ++ "(found: " ++ show tarballs ++ ")."
85
86 need tarballs
87 build $ Target gmpContext Tar tarballs [gmpBuildPath]
88
89 forM_ gmpPatches $ \src -> do
90 let patch = takeFileName src
91 patchPath = gmpBuildPath -/- patch
92 copyFile src patchPath
93 applyPatch gmpBuildPath patch
94
95 let filename = dropExtension . dropExtension . takeFileName $ head tarballs
96 suffix = "-nodoc-patched"
97 unless (suffix `isSuffixOf` filename) $
98 putError $ "gmpRules: expected suffix " ++ suffix
99 ++ " (found: " ++ filename ++ ")."
100 let libName = take (length filename - length suffix) filename
101 libPath = gmpBuildPath -/- libName
102
103 envs <- configureEnvironment
104 args <- configureArguments
105 runConfigure libPath envs args
106
107 runMake libPath ["MAKEFLAGS="]
108
109 copyFile (libPath -/- "gmp.h") gmpLibraryInTreeH
110 copyFile (libPath -/- "gmp.h") gmpLibraryH
111 -- TODO: why copy library, can we move it instead?
112 copyFile (libPath -/- ".libs/libgmp.a") gmpLibrary
113
114 createDirectory gmpObjects
115 build $ Target gmpContext Ar [gmpLibrary] [gmpObjects]
116
117 runBuilder Ranlib [gmpLibrary]
118
119 putSuccess "| Successfully built custom library 'gmp'"
120
121 gmpLibraryInTreeH %> \_ -> need [gmpLibraryH]
122
123 -- This causes integerGmp package to be configured, hence creating the files
124 [gmpBase -/- "config.mk", gmpBuildInfoPath] &%> \_ ->
125 need [pkgDataFile gmpContext]