Refactor dependency oracles
[ghc.git] / src / Oracles / Config / Setting.hs
1 module Oracles.Config.Setting (
2 Setting (..), SettingList (..), setting, settingList, getSetting,
3 getSettingList, anyTargetPlatform, anyTargetOs, anyTargetArch, anyHostOs,
4 ghcWithInterpreter, ghcEnableTablesNextToCode, useLibFFIForAdjustors,
5 ghcCanonVersion, cmdLineLengthLimit, iosHost, osxHost, windowsHost
6 ) where
7
8 import Control.Monad.Trans.Reader
9
10 import Base
11 import Oracles.Config
12 import Stage
13
14 -- TODO: Reduce the variety of similar flags (e.g. CPP and non-CPP versions).
15 -- | Each 'Setting' comes from @system.config@ file, e.g. 'target-os = mingw32'.
16 -- @setting TargetOs@ looks up the config file and returns "mingw32".
17 -- 'SettingList' is used for multiple string values separated by spaces, such
18 -- as @gmp-include-dirs = a b@.
19 -- @settingList GmpIncludeDirs@ therefore returns a list of strings ["a", "b"].
20 data Setting = BuildArch
21 | BuildOs
22 | BuildPlatform
23 | BuildVendor
24 | CcClangBackend
25 | CcLlvmBackend
26 | DynamicExtension
27 | GhcMajorVersion
28 | GhcMinorVersion
29 | GhcPatchLevel
30 | GhcVersion
31 | GhcSourcePath
32 | HostArch
33 | HostOs
34 | HostPlatform
35 | HostVendor
36 | ProjectGitCommitId
37 | ProjectName
38 | ProjectVersion
39 | ProjectVersionInt
40 | ProjectPatchLevel
41 | ProjectPatchLevel1
42 | ProjectPatchLevel2
43 | TargetArch
44 | TargetOs
45 | TargetPlatform
46 | TargetPlatformFull
47 | TargetVendor
48 | FfiIncludeDir
49 | FfiLibDir
50 | GmpIncludeDir
51 | GmpLibDir
52 | IconvIncludeDir
53 | IconvLibDir
54
55 data SettingList = ConfCcArgs Stage
56 | ConfCppArgs Stage
57 | ConfGccLinkerArgs Stage
58 | ConfLdLinkerArgs Stage
59 | HsCppArgs
60
61 setting :: Setting -> Action String
62 setting key = askConfig $ case key of
63 BuildArch -> "build-arch"
64 BuildOs -> "build-os"
65 BuildPlatform -> "build-platform"
66 BuildVendor -> "build-vendor"
67 CcClangBackend -> "cc-clang-backend"
68 CcLlvmBackend -> "cc-llvm-backend"
69 DynamicExtension -> "dynamic-extension"
70 GhcMajorVersion -> "ghc-major-version"
71 GhcMinorVersion -> "ghc-minor-version"
72 GhcPatchLevel -> "ghc-patch-level"
73 GhcVersion -> "ghc-version"
74 GhcSourcePath -> "ghc-source-path"
75 HostArch -> "host-arch"
76 HostOs -> "host-os"
77 HostPlatform -> "host-platform"
78 HostVendor -> "host-vendor"
79 ProjectGitCommitId -> "project-git-commit-id"
80 ProjectName -> "project-name"
81 ProjectVersion -> "project-version"
82 ProjectVersionInt -> "project-version-int"
83 ProjectPatchLevel -> "project-patch-level"
84 ProjectPatchLevel1 -> "project-patch-level1"
85 ProjectPatchLevel2 -> "project-patch-level2"
86 TargetArch -> "target-arch"
87 TargetOs -> "target-os"
88 TargetPlatform -> "target-platform"
89 TargetPlatformFull -> "target-platform-full"
90 TargetVendor -> "target-vendor"
91 FfiIncludeDir -> "ffi-include-dir"
92 FfiLibDir -> "ffi-lib-dir"
93 GmpIncludeDir -> "gmp-include-dir"
94 GmpLibDir -> "gmp-lib-dir"
95 IconvIncludeDir -> "iconv-include-dir"
96 IconvLibDir -> "iconv-lib-dir"
97
98 settingList :: SettingList -> Action [String]
99 settingList key = fmap words $ askConfig $ case key of
100 ConfCcArgs stage -> "conf-cc-args-" ++ stageString stage
101 ConfCppArgs stage -> "conf-cpp-args-" ++ stageString stage
102 ConfGccLinkerArgs stage -> "conf-gcc-linker-args-" ++ stageString stage
103 ConfLdLinkerArgs stage -> "conf-ld-linker-args-" ++ stageString stage
104 HsCppArgs -> "hs-cpp-args"
105
106 getSetting :: Setting -> ReaderT a Action String
107 getSetting = lift . setting
108
109 getSettingList :: SettingList -> ReaderT a Action [String]
110 getSettingList = lift . settingList
111
112 matchSetting :: Setting -> [String] -> Action Bool
113 matchSetting key values = fmap (`elem` values) $ setting key
114
115 anyTargetPlatform :: [String] -> Action Bool
116 anyTargetPlatform = matchSetting TargetPlatformFull
117
118 anyTargetOs :: [String] -> Action Bool
119 anyTargetOs = matchSetting TargetOs
120
121 anyTargetArch :: [String] -> Action Bool
122 anyTargetArch = matchSetting TargetArch
123
124 anyHostOs :: [String] -> Action Bool
125 anyHostOs = matchSetting HostOs
126
127 iosHost :: Action Bool
128 iosHost = anyHostOs ["ios"]
129
130 osxHost :: Action Bool
131 osxHost = anyHostOs ["darwin"]
132
133 windowsHost :: Action Bool
134 windowsHost = anyHostOs ["mingw32", "cygwin32"]
135
136 ghcWithInterpreter :: Action Bool
137 ghcWithInterpreter = do
138 goodOs <- anyTargetOs [ "mingw32", "cygwin32", "linux", "solaris2"
139 , "freebsd", "dragonfly", "netbsd", "openbsd"
140 , "darwin", "kfreebsdgnu" ]
141 goodArch <- anyTargetArch [ "i386", "x86_64", "powerpc", "sparc"
142 , "sparc64", "arm" ]
143 return $ goodOs && goodArch
144
145 ghcEnableTablesNextToCode :: Action Bool
146 ghcEnableTablesNextToCode = notM $ anyTargetArch ["ia64", "powerpc64", "powerpc64le"]
147
148 useLibFFIForAdjustors :: Action Bool
149 useLibFFIForAdjustors = notM $ anyTargetArch ["i386", "x86_64"]
150
151 -- | Canonicalised GHC version number, used for integer version comparisons. We
152 -- expand GhcMinorVersion to two digits by adding a leading zero if necessary.
153 ghcCanonVersion :: Action String
154 ghcCanonVersion = do
155 ghcMajorVersion <- setting GhcMajorVersion
156 ghcMinorVersion <- setting GhcMinorVersion
157 let leadingZero = [ '0' | length ghcMinorVersion == 1 ]
158 return $ ghcMajorVersion ++ leadingZero ++ ghcMinorVersion
159
160 -- | Command lines have limited size on Windows. Since Windows 7 the limit is
161 -- 32768 characters (theoretically). In practice we use 31000 to leave some
162 -- breathing space for the builder's path & name, auxiliary flags, and other
163 -- overheads. Use this function to set limits for other OSs if necessary.
164 cmdLineLengthLimit :: Action Int
165 cmdLineLengthLimit = do
166 windows <- windowsHost
167 osx <- osxHost
168 return $ case (windows, osx) of
169 -- Windows:
170 (True, False) -> 31000
171 -- On Mac OSX ARG_MAX is 262144, yet when using @xargs@ on OSX this is
172 -- reduced by over 20 000. Hence, 200 000 seems like a sensible limit.
173 (False, True) -> 200000
174 -- On all other systems, we try this:
175 _ -> 4194304 -- Cabal library needs a bit more than 2MB!