Compile.hs 2.29 KB
Newer Older
1
{-# LANGUAGE NoImplicitPrelude #-}
Andrey Mokhov's avatar
Andrey Mokhov committed
2
3
4
5
6
module Package.Compile (buildPackageCompile) where

import Package.Base
import Development.Shake.Util

7
8
argListDir :: FilePath
argListDir = "shake/arg/buildPackageCompile"
Andrey Mokhov's avatar
Andrey Mokhov committed
9
10

suffixArgs :: Way -> Args
11
12
13
suffixArgs way = arg ["-hisuf", hisuf way]
              <> arg [ "-osuf",  osuf way]
              <> arg ["-hcsuf", hcsuf way]
Andrey Mokhov's avatar
Andrey Mokhov committed
14

15
16
ghcArgs :: Package -> TodoItem -> Way -> [FilePath] -> FilePath -> Args
ghcArgs (Package _ path _) (stage, dist, _) way srcs result =
Andrey Mokhov's avatar
Andrey Mokhov committed
17
    let buildDir = toStandard $ path </> dist </> "build"
Andrey Mokhov's avatar
Andrey Mokhov committed
18
        pkgData  = path </> dist </> "package-data.mk"
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    in suffixArgs way
    <> wayHcArgs way
    <> arg SrcHcOpts
    <> packageArgs stage pkgData
    <> includeArgs path dist
    <> concatArgs ["-optP"] (CppOpts pkgData)
    <> arg (HsOpts pkgData)
    -- TODO: now we have both -O and -O2
    -- <> arg ["-O2"]
    <> productArgs ["-odir", "-hidir", "-stubdir"] buildDir
    <> when (splitObjects stage) (arg "-split-objs")
    <> arg ("-c":srcs)
    <> arg ["-o", result]

buildRule :: Package -> TodoItem -> Rules ()
buildRule pkg @ (Package name path _) todo @ (stage, dist, _) =
    let buildDir = toStandard $ path </> dist </> "build"
36
        depFile  = buildDir </> takeBaseName name <.> "m"
Andrey Mokhov's avatar
Andrey Mokhov committed
37
    in
38
    [buildDir <//> "*o", buildDir <//> "*hi"] &%> \[out, _] -> do
Andrey Mokhov's avatar
Andrey Mokhov committed
39
        let way  = detectWay $ tail $ takeExtension out
40
        need [argListPath argListDir pkg stage, depFile]
Andrey Mokhov's avatar
Andrey Mokhov committed
41
42
        depContents <- parseMakefile <$> (liftIO $ readFile depFile)
        let deps = concat $ snd $ unzip $ filter ((== out) . fst) depContents
43
            srcs = filter ("//*hs" ?==) deps -- TODO: handle *.c sources
Andrey Mokhov's avatar
Andrey Mokhov committed
44
        need deps
45
        terseRun (Ghc stage) $ ghcArgs pkg todo way srcs (toStandard out)
Andrey Mokhov's avatar
Andrey Mokhov committed
46

47
48
49
50
51
52
53
54
55
56
57
58
59
argListRule :: Package -> TodoItem -> Rules ()
argListRule pkg todo @ (stage, _, settings) =
    (argListPath argListDir pkg stage) %> \out -> do
        need $ ["shake/src/Package/Compile.hs"] ++ sourceDependecies
        ways' <- ways settings
        ghcList <- forM ways' $ \way ->
            argList (Ghc stage)
                (ghcArgs pkg todo way ["input.hs"] $ "output" <.> osuf way)
                $ "way '" ++ tag way ++ "'"
        writeFileChanged out $ unlines ghcList

buildPackageCompile :: Package -> TodoItem -> Rules ()
buildPackageCompile = argListRule <> buildRule