Build deriveConstants utility.
[hadrian.git] / src / Oracles / PackageData.hs
1 {-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
2 module Oracles.PackageData (
3 PackageData (..), PackageDataList (..),
4 pkgData, pkgDataList, packageDataOracle
5 ) where
6
7 import Base
8 import qualified Data.HashMap.Strict as Map
9
10 -- For each (PackageData path) the file 'path/package-data.mk' contains
11 -- a line of the form 'path_VERSION = 1.2.3.4'.
12 -- pkgData $ PackageData path is an action that consults the file and
13 -- returns "1.2.3.4".
14 --
15 -- PackageDataList is used for multiple string options separated by spaces,
16 -- such as 'path_MODULES = Data.Array Data.Array.Base ...'.
17 -- pkgListData Modules therefore returns ["Data.Array", "Data.Array.Base", ...]
18 data PackageData = BuildGhciLib FilePath
19 | LibName FilePath
20 | PackageKey FilePath
21 | Synopsis FilePath
22 | Version FilePath
23
24 data PackageDataList = CcArgs FilePath
25 | CSrcs FilePath
26 | CppArgs FilePath
27 | DepCcArgs FilePath
28 | DepExtraLibs FilePath
29 | DepIds FilePath
30 | DepIncludeDirs FilePath
31 | DepLdArgs FilePath
32 | DepLibDirs FilePath
33 | DepNames FilePath
34 | Deps FilePath
35 | HiddenModules FilePath
36 | HsArgs FilePath
37 | IncludeDirs FilePath
38 | LdArgs FilePath
39 | Modules FilePath
40 | SrcDirs FilePath
41
42 newtype PackageDataKey = PackageDataKey (FilePath, String)
43 deriving (Show, Typeable, Eq, Hashable, Binary, NFData)
44
45 askPackageData :: FilePath -> String -> Action String
46 askPackageData path key = do
47 let fullKey = replaceSeparators '_' $ path ++ "_" ++ key
48 file = path -/- "package-data.mk"
49 maybeValue <- askOracle $ PackageDataKey (file, fullKey)
50 case maybeValue of
51 Nothing -> return ""
52 Just value -> return value
53 -- Nothing -> putError $ "No key '" ++ key ++ "' in " ++ file ++ "."
54
55 pkgData :: PackageData -> Action String
56 pkgData packageData = case packageData of
57 BuildGhciLib path -> askPackageData path "BUILD_GHCI_LIB"
58 LibName path -> askPackageData path "LIB_NAME"
59 PackageKey path -> askPackageData path "PACKAGE_KEY"
60 Synopsis path -> askPackageData path "SYNOPSIS"
61 Version path -> askPackageData path "VERSION"
62
63 pkgDataList :: PackageDataList -> Action [String]
64 pkgDataList packageData = fmap (map unquote . words) $ case packageData of
65 CcArgs path -> askPackageData path "CC_OPTS"
66 CSrcs path -> askPackageData path "C_SRCS"
67 CppArgs path -> askPackageData path "CPP_OPTS"
68 DepCcArgs path -> askPackageData path "DEP_CC_OPTS"
69 DepExtraLibs path -> askPackageData path "DEP_EXTRA_LIBS"
70 DepIds path -> askPackageData path "DEP_IPIDS"
71 DepIncludeDirs path -> askPackageData path "DEP_INCLUDE_DIRS_SINGLE_QUOTED"
72 DepLibDirs path -> askPackageData path "DEP_LIB_DIRS_SINGLE_QUOTED"
73 DepLdArgs path -> askPackageData path "DEP_LD_OPTS"
74 DepNames path -> askPackageData path "DEP_NAMES"
75 Deps path -> askPackageData path "DEPS"
76 HiddenModules path -> askPackageData path "HIDDEN_MODULES"
77 HsArgs path -> askPackageData path "HC_OPTS"
78 IncludeDirs path -> askPackageData path "INCLUDE_DIRS"
79 LdArgs path -> askPackageData path "LD_OPTS"
80 Modules path -> askPackageData path "MODULES"
81 SrcDirs path -> askPackageData path "HS_SRC_DIRS"
82 where
83 unquote = dropWhile (== '\'') . dropWhileEnd (== '\'')
84
85 -- Oracle for 'package-data.mk' files
86 packageDataOracle :: Rules ()
87 packageDataOracle = do
88 pkgDataContents <- newCache $ \file -> do
89 need [file]
90 putOracle $ "Reading " ++ file ++ "..."
91 liftIO $ readConfigFile file
92 _ <- addOracle $ \(PackageDataKey (file, key)) ->
93 Map.lookup key <$> pkgDataContents file
94 return ()