Data.hs 4.12 KB
Newer Older
1
module Rules.Data (buildPackageData) where
2

3
import Expression
Andrey Mokhov's avatar
Andrey Mokhov committed
4
import GHC
5
import Oracles
6
import Predicates (registerPackage)
Andrey Mokhov's avatar
Andrey Mokhov committed
7
import Rules.Actions
8
import Rules.Resources
9
import Settings
Andrey Mokhov's avatar
Andrey Mokhov committed
10
import Settings.Builders.GhcCabal
11
12

-- Build package-data.mk by using GhcCabal to process pkgCabal file
13
14
buildPackageData :: Resources -> PartialTarget -> Rules ()
buildPackageData rs target @ (PartialTarget stage pkg) = do
15
    let cabalFile = pkgCabalFile pkg
Andrey Mokhov's avatar
Andrey Mokhov committed
16
        configure = pkgPath pkg -/- "configure"
Andrey Mokhov's avatar
Andrey Mokhov committed
17
        dataFile  = pkgDataFile stage pkg
18

Andrey Mokhov's avatar
Andrey Mokhov committed
19
20
21
22
    dataFile %> \mk -> do
        -- GhcCabal may run the configure script, so we depend on it
        -- We don't know who built the configure script from configure.ac
        whenM (doesFileExist $ configure <.> "ac") $ need [configure]
23

Andrey Mokhov's avatar
Andrey Mokhov committed
24
25
26
27
28
        -- We configure packages in the order of their dependencies
        deps <- packageDeps pkg
        pkgs <- interpretPartial target getPackages
        let depPkgs = matchPackageNames (sort pkgs) deps
        need $ map (pkgDataFile stage) depPkgs
29

Andrey Mokhov's avatar
Andrey Mokhov committed
30
31
32
        need [cabalFile]
        buildWithResources [(resGhcCabal rs, 1)] $
            fullTarget target GhcCabal [cabalFile] [mk]
33

Andrey Mokhov's avatar
Andrey Mokhov committed
34
35
36
37
38
39
        -- ghc-pkg produces inplace-pkg-config when run on packages with
        -- library components only
        when (isLibrary pkg) .
            whenM (interpretPartial target registerPackage) .
            buildWithResources [(resGhcPkg rs, 1)] $
            fullTarget target (GhcPkg stage) [cabalFile] [mk]
40

Andrey Mokhov's avatar
Andrey Mokhov committed
41
        postProcessPackageData dataFile
42

Andrey Mokhov's avatar
Andrey Mokhov committed
43
44
    -- TODO: PROGNAME was $(CrossCompilePrefix)hp2ps
    -- TODO: code duplication around ghcIncludeDirs
Andrey Mokhov's avatar
Andrey Mokhov committed
45
46
    priority 2.0 $ do
        when (pkg == hp2ps) $ dataFile %> \mk -> do
Andrey Mokhov's avatar
Andrey Mokhov committed
47
48
49
50
51
52
53
54
55
56
57
58
59
            let prefix = "utils_hp2ps_stage" ++ show (fromEnum stage) ++ "_"
                cSrcs  = [ "AreaBelow.c", "Curves.c", "Error.c", "Main.c"
                         , "Reorder.c", "TopTwenty.c", "AuxFile.c"
                         , "Deviation.c", "HpFile.c", "Marks.c", "Scale.c"
                         , "TraceElement.c", "Axes.c", "Dimensions.c", "Key.c"
                         , "PsFile.c", "Shade.c", "Utilities.c" ]
                contents = unlines $ map (prefix++)
                    [ "PROGNAME = hp2ps"
                    , "C_SRCS = " ++ unwords cSrcs
                    , "INSTALL = YES"
                    , "INSTALL_INPLACE = YES"
                    , "DEP_EXTRA_LIBS = m"
                    , "CC_OPTS = " ++ unwords (map ("-I"++) ghcIncludeDirs) ]
Andrey Mokhov's avatar
Andrey Mokhov committed
60
61
62
63
64
65
66
67
            writeFileChanged mk contents
            putBuild $ "| Successfully generated '" ++ mk ++ "'."

        -- Bootstrapping `ghcCabal`: although `ghcCabal` is a proper cabal
        -- package, we cannot generate the corresponding `package-data.mk` file
        -- by running by running `ghcCabal`, because it has not yet been built.
        when (pkg == ghcCabal && stage == Stage0) $ dataFile %> \mk -> do
            let contents = unlines
68
69
70
71
                    [ "utils_ghc-cabal_stage0_PROGNAME = ghc-cabal"
                    , "utils_ghc-cabal_stage0_MODULES = Main"
                    , "utils_ghc-cabal_stage0_SYNOPSIS = Bootstrapped ghc-cabal utility."
                    , "utils_ghc-cabal_stage0_HS_SRC_DIRS = ." ]
Andrey Mokhov's avatar
Andrey Mokhov committed
72
73
            writeFileChanged mk contents
            putBuild $ "| Successfully generated '" ++ mk ++ "'."
Andrey Mokhov's avatar
Andrey Mokhov committed
74

Andrey Mokhov's avatar
Andrey Mokhov committed
75
76
77
78
79
80
81
82
83
84
85
-- Prepare a given 'packaga-data.mk' file for parsing by readConfigFile:
-- 1) Drop lines containing '$'
-- For example, get rid of
-- libraries/Win32_dist-install_CMM_SRCS  := $(addprefix cbits/,$(notdir ...
-- Reason: we don't need them and we can't parse them.
-- 2) Replace '/' and '\' with '_' before '='
-- For example libraries/deepseq/dist-install_VERSION = 1.4.0.0
-- is replaced by libraries_deepseq_dist-install_VERSION = 1.4.0.0
-- Reason: Shake's built-in makefile parser doesn't recognise slashes
postProcessPackageData :: FilePath -> Action ()
postProcessPackageData file = do
86
87
    contents <- fmap (filter ('$' `notElem`) . lines) . liftIO $ readFile file
    length contents `seq` writeFileLines file $ map processLine contents
Andrey Mokhov's avatar
Andrey Mokhov committed
88
89
90
91
      where
        processLine line = replaceSeparators '_' prefix ++ suffix
          where
            (prefix, suffix) = break (== '=') line