Program.hs 2.83 KB
Newer Older
Andrey Mokhov's avatar
Andrey Mokhov committed
1
2
module Rules.Program (buildProgram) where

Ben Gamari's avatar
Ben Gamari committed
3
4
import Data.Char

Andrey Mokhov's avatar
Andrey Mokhov committed
5
import Expression hiding (splitPath)
Andrey Mokhov's avatar
Andrey Mokhov committed
6
import GHC hiding (ghci)
Andrey Mokhov's avatar
Andrey Mokhov committed
7
8
9
10
11
import Oracles
import Rules.Actions
import Rules.Library
import Rules.Resources
import Settings
12
import Settings.Builders.GhcCabal
Andrey Mokhov's avatar
Andrey Mokhov committed
13

14
-- TODO: Get rid of the Paths_hsc2hs.o hack.
15
-- TODO: Do we need to consider other ways when building programs?
Andrey Mokhov's avatar
Andrey Mokhov committed
16
17
buildProgram :: Resources -> PartialTarget -> Rules ()
buildProgram _ target @ (PartialTarget stage pkg) = do
Andrey Mokhov's avatar
Andrey Mokhov committed
18
19
20
21
22
    let path       = targetPath stage pkg
        buildPath  = path -/- "build"
        match file = case programPath stage pkg of
            Nothing      -> False
            Just prgPath -> ("//" ++ prgPath) ?== file
Andrey Mokhov's avatar
Andrey Mokhov committed
23

Andrey Mokhov's avatar
Andrey Mokhov committed
24
    match ?> \bin -> do
Andrey Mokhov's avatar
Andrey Mokhov committed
25
26
        cSrcs <- cSources target -- TODO: remove code duplication (Library.hs)
        hSrcs <- hSources target
Andrey Mokhov's avatar
Andrey Mokhov committed
27
28
29
30
        let cObjs = [ buildPath -/- src -<.> osuf vanilla | src <- cSrcs   ]
            hObjs = [ buildPath -/- src  <.> osuf vanilla | src <- hSrcs   ]
                 ++ [ buildPath -/- "Paths_hsc2hs.o"      | pkg == hsc2hs  ]
                 ++ [ buildPath -/- "Paths_haddock.o"     | pkg == haddock ]
Andrey Mokhov's avatar
Andrey Mokhov committed
31
            objs  = cObjs ++ hObjs
32
        ways     <- interpretPartial target getWays
33
        depNames <- interpretPartial target $ getPkgDataList TransitiveDepNames
34
35
36
37
        let libStage  = min stage Stage1 -- libraries are built only in Stage0/1
            libTarget = PartialTarget libStage pkg
        pkgs     <- interpretPartial libTarget getPackages
        ghciFlag <- interpretPartial libTarget $ getPkgData BuildGhciLib
38
        let deps = matchPackageNames (sort pkgs) (map PackageName $ sort depNames)
39
40
            ghci = ghciFlag == "YES" && stage == Stage1
        libs <- fmap concat . forM deps $ \dep -> do
41
            let depTarget = PartialTarget libStage dep
42
43
            compId <- interpretPartial depTarget $ getPkgData ComponentId
            libFiles <- fmap concat . forM ways $ \way -> do
44
45
46
                libFile  <- pkgLibraryFile libStage dep compId           way
                lib0File <- pkgLibraryFile libStage dep (compId ++ "-0") way
                dll0     <- needDll0 libStage dep
47
                return $ [ libFile ] ++ [ lib0File | dll0 ]
48
            return $ libFiles ++ [ pkgGhciLibraryFile libStage dep compId | ghci ]
Andrey Mokhov's avatar
Andrey Mokhov committed
49
50
        let binDeps = if pkg == ghcCabal && stage == Stage0
                      then [ pkgPath pkg -/- src <.> "hs" | src <- hSrcs ]
51
52
                      else objs
        need $ binDeps ++ libs
Andrey Mokhov's avatar
Andrey Mokhov committed
53
        build $ fullTargetWithWay target (Ghc stage) vanilla binDeps [bin]
Andrey Mokhov's avatar
Andrey Mokhov committed
54
        synopsis <- interpretPartial target $ getPkgData Synopsis
Ben Gamari's avatar
Ben Gamari committed
55
56
        putSuccess $ renderBox
            [ "Successfully built program '"
57
              ++ pkgNameString pkg ++ "' (" ++ show stage ++ ")."
Ben Gamari's avatar
Ben Gamari committed
58
            , "Executable: " ++ bin
Andrey Mokhov's avatar
Andrey Mokhov committed
59
            , "Package synopsis: " ++ dropWhileEnd isPunctuation synopsis ++ "." ]