962ce1d7493a6bb6a230d05bb7aa87d6d427c7bd
[hadrian.git] / src / Rules / Program.hs
1 module Rules.Program (buildProgram) where
2
3 import Data.Char
4
5 import Expression hiding (splitPath)
6 import GHC hiding (ghci)
7 import Oracles
8 import Rules.Actions
9 import Rules.Library
10 import Rules.Resources
11 import Settings
12 import Settings.Builders.GhcCabal
13
14 -- TODO: Get rid of the Paths_hsc2hs.o hack.
15 -- TODO: Do we need to consider other ways when building programs?
16 buildProgram :: Resources -> PartialTarget -> Rules ()
17 buildProgram _ target @ (PartialTarget stage pkg) = do
18 let path = targetPath stage pkg
19 buildPath = path -/- "build"
20 match file = case programPath stage pkg of
21 Nothing -> False
22 Just prgPath -> ("//" ++ prgPath) ?== file
23
24 match ?> \bin -> do
25 cSrcs <- cSources target -- TODO: remove code duplication (Library.hs)
26 hSrcs <- hSources target
27 let cObjs = [ buildPath -/- src -<.> osuf vanilla | src <- cSrcs ]
28 hObjs = [ buildPath -/- src <.> osuf vanilla | src <- hSrcs ]
29 ++ [ buildPath -/- "Paths_hsc2hs.o" | pkg == hsc2hs ]
30 ++ [ buildPath -/- "Paths_haddock.o" | pkg == haddock ]
31 objs = cObjs ++ hObjs
32 ways <- interpretPartial target getWays
33 depNames <- interpretPartial target $ getPkgDataList TransitiveDepNames
34 let libStage = min stage Stage1 -- libraries are built only in Stage0/1
35 libTarget = PartialTarget libStage pkg
36 pkgs <- interpretPartial libTarget getPackages
37 ghciFlag <- interpretPartial libTarget $ getPkgData BuildGhciLib
38 let deps = matchPackageNames (sort pkgs) (map PackageName $ sort depNames)
39 ghci = ghciFlag == "YES" && stage == Stage1
40 libs <- fmap concat . forM deps $ \dep -> do
41 let depTarget = PartialTarget libStage dep
42 compId <- interpretPartial depTarget $ getPkgData ComponentId
43 libFiles <- fmap concat . forM ways $ \way -> do
44 libFile <- pkgLibraryFile libStage dep compId way
45 lib0File <- pkgLibraryFile libStage dep (compId ++ "-0") way
46 dll0 <- needDll0 libStage dep
47 return $ [ libFile ] ++ [ lib0File | dll0 ]
48 return $ libFiles ++ [ pkgGhciLibraryFile libStage dep compId | ghci ]
49 let binDeps = if pkg == ghcCabal && stage == Stage0
50 then [ pkgPath pkg -/- src <.> "hs" | src <- hSrcs ]
51 else objs
52 need $ binDeps ++ libs
53 build $ fullTargetWithWay target (Ghc stage) vanilla binDeps [bin]
54 synopsis <- interpretPartial target $ getPkgData Synopsis
55 putSuccess $ renderBox
56 [ "Successfully built program '"
57 ++ pkgNameString pkg ++ "' (" ++ show stage ++ ")."
58 , "Executable: " ++ bin
59 , "Package synopsis: " ++ dropWhileEnd isPunctuation synopsis ++ "." ]