Minor revision
[hadrian.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 relocatableBuild, installDocDir, installGhcLibDir
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 @system.config@ file, e.g. 'target-os = mingw32'.
17 -- @setting TargetOs@ looks up the config file and returns "mingw32".
18 -- 'SettingList' is used for multiple string values separated by spaces, such
19 -- as @gmp-include-dirs = a b@.
20 -- @settingList GmpIncludeDirs@ therefore returns a list of strings ["a", "b"].
21 data Setting = BuildArch
22 | BuildOs
23 | BuildPlatform
24 | BuildVendor
25 | CcClangBackend
26 | CcLlvmBackend
27 | DynamicExtension
28 | GhcMajorVersion
29 | GhcMinorVersion
30 | GhcPatchLevel
31 | GhcVersion
32 | GhcSourcePath
33 | HostArch
34 | HostOs
35 | HostPlatform
36 | HostVendor
37 | ProjectGitCommitId
38 | ProjectName
39 | ProjectVersion
40 | ProjectVersionInt
41 | ProjectPatchLevel
42 | ProjectPatchLevel1
43 | ProjectPatchLevel2
44 | TargetArch
45 | TargetOs
46 | TargetPlatform
47 | TargetPlatformFull
48 | TargetVendor
49 | FfiIncludeDir
50 | FfiLibDir
51 | GmpIncludeDir
52 | GmpLibDir
53 | IconvIncludeDir
54 | IconvLibDir
55 | CursesLibDir
56 -- Paths to where GHC is installed (ref: mk/install.mk)
57 | InstallPrefix
58 | InstallBinDir
59 | InstallLibDir
60 | InstallDataRootDir
61 -- Command lines for invoking the @install@ utility
62 | Install
63 | InstallData
64 | InstallProgram
65 | InstallScript
66 | InstallDir
67 -- Command line for creating a symbolic link
68 | LnS
69
70 data SettingList = ConfCcArgs Stage
71 | ConfCppArgs Stage
72 | ConfGccLinkerArgs Stage
73 | ConfLdLinkerArgs Stage
74 | HsCppArgs
75
76 -- | Maps 'Setting's to names in @cfg/system.config.in@.
77 setting :: Setting -> Action String
78 setting key = unsafeAskConfig $ case key of
79 BuildArch -> "build-arch"
80 BuildOs -> "build-os"
81 BuildPlatform -> "build-platform"
82 BuildVendor -> "build-vendor"
83 CcClangBackend -> "cc-clang-backend"
84 CcLlvmBackend -> "cc-llvm-backend"
85 DynamicExtension -> "dynamic-extension"
86 GhcMajorVersion -> "ghc-major-version"
87 GhcMinorVersion -> "ghc-minor-version"
88 GhcPatchLevel -> "ghc-patch-level"
89 GhcVersion -> "ghc-version"
90 GhcSourcePath -> "ghc-source-path"
91 HostArch -> "host-arch"
92 HostOs -> "host-os"
93 HostPlatform -> "host-platform"
94 HostVendor -> "host-vendor"
95 ProjectGitCommitId -> "project-git-commit-id"
96 ProjectName -> "project-name"
97 ProjectVersion -> "project-version"
98 ProjectVersionInt -> "project-version-int"
99 ProjectPatchLevel -> "project-patch-level"
100 ProjectPatchLevel1 -> "project-patch-level1"
101 ProjectPatchLevel2 -> "project-patch-level2"
102 TargetArch -> "target-arch"
103 TargetOs -> "target-os"
104 TargetPlatform -> "target-platform"
105 TargetPlatformFull -> "target-platform-full"
106 TargetVendor -> "target-vendor"
107 FfiIncludeDir -> "ffi-include-dir"
108 FfiLibDir -> "ffi-lib-dir"
109 GmpIncludeDir -> "gmp-include-dir"
110 GmpLibDir -> "gmp-lib-dir"
111 IconvIncludeDir -> "iconv-include-dir"
112 IconvLibDir -> "iconv-lib-dir"
113 CursesLibDir -> "curses-lib-dir"
114 InstallPrefix -> "install-prefix"
115 InstallBinDir -> "install-bindir"
116 InstallLibDir -> "install-libdir"
117 InstallDataRootDir -> "install-datarootdir"
118 Install -> "install"
119 InstallDir -> "install-dir"
120 InstallProgram -> "install-program"
121 InstallScript -> "install-script"
122 InstallData -> "install-data"
123 LnS -> "ln-s"
124
125 settingList :: SettingList -> Action [String]
126 settingList key = fmap words $ unsafeAskConfig $ case key of
127 ConfCcArgs stage -> "conf-cc-args-" ++ stageString stage
128 ConfCppArgs stage -> "conf-cpp-args-" ++ stageString stage
129 ConfGccLinkerArgs stage -> "conf-gcc-linker-args-" ++ stageString stage
130 ConfLdLinkerArgs stage -> "conf-ld-linker-args-" ++ stageString stage
131 HsCppArgs -> "hs-cpp-args"
132
133 getSetting :: Setting -> ReaderT a Action String
134 getSetting = lift . setting
135
136 getSettingList :: SettingList -> ReaderT a Action [String]
137 getSettingList = lift . settingList
138
139 matchSetting :: Setting -> [String] -> Action Bool
140 matchSetting key values = fmap (`elem` values) $ setting key
141
142 anyTargetPlatform :: [String] -> Action Bool
143 anyTargetPlatform = matchSetting TargetPlatformFull
144
145 anyTargetOs :: [String] -> Action Bool
146 anyTargetOs = matchSetting TargetOs
147
148 anyTargetArch :: [String] -> Action Bool
149 anyTargetArch = matchSetting TargetArch
150
151 anyHostOs :: [String] -> Action Bool
152 anyHostOs = matchSetting HostOs
153
154 iosHost :: Action Bool
155 iosHost = anyHostOs ["ios"]
156
157 osxHost :: Action Bool
158 osxHost = anyHostOs ["darwin"]
159
160 windowsHost :: Action Bool
161 windowsHost = anyHostOs ["mingw32", "cygwin32"]
162
163 ghcWithInterpreter :: Action Bool
164 ghcWithInterpreter = do
165 goodOs <- anyTargetOs [ "mingw32", "cygwin32", "linux", "solaris2"
166 , "freebsd", "dragonfly", "netbsd", "openbsd"
167 , "darwin", "kfreebsdgnu" ]
168 goodArch <- anyTargetArch [ "i386", "x86_64", "powerpc", "sparc"
169 , "sparc64", "arm" ]
170 return $ goodOs && goodArch
171
172 ghcEnableTablesNextToCode :: Action Bool
173 ghcEnableTablesNextToCode = notM $ anyTargetArch ["ia64", "powerpc64", "powerpc64le"]
174
175 useLibFFIForAdjustors :: Action Bool
176 useLibFFIForAdjustors = notM $ anyTargetArch ["i386", "x86_64"]
177
178 -- | Canonicalised GHC version number, used for integer version comparisons. We
179 -- expand GhcMinorVersion to two digits by adding a leading zero if necessary.
180 ghcCanonVersion :: Action String
181 ghcCanonVersion = do
182 ghcMajorVersion <- setting GhcMajorVersion
183 ghcMinorVersion <- setting GhcMinorVersion
184 let leadingZero = [ '0' | length ghcMinorVersion == 1 ]
185 return $ ghcMajorVersion ++ leadingZero ++ ghcMinorVersion
186
187 -- | Command lines have limited size on Windows. Since Windows 7 the limit is
188 -- 32768 characters (theoretically). In practice we use 31000 to leave some
189 -- breathing space for the builder's path & name, auxiliary flags, and other
190 -- overheads. Use this function to set limits for other OSs if necessary.
191 cmdLineLengthLimit :: Action Int
192 cmdLineLengthLimit = do
193 windows <- windowsHost
194 osx <- osxHost
195 return $ case (windows, osx) of
196 -- Windows:
197 (True, False) -> 31000
198 -- On Mac OSX ARG_MAX is 262144, yet when using @xargs@ on OSX this is
199 -- reduced by over 20 000. Hence, 200 000 seems like a sensible limit.
200 (False, True) -> 200000
201 -- On all other systems, we try this:
202 _ -> 4194304 -- Cabal library needs a bit more than 2MB!
203
204 -- ref: https://ghc.haskell.org/trac/ghc/wiki/Building/Installing#HowGHCfindsitsfiles
205 -- | On Windows we normally build a relocatable installation, which assumes that
206 -- the library directory @libdir@ is in a fixed location relative to the GHC
207 -- binary, namely @../lib@.
208 relocatableBuild :: Action Bool
209 relocatableBuild = windowsHost
210
211 installDocDir :: Action String
212 installDocDir = do
213 version <- setting ProjectVersion
214 (-/- ("doc/ghc-" ++ version)) <$> setting InstallDataRootDir
215
216 -- ref: mk/install.mk:101
217 -- TODO: CroosCompilePrefix
218 -- | Unix: override @libdir@ and @datadir@ to put GHC-specific files in a
219 -- subdirectory with the version number included.
220 installGhcLibDir :: Action String
221 installGhcLibDir = do
222 r <- relocatableBuild
223 libdir <- setting InstallLibDir
224 if r then return libdir
225 else do
226 v <- setting ProjectVersion
227 return $ libdir -/- ("ghc-" ++ v)