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