summaryrefslogtreecommitdiff
path: root/hadrian/src/Rules/SourceDist.hs
blob: 8eb215d9eaf34745eda6f54fed665b0ca2e84653 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
module Rules.SourceDist (sourceDistRules) where

import Hadrian.Oracles.DirectoryContents

import Base
import Builder
import Context
import Oracles.Setting
import Packages
import Rules.Clean

sourceDistRules :: Rules ()
sourceDistRules = do
    root <- buildRootRules
    "source-dist" ~> do
        -- We clean the source tree first.
        -- See https://github.com/snowleopard/hadrian/issues/384.
        -- TODO: Do we still need to clean the tree?
        cleanSourceTree
        version <- setting ProjectVersion
        need [root -/- "source-dist" -/- ("ghc-" ++ version ++ "-src.tar.xz")]
        putSuccess "| Done"
    root -/- "source-dist" -/- "ghc-*-src.tar.xz" %> \fname -> do
        let tarName   = takeFileName fname
            dropTarXz = dropExtension . dropExtension
            treePath  = root -/- "source-dist" -/- dropTarXz tarName
        prepareTree treePath
        runBuilder
            (Tar Create)
            ["cJf", fname,  treePath]
            ["cJf", fname] [treePath]
    "GIT_COMMIT_ID" %> \fname ->
        writeFileChanged fname =<< setting ProjectGitCommitId
    "VERSION" %> \fname ->
        writeFileChanged fname =<< setting ProjectVersion

prepareTree :: FilePath -> Action ()
prepareTree dest = do
    root <- buildRoot
    mapM_ cpDir  srcDirs
    mapM_ cpFile srcFiles
    copyAlexHappyFiles root
  where

    copyAlexHappyFiles root =
      forM_ alexHappyFiles $ \(stg, pkg, inp, srcDir, out) -> do
        let dir = root -/- buildDir (Context stg pkg vanilla)
            srcInputFile = dest -/- pkgPath pkg -/- maybe id (-/-) srcDir inp
        -- We first make sure that the generated file is... generated.
        need [ dir -/- out ]
        -- We then copy the generated file in the source dist, right
        -- next to the input file.
        copyFile (dir -/- out)
                 (dest -/- pkgPath pkg -/- maybe id (-/-) srcDir out)
        -- We finally add a ".source" suffix to the input file to
        -- prevent it from being used when building GHC, since the
        -- generated file being there already should prevent
        -- the need for the original input.
        moveFile srcInputFile (srcInputFile <.> "source")

    cpFile a = copyFile a (dest -/- a)
    cpDir  a = copyDirectoryContents (Not excluded) a (dest -/- a)
    excluded = Or
        [ Test "**/.*"
        , Test "**/#*"
        , Test "**/*-SAVE"
        , Test "**/*.orig"
        , Test "**/*.rej"
        , Test "**/*~"
        , Test "**/autom4te*"
        , Test "**/dist"
        , Test "**/dist-install"
        , Test "**/log"
        , Test "**/stage0"
        , Test "**/stage1"
        , Test "**/stage2"
        , Test "**/stage3"
        , Test "hadrian/.cabal-sandbox"
        , Test "hadrian/.stack-work"
        , Test "hadrian/UserSettings.hs"
        , Test "hadrian/cabal.sandbox.config"
        , Test "hadrian/cfg/system.config"
        , Test "hadrian/bin"
        , Test "hadrian/dist"
        , Test "hadrian/dist-newstyle"
        , Test "libraries/**/*.buildinfo"
        , Test "libraries/**/GNUmakefile"
        , Test "libraries/**/config.log"
        , Test "libraries/**/config.status"
        , Test "libraries/**/ghc.mk"
        , Test "libraries/**/include/Hs*Config.h"
        , Test "libraries/dph"
        , Test "libraries/primitive"
        , Test "libraries/random"
        , Test "libraries/vector"
        , Test "rts/rts.cabal"
        , Test "mk/build.mk" ]
    srcDirs =
        [ "bindisttest"
        , "compiler"
        , "distrib"
        , "docs"
        , "docs"
        , "driver"
        , "ghc"
        , "hadrian"
        , "includes"
        , "libffi"
        , "libffi-tarballs"
        , "libraries"
        , "mk"
        , "rts"
        , "rules"
        , "utils" ]
    srcFiles =
        [ "GIT_COMMIT_ID"
        , "HACKING.md"
        , "INSTALL.md"
        , "LICENSE"
        , "MAKEHELP.md"
        , "Makefile"
        , "README.md"
        , "VERSION"
        , "aclocal.m4"
        , "boot"
        , "config.guess"
        , "config.sub"
        , "configure"
        , "configure.ac"
        , "ghc.mk"
        , "install-sh"
        , "packages"
        , "llvm-targets"
        , "llvm-passes"
        ]

    -- (stage, package, input file, dir, output file)
    --
    -- where "dir" is the subdirectory of the package's directory
    -- where the input file resides and where we're supposed to
    -- put the output file, in the source distribution.
    --
    -- This list was taken from ghc.mk. The treatment of those
    -- alex/happy files is exactly the one implemented in ghc.mk,
    -- where Make ends up calling 'sdist-ghc-file' on all those
    -- files, which implements exactly the logic that we
    -- have for 'alexHappyFiles' above.
    alexHappyFiles =
        [ (Stage0, compiler, "CmmParse.y", Just "cmm", "CmmParse.hs")
        , (Stage0, compiler, "CmmLex.x", Just "cmm", "CmmLex.hs")
        , (Stage0, compiler, "Parser.y", Just "parser", "Parser.hs")
        , (Stage0, compiler, "Lexer.x", Just "parser", "Lexer.hs")
        , (Stage0, hpcBin, "HpcParser.y", Nothing, "HpcParser.hs")
        , (Stage0, genprimopcode, "Parser.y", Nothing, "Parser.hs")
        , (Stage0, genprimopcode, "Lexer.x", Nothing, "Lexer.hs")
        ]