d98bc3b6626be3aa7656a687710f295b9caa0fc0
[ghc.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" $ Cc Compile Stage1
41 , builderEnv "AR" Ar
42 , builderEnv "NM" Nm ]
43 where
44 builderEnv var bld = do
45 needBuilder bld
46 path <- builderPath bld
47 return $ AddEnv var path
48
49 -- TODO: we rebuild gmp every time.
50 gmpRules :: Rules ()
51 gmpRules = do
52 -- TODO: split into multiple rules
53 gmpLibraryH %> \_ -> do
54 when trackBuildSystem $ need [sourcePath -/- "Rules/Gmp.hs"]
55 removeDirectoryIfExists gmpBuildPath
56
57 -- We don't use system GMP on Windows. TODO: fix?
58 windows <- windowsHost
59 configMk <- readFile' $ gmpBase -/- "config.mk"
60 if not windows && any (`isInfixOf` configMk)
61 [ "HaveFrameworkGMP = YES", "HaveLibGmp = YES" ]
62 then do
63 putBuild "| GMP library/framework detected and will be used"
64 createDirectory $ takeDirectory gmpLibraryH
65 copyFile gmpLibraryFakeH gmpLibraryH
66 else do
67 putBuild "| No GMP library/framework detected; in tree GMP will be built"
68
69 -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is
70 -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents.
71 -- That's because the doc/ directory contents are under the GFDL,
72 -- which causes problems for Debian.
73 tarballs <- getDirectoryFiles "" [gmpBase -/- "tarball/gmp*.tar.bz2"]
74 tarball <- case tarballs of
75 [file] -> return $ unifyPath file
76 _ -> putError $ "gmpRules: exactly one tarball expected"
77 ++ "(found: " ++ show tarballs ++ ")."
78
79 withTempDir $ \dir -> do
80 let tmp = unifyPath dir
81 need [tarball]
82 build $ Target gmpContext Tar [tarball] [tmp]
83
84 forM_ gmpPatches $ \src -> do
85 let patch = takeFileName src
86 patchPath = tmp -/- patch
87 copyFile src patchPath
88 applyPatch tmp patch
89
90 let name = dropExtension . dropExtension $ takeFileName tarball
91 libName <- case stripSuffix "-nodoc-patched" name of
92 Just rest -> return rest
93 Nothing -> putError $ "gmpRules: expected suffix "
94 ++ "-nodoc-patched (found: " ++ name ++ ")."
95
96 moveDirectory (tmp -/- libName) gmpBuildPath
97
98 env <- configureEnvironment
99 buildWithCmdOptions env $
100 Target gmpContext (Configure gmpBuildPath)
101 [gmpBuildPath -/- "Makefile.in"]
102 [gmpBuildPath -/- "Makefile"]
103
104 runMake gmpBuildPath ["MAKEFLAGS="]
105
106 createDirectory $ takeDirectory gmpLibraryH
107 copyFile (gmpBuildPath -/- "gmp.h") gmpLibraryH
108 copyFile (gmpBuildPath -/- "gmp.h") gmpLibraryInTreeH
109 moveFile (gmpBuildPath -/- ".libs/libgmp.a") gmpLibrary
110
111 createDirectory gmpObjects
112 build $ Target gmpContext Ar [gmpLibrary] [gmpObjects]
113
114 runBuilder Ranlib [gmpLibrary]
115
116 putSuccess "| Successfully built custom library 'gmp'"
117
118 gmpLibraryInTreeH %> \_ -> need [gmpLibraryH]
119
120 -- This causes integerGmp package to be configured, hence creating the files
121 [gmpBase -/- "config.mk", gmpBuildInfoPath] &%> \_ ->
122 need [pkgDataFile gmpContext]