46fad8a32cda4658853585d19099fb683356b6e1
[hadrian.git] / src / Rules / Gmp.hs
1 module Rules.Gmp (
2 gmpRules, gmpBuildPath, gmpObjectsDir, gmpLibraryH, gmpBuildInfoPath
3 ) where
4
5 import Base
6 import Context
7 import GHC
8 import Oracles.Setting
9 import Target
10 import Utilities
11
12 gmpBase :: FilePath
13 gmpBase = pkgPath integerGmp -/- "gmp"
14
15 gmpLibraryInTreeH :: FilePath
16 gmpLibraryInTreeH = "include/gmp.h"
17
18 gmpLibrary :: FilePath
19 gmpLibrary = ".libs/libgmp.a"
20
21 -- | GMP is considered a Stage1 package. This determines GMP build directory.
22 gmpContext :: Context
23 gmpContext = vanillaContext Stage1 integerGmp
24
25 -- | Build directory for in-tree GMP library.
26 gmpBuildPath :: Action FilePath
27 gmpBuildPath = buildRoot <&> (-/- stageString (stage gmpContext) -/- "gmp")
28
29 -- | GMP library header, relative to 'gmpBuildPath'.
30 gmpLibraryH :: FilePath
31 gmpLibraryH = "include/ghc-gmp.h"
32
33 -- | Directory for GMP library object files, relative to 'gmpBuildPath'.
34 gmpObjectsDir :: FilePath
35 gmpObjectsDir = "objs"
36
37 -- | Path to the GMP library buildinfo file.
38 gmpBuildInfoPath :: FilePath
39 gmpBuildInfoPath = pkgPath integerGmp -/- "integer-gmp.buildinfo"
40
41 configureEnvironment :: Action [CmdOption]
42 configureEnvironment = sequence [ builderEnvironment "CC" $ Cc CompileC Stage1
43 , builderEnvironment "AR" (Ar Unpack Stage1)
44 , builderEnvironment "NM" Nm ]
45
46 gmpRules :: Rules ()
47 gmpRules = do
48 -- Copy appropriate GMP header and object files
49 "//" ++ gmpLibraryH %> \header -> do
50 windows <- windowsHost
51 configMk <- readFile' $ gmpBase -/- "config.mk"
52 if not windows && -- TODO: We don't use system GMP on Windows. Fix?
53 any (`isInfixOf` configMk) [ "HaveFrameworkGMP = YES", "HaveLibGmp = YES" ]
54 then do
55 putBuild "| GMP library/framework detected and will be used"
56 copyFile (gmpBase -/- "ghc-gmp.h") header
57 else do
58 putBuild "| No GMP library/framework detected; in tree GMP will be built"
59 gmpPath <- gmpBuildPath
60 need [gmpPath -/- gmpLibrary]
61 createDirectory (gmpPath -/- gmpObjectsDir)
62 top <- topDirectory
63 build $ target gmpContext (Ar Unpack Stage1)
64 [top -/- gmpPath -/- gmpLibrary] [gmpPath -/- gmpObjectsDir]
65 copyFile (gmpPath -/- "gmp.h") header
66 copyFile (gmpPath -/- "gmp.h") (gmpPath -/- gmpLibraryInTreeH)
67
68 -- Build in-tree GMP library
69 "//" ++ gmpLibrary %> \lib -> do
70 gmpPath <- gmpBuildPath
71 build $ target gmpContext (Make gmpPath) [gmpPath -/- "Makefile"] [lib]
72 putSuccess "| Successfully built custom library 'gmp'"
73
74 -- In-tree GMP header is built by the gmpLibraryH rule
75 "//" ++ gmpLibraryInTreeH %> \_ -> do
76 gmpPath <- gmpBuildPath
77 need [gmpPath -/- gmpLibraryH]
78
79 -- This causes integerGmp package to be configured, hence creating the files
80 [gmpBase -/- "config.mk", gmpBuildInfoPath] &%> \_ -> do
81 dataFile <- pkgDataFile gmpContext
82 need [dataFile]
83
84 -- Run GMP's configure script
85 -- TODO: Get rid of hard-coded @gmp@.
86 "//gmp/Makefile" %> \mk -> do
87 env <- configureEnvironment
88 gmpPath <- gmpBuildPath
89 need [mk <.> "in"]
90 buildWithCmdOptions env $
91 target gmpContext (Configure gmpPath) [mk <.> "in"] [mk]
92
93 -- Extract in-tree GMP sources and apply patches
94 "//gmp/Makefile.in" %> \_ -> do
95 gmpPath <- gmpBuildPath
96 removeDirectory gmpPath
97 -- Note: We use a tarball like gmp-4.2.4-nodoc.tar.bz2, which is
98 -- gmp-4.2.4.tar.bz2 repacked without the doc/ directory contents.
99 -- That's because the doc/ directory contents are under the GFDL,
100 -- which causes problems for Debian.
101 tarball <- unifyPath . fromSingleton "Exactly one GMP tarball is expected"
102 <$> getDirectoryFiles "" [gmpBase -/- "gmp-tarballs/gmp*.tar.bz2"]
103
104 withTempDir $ \dir -> do
105 let tmp = unifyPath dir
106 need [tarball]
107 build $ target gmpContext (Tar Extract) [tarball] [tmp]
108
109 let patch = gmpBase -/- "gmpsrc.patch"
110 patchName = takeFileName patch
111 copyFile patch $ tmp -/- patchName
112 applyPatch tmp patchName
113
114 let name = dropExtension . dropExtension $ takeFileName tarball
115 unpack = fromMaybe . error $ "gmpRules: expected suffix "
116 ++ "-nodoc (found: " ++ name ++ ")."
117 libName = unpack $ stripSuffix "-nodoc" name
118
119 moveDirectory (tmp -/- libName) gmpPath