78b45870b947baa449102e827c17e4d8e314f018
[hadrian.git] / src / Settings / Builders / GhcCabal.hs
1 module Settings.Builders.GhcCabal (
2 ghcCabalBuilderArgs
3 ) where
4
5 import Hadrian.Haskell.Cabal
6
7 import Context
8 import Flavour
9 import Settings.Builders.Common
10
11 ghcCabalBuilderArgs :: Args
12 ghcCabalBuilderArgs = builder GhcCabal ? do
13 verbosity <- expr getVerbosity
14 top <- expr topDirectory
15 path <- getBuildPath
16 notStage0 ? expr (need inplaceLibCopyTargets)
17 mconcat [ arg "configure"
18 , arg =<< pkgPath <$> getPackage
19 , arg $ top -/- path
20 , withStaged $ Ghc CompileHs
21 , withStaged (GhcPkg Update)
22 , bootPackageDatabaseArgs
23 , libraryArgs
24 , configureArgs
25 , bootPackageConstraints
26 , withStaged $ Cc CompileC
27 , notStage0 ? with Ld
28 , withStaged (Ar Pack)
29 , with Alex
30 , with Happy
31 , verbosity < Chatty ? pure [ "-v0", "--configure-option=--quiet"
32 , "--configure-option=--disable-option-checking" ] ]
33
34 -- TODO: Isn't vanilla always built? If yes, some conditions are redundant.
35 -- TODO: Need compiler_stage1_CONFIGURE_OPTS += --disable-library-for-ghci?
36 libraryArgs :: Args
37 libraryArgs = do
38 ways <- getLibraryWays
39 withGhci <- expr ghcWithInterpreter
40 dynPrograms <- dynamicGhcPrograms <$> expr flavour
41 pure [ if vanilla `elem` ways
42 then "--enable-library-vanilla"
43 else "--disable-library-vanilla"
44 , if vanilla `elem` ways && withGhci && not dynPrograms
45 then "--enable-library-for-ghci"
46 else "--disable-library-for-ghci"
47 , if profiling `elem` ways
48 then "--enable-library-profiling"
49 else "--disable-library-profiling"
50 , if dynamic `elem` ways
51 then "--enable-shared"
52 else "--disable-shared" ]
53
54 -- TODO: LD_OPTS?
55 configureArgs :: Args
56 configureArgs = do
57 top <- expr topDirectory
58 root <- getBuildRoot
59 pkg <- getPackage
60 let conf key expr = do
61 values <- unwords <$> expr
62 not (null values) ?
63 arg ("--configure-option=" ++ key ++ "=" ++ values)
64 cFlags = mconcat [ remove ["-Werror"] cArgs
65 , getStagedSettingList ConfCcArgs
66 , arg $ "-I" ++ top -/- root -/- generatedDir
67 -- See https://github.com/snowleopard/hadrian/issues/523
68 , arg $ "-I" ++ top -/- pkgPath pkg
69 , arg $ "-I" ++ top -/- "includes" ]
70 ldFlags = ldArgs <> (getStagedSettingList ConfGccLinkerArgs)
71 cppFlags = cppArgs <> (getStagedSettingList ConfCppArgs)
72 cldFlags <- unwords <$> (cFlags <> ldFlags)
73 mconcat
74 [ conf "CFLAGS" cFlags
75 , conf "LDFLAGS" ldFlags
76 , conf "CPPFLAGS" cppFlags
77 , not (null cldFlags) ? arg ("--gcc-options=" ++ cldFlags)
78 , conf "--with-iconv-includes" $ arg =<< getSetting IconvIncludeDir
79 , conf "--with-iconv-libraries" $ arg =<< getSetting IconvLibDir
80 , conf "--with-gmp-includes" $ arg =<< getSetting GmpIncludeDir
81 , conf "--with-gmp-libraries" $ arg =<< getSetting GmpLibDir
82 , conf "--with-curses-libraries" $ arg =<< getSetting CursesLibDir
83 , crossCompiling ? (conf "--host" $ arg =<< getSetting TargetPlatformFull)
84 , conf "--with-cc" $ arg =<< getBuilderPath . (Cc CompileC) =<< getStage ]
85
86 bootPackageConstraints :: Args
87 bootPackageConstraints = stage0 ? do
88 bootPkgs <- expr $ stagePackages Stage0
89 let pkgs = filter (\p -> p /= compiler && isLibrary p) bootPkgs
90 constraints <- expr $ fmap catMaybes $ forM (sort pkgs) $ \pkg -> do
91 version <- traverse pkgVersion (pkgCabalFile pkg)
92 return $ fmap ((pkgName pkg ++ " == ") ++) version
93 pure $ concat [ ["--constraint", c] | c <- constraints ]
94
95 cppArgs :: Args
96 cppArgs = do
97 root <- getBuildRoot
98 arg $ "-I" ++ root -/- generatedDir
99
100 withBuilderKey :: Builder -> String
101 withBuilderKey b = case b of
102 Ar _ _ -> "--with-ar="
103 Ld -> "--with-ld="
104 Cc _ _ -> "--with-gcc="
105 Ghc _ _ -> "--with-ghc="
106 Alex -> "--with-alex="
107 Happy -> "--with-happy="
108 GhcPkg _ _ -> "--with-ghc-pkg="
109 _ -> error $ "withBuilderKey: not supported builder " ++ show b
110
111 -- Expression 'with Alex' appends "--with-alex=/path/to/alex" and needs Alex.
112 with :: Builder -> Args
113 with b = do
114 path <- getBuilderPath b
115 if (null path) then mempty else do
116 top <- expr topDirectory
117 expr $ needBuilder b
118 arg $ withBuilderKey b ++ unifyPath (top </> path)
119
120 withStaged :: (Stage -> Builder) -> Args
121 withStaged sb = with . sb =<< getStage
122