Fix copying of fs*.h files during RTS registration (#566)
[ghc.git] / src / Rules / Generate.hs
1 module Rules.Generate (
2 isGeneratedCmmFile, generatePackageCode, generateRules, copyRules,
3 includesDependencies, generatedDependencies
4 ) where
5
6 import Base
7 import Expression
8 import Flavour
9 import GHC.Packages
10 import Oracles.Flag
11 import Oracles.ModuleFiles
12 import Oracles.Setting
13 import Rules.Gmp
14 import Rules.Libffi
15 import Settings
16 import Settings.Packages.Rts
17 import Target
18 import Utilities
19
20 -- | Track this file to rebuild generated files whenever it changes.
21 trackGenerateHs :: Expr ()
22 trackGenerateHs = expr $ need [sourcePath -/- "Rules/Generate.hs"]
23
24 primopsSource :: FilePath
25 primopsSource = "compiler/prelude/primops.txt.pp"
26
27 primopsTxt :: Stage -> FilePath
28 primopsTxt stage = buildDir (vanillaContext stage compiler) -/- "primops.txt"
29
30 platformH :: Stage -> FilePath
31 platformH stage = buildDir (vanillaContext stage compiler) -/- "ghc_boot_platform.h"
32
33 isGeneratedCmmFile :: FilePath -> Bool
34 isGeneratedCmmFile file = takeBaseName file == "AutoApply"
35
36 includesDependencies :: [FilePath]
37 includesDependencies = fmap (generatedDir -/-)
38 [ "ghcautoconf.h"
39 , "ghcplatform.h"
40 , "ghcversion.h" ]
41
42 ghcPrimDependencies :: Expr [FilePath]
43 ghcPrimDependencies = do
44 stage <- getStage
45 path <- expr $ buildPath (vanillaContext stage ghcPrim)
46 return [path -/- "GHC/Prim.hs", path -/- "GHC/PrimopWrappers.hs"]
47
48 derivedConstantsDependencies :: [FilePath]
49 derivedConstantsDependencies = fmap (generatedDir -/-)
50 [ "DerivedConstants.h"
51 , "GHCConstantsHaskellExports.hs"
52 , "GHCConstantsHaskellType.hs"
53 , "GHCConstantsHaskellWrappers.hs" ]
54
55 compilerDependencies :: Expr [FilePath]
56 compilerDependencies = do
57 root <- getBuildRoot
58 stage <- getStage
59 isGmp <- (== integerGmp) <$> getIntegerPackage
60 ghcPath <- expr $ buildPath (vanillaContext stage compiler)
61 gmpPath <- expr gmpBuildPath
62 rtsPath <- expr rtsBuildPath
63 mconcat [ return [root -/- platformH stage]
64 , return ((root -/-) <$> includesDependencies)
65 , return ((root -/-) <$> derivedConstantsDependencies)
66 , notStage0 ? isGmp ? return [gmpPath -/- gmpLibraryH]
67 , notStage0 ? return ((rtsPath -/-) <$> libffiDependencies)
68 , return $ fmap (ghcPath -/-)
69 [ "primop-can-fail.hs-incl"
70 , "primop-code-size.hs-incl"
71 , "primop-commutable.hs-incl"
72 , "primop-data-decl.hs-incl"
73 , "primop-fixity.hs-incl"
74 , "primop-has-side-effects.hs-incl"
75 , "primop-list.hs-incl"
76 , "primop-out-of-line.hs-incl"
77 , "primop-primop-info.hs-incl"
78 , "primop-strictness.hs-incl"
79 , "primop-tag.hs-incl"
80 , "primop-vector-tycons.hs-incl"
81 , "primop-vector-tys-exports.hs-incl"
82 , "primop-vector-tys.hs-incl"
83 , "primop-vector-uniques.hs-incl" ] ]
84
85 generatedDependencies :: Expr [FilePath]
86 generatedDependencies = do
87 root <- getBuildRoot
88 rtsPath <- expr rtsBuildPath
89 mconcat [ package compiler ? compilerDependencies
90 , package ghcPrim ? ghcPrimDependencies
91 , package rts ? return (fmap (rtsPath -/-) libffiDependencies
92 ++ fmap (root -/-) includesDependencies
93 ++ fmap (root -/-) derivedConstantsDependencies)
94 , stage0 ? return (fmap (root -/-) includesDependencies) ]
95
96 generate :: FilePath -> Context -> Expr String -> Action ()
97 generate file context expr = do
98 contents <- interpretInContext context expr
99 writeFileChanged file contents
100 putSuccess $ "| Successfully generated " ++ file ++ "."
101
102 generatePackageCode :: Context -> Rules ()
103 generatePackageCode context@(Context stage pkg _) = do
104 root <- buildRootRules
105 let dir = buildDir context
106 generated f = (root -/- dir ++ "//*.hs") ?== f && not ("//autogen/*" ?== f)
107 go gen file = generate file context gen
108 generated ?> \file -> do
109 let unpack = fromMaybe . error $ "No generator for " ++ file ++ "."
110 (src, builder) <- unpack <$> findGenerator context file
111 need [src]
112 build $ target context builder [src] [file]
113 let boot = src -<.> "hs-boot"
114 whenM (doesFileExist boot) . copyFile boot $ file -<.> "hs-boot"
115
116 priority 2.0 $ do
117 when (pkg == compiler) $ do root <//> dir -/- "Config.hs" %> go generateConfigHs
118 root <//> dir -/- "*.hs-incl" %> genPrimopCode context
119 when (pkg == ghcPrim) $ do (root <//> dir -/- "GHC/Prim.hs") %> genPrimopCode context
120 (root <//> dir -/- "GHC/PrimopWrappers.hs") %> genPrimopCode context
121 when (pkg == ghcPkg) $ do root <//> dir -/- "Version.hs" %> go generateVersionHs
122
123 -- TODO: needing platformH is ugly and fragile
124 when (pkg == compiler) $ do
125 root -/- primopsTxt stage %> \file -> do
126 root <- buildRoot
127 need $ [ root -/- platformH stage
128 , primopsSource]
129 ++ fmap (root -/-) includesDependencies
130 build $ target context HsCpp [primopsSource] [file]
131
132 -- only generate this once! Until we have the include logic fixed.
133 -- See the note on `platformH`
134 when (stage == Stage0) $ do
135 root <//> "compiler/ghc_boot_platform.h" %> go generateGhcBootPlatformH
136 root <//> platformH stage %> go generateGhcBootPlatformH
137
138 when (pkg == rts) $ do
139 root <//> dir -/- "cmm/AutoApply.cmm" %> \file ->
140 build $ target context GenApply [] [file]
141 -- XXX: this should be fixed properly, e.g. generated here on demand.
142 (root <//> dir -/- "DerivedConstants.h") <~ (buildRoot <&> (-/- generatedDir))
143 (root <//> dir -/- "ghcautoconf.h") <~ (buildRoot <&> (-/- generatedDir))
144 (root <//> dir -/- "ghcplatform.h") <~ (buildRoot <&> (-/- generatedDir))
145 (root <//> dir -/- "ghcversion.h") <~ (buildRoot <&> (-/- generatedDir))
146 when (pkg == integerGmp) $ do
147 (root <//> dir -/- "ghc-gmp.h") <~ (buildRoot <&> (-/- "include"))
148 where
149 pattern <~ mdir = pattern %> \file -> do
150 dir <- mdir
151 copyFile (dir -/- takeFileName file) file
152
153 genPrimopCode :: Context -> FilePath -> Action ()
154 genPrimopCode context@(Context stage _pkg _) file = do
155 root <- buildRoot
156 need [root -/- primopsTxt stage]
157 build $ target context GenPrimopCode [root -/- primopsTxt stage] [file]
158
159 copyRules :: Rules ()
160 copyRules = do
161 root <- buildRootRules
162 forM_ [Stage0 ..] $ \stage -> do
163 let prefix = root -/- stageString stage -/- "lib"
164 prefix -/- "ghc-usage.txt" <~ return "driver"
165 prefix -/- "ghci-usage.txt" <~ return "driver"
166 prefix -/- "llvm-targets" <~ return "."
167 prefix -/- "platformConstants" <~ (buildRoot <&> (-/- generatedDir))
168 prefix -/- "settings" <~ return "."
169 prefix -/- "template-hsc.h" <~ return (pkgPath hsc2hs)
170
171 -- TODO: Get rid of this workaround.
172 -- See https://github.com/snowleopard/hadrian/issues/554
173 root -/- buildDir rtsContext -/- "rts/fs.h" <~ return "rts"
174 root -/- buildDir rtsContext -/- "rts/fs_rts.h" <~ return "rts"
175 where
176 infixl 1 <~
177 pattern <~ mdir = pattern %> \file -> do
178 dir <- mdir
179 copyFile (dir -/- takeFileName file) file
180
181 generateRules :: Rules ()
182 generateRules = do
183 root <- buildRootRules
184 priority 2.0 $ (root -/- generatedDir -/- "ghcautoconf.h") <~ generateGhcAutoconfH
185 priority 2.0 $ (root -/- generatedDir -/- "ghcplatform.h") <~ generateGhcPlatformH
186 priority 2.0 $ (root -/- generatedDir -/- "ghcversion.h") <~ generateGhcVersionH
187
188 forM_ [Stage0 ..] $ \stage ->
189 root -/- ghcSplitPath stage %> \path -> do
190 generate path emptyTarget generateGhcSplit
191 makeExecutable path
192
193 -- TODO: simplify, get rid of fake rts context
194 root -/- generatedDir ++ "//*" %> \file -> do
195 withTempDir $ \dir -> build $
196 target rtsContext DeriveConstants [] [file, dir]
197 where
198 file <~ gen = file %> \out -> generate out emptyTarget gen
199
200 -- TODO: Use the Types, Luke! (drop partial function)
201 -- We sometimes need to evaluate expressions that do not require knowing all
202 -- information about the context. In this case, we don't want to know anything.
203 emptyTarget :: Context
204 emptyTarget = vanillaContext (error "Rules.Generate.emptyTarget: unknown stage")
205 (error "Rules.Generate.emptyTarget: unknown package")
206
207 -- Generators
208
209 -- | Given a 'String' replace charaters '.' and '-' by underscores ('_') so that
210 -- the resulting 'String' is a valid C preprocessor identifier.
211 cppify :: String -> String
212 cppify = replaceEq '-' '_' . replaceEq '.' '_'
213
214 ghcSplitSource :: FilePath
215 ghcSplitSource = "driver/split/ghc-split.pl"
216
217 -- ref: rules/build-perl.mk
218 -- | Generate the @ghc-split@ Perl script.
219 generateGhcSplit :: Expr String
220 generateGhcSplit = do
221 trackGenerateHs
222 targetPlatform <- getSetting TargetPlatform
223 ghcEnableTNC <- expr $ yesNo <$> ghcEnableTablesNextToCode
224 perlPath <- getBuilderPath Perl
225 contents <- expr $ readFileLines ghcSplitSource
226 return . unlines $
227 [ "#!" ++ perlPath
228 , "my $TARGETPLATFORM = " ++ show targetPlatform ++ ";"
229 -- I don't see where the ghc-split tool uses TNC, but
230 -- it's in the build-perl macro.
231 , "my $TABLES_NEXT_TO_CODE = " ++ show ghcEnableTNC ++ ";"
232 ] ++ contents
233
234 -- | Generate @ghcplatform.h@ header.
235 generateGhcPlatformH :: Expr String
236 generateGhcPlatformH = do
237 trackGenerateHs
238 hostPlatform <- getSetting HostPlatform
239 hostArch <- getSetting HostArch
240 hostOs <- getSetting HostOs
241 hostVendor <- getSetting HostVendor
242 targetPlatform <- getSetting TargetPlatform
243 targetArch <- getSetting TargetArch
244 targetOs <- getSetting TargetOs
245 targetVendor <- getSetting TargetVendor
246 ghcUnreg <- expr $ flag GhcUnregisterised
247 return . unlines $
248 [ "#ifndef __GHCPLATFORM_H__"
249 , "#define __GHCPLATFORM_H__"
250 , ""
251 , "#define BuildPlatform_TYPE " ++ cppify hostPlatform
252 , "#define HostPlatform_TYPE " ++ cppify targetPlatform
253 , ""
254 , "#define " ++ cppify hostPlatform ++ "_BUILD 1"
255 , "#define " ++ cppify targetPlatform ++ "_HOST 1"
256 , ""
257 , "#define " ++ hostArch ++ "_BUILD_ARCH 1"
258 , "#define " ++ targetArch ++ "_HOST_ARCH 1"
259 , "#define BUILD_ARCH " ++ show hostArch
260 , "#define HOST_ARCH " ++ show targetArch
261 , ""
262 , "#define " ++ hostOs ++ "_BUILD_OS 1"
263 , "#define " ++ targetOs ++ "_HOST_OS 1"
264 , "#define BUILD_OS " ++ show hostOs
265 , "#define HOST_OS " ++ show targetOs
266 , ""
267 , "#define " ++ hostVendor ++ "_BUILD_VENDOR 1"
268 , "#define " ++ targetVendor ++ "_HOST_VENDOR 1"
269 , "#define BUILD_VENDOR " ++ show hostVendor
270 , "#define HOST_VENDOR " ++ show targetVendor
271 , ""
272 , "/* These TARGET macros are for backwards compatibility... DO NOT USE! */"
273 , "#define TargetPlatform_TYPE " ++ cppify targetPlatform
274 , "#define " ++ cppify targetPlatform ++ "_TARGET 1"
275 , "#define " ++ targetArch ++ "_TARGET_ARCH 1"
276 , "#define TARGET_ARCH " ++ show targetArch
277 , "#define " ++ targetOs ++ "_TARGET_OS 1"
278 , "#define TARGET_OS " ++ show targetOs
279 , "#define " ++ targetVendor ++ "_TARGET_VENDOR 1" ]
280 ++
281 [ "#define UnregisterisedCompiler 1" | ghcUnreg ]
282 ++
283 [ "\n#endif /* __GHCPLATFORM_H__ */" ]
284
285 -- | Generate @Config.hs@ files.
286 generateConfigHs :: Expr String
287 generateConfigHs = do
288 trackGenerateHs
289 cProjectName <- getSetting ProjectName
290 cProjectGitCommitId <- getSetting ProjectGitCommitId
291 cProjectVersion <- getSetting ProjectVersion
292 cProjectVersionInt <- getSetting ProjectVersionInt
293 cProjectPatchLevel <- getSetting ProjectPatchLevel
294 cProjectPatchLevel1 <- getSetting ProjectPatchLevel1
295 cProjectPatchLevel2 <- getSetting ProjectPatchLevel2
296 cBooterVersion <- getSetting GhcVersion
297 intLib <- getIntegerPackage
298 debugged <- ghcDebugged <$> expr flavour
299 let cIntegerLibraryType
300 | intLib == integerGmp = "IntegerGMP"
301 | intLib == integerSimple = "IntegerSimple"
302 | otherwise = error $ "Unknown integer library: " ++ pkgName intLib
303 cSupportsSplitObjs <- expr $ yesNo <$> supportsSplitObjects
304 cGhcWithInterpreter <- expr $ yesNo <$> ghcWithInterpreter
305 cGhcWithNativeCodeGen <- expr $ yesNo <$> ghcWithNativeCodeGen
306 cGhcWithSMP <- expr $ yesNo <$> ghcWithSMP
307 cGhcEnableTablesNextToCode <- expr $ yesNo <$> ghcEnableTablesNextToCode
308 cLeadingUnderscore <- expr $ yesNo <$> flag LeadingUnderscore
309 cGHC_UNLIT_PGM <- fmap takeFileName $ getBuilderPath Unlit
310 cLibFFI <- expr useLibFFIForAdjustors
311 rtsWays <- getRtsWays
312 cGhcRtsWithLibdw <- expr $ flag WithLibdw
313 let cGhcRTSWays = unwords $ map show rtsWays
314 return $ unlines
315 [ "{-# LANGUAGE CPP #-}"
316 , "module Config where"
317 , ""
318 , "import GhcPrelude"
319 , ""
320 , "#include \"ghc_boot_platform.h\""
321 , ""
322 , "data IntegerLibrary = IntegerGMP"
323 , " | IntegerSimple"
324 , " deriving Eq"
325 , ""
326 , "cBuildPlatformString :: String"
327 , "cBuildPlatformString = BuildPlatform_NAME"
328 , "cHostPlatformString :: String"
329 , "cHostPlatformString = HostPlatform_NAME"
330 , "cTargetPlatformString :: String"
331 , "cTargetPlatformString = TargetPlatform_NAME"
332 , ""
333 , "cProjectName :: String"
334 , "cProjectName = " ++ show cProjectName
335 , "cProjectGitCommitId :: String"
336 , "cProjectGitCommitId = " ++ show cProjectGitCommitId
337 , "cProjectVersion :: String"
338 , "cProjectVersion = " ++ show cProjectVersion
339 , "cProjectVersionInt :: String"
340 , "cProjectVersionInt = " ++ show cProjectVersionInt
341 , "cProjectPatchLevel :: String"
342 , "cProjectPatchLevel = " ++ show cProjectPatchLevel
343 , "cProjectPatchLevel1 :: String"
344 , "cProjectPatchLevel1 = " ++ show cProjectPatchLevel1
345 , "cProjectPatchLevel2 :: String"
346 , "cProjectPatchLevel2 = " ++ show cProjectPatchLevel2
347 , "cBooterVersion :: String"
348 , "cBooterVersion = " ++ show cBooterVersion
349 , "cStage :: String"
350 , "cStage = show (STAGE :: Int)"
351 , "cIntegerLibrary :: String"
352 , "cIntegerLibrary = " ++ show (pkgName intLib)
353 , "cIntegerLibraryType :: IntegerLibrary"
354 , "cIntegerLibraryType = " ++ cIntegerLibraryType
355 , "cSupportsSplitObjs :: String"
356 , "cSupportsSplitObjs = " ++ show cSupportsSplitObjs
357 , "cGhcWithInterpreter :: String"
358 , "cGhcWithInterpreter = " ++ show cGhcWithInterpreter
359 , "cGhcWithNativeCodeGen :: String"
360 , "cGhcWithNativeCodeGen = " ++ show cGhcWithNativeCodeGen
361 , "cGhcWithSMP :: String"
362 , "cGhcWithSMP = " ++ show cGhcWithSMP
363 , "cGhcRTSWays :: String"
364 , "cGhcRTSWays = " ++ show cGhcRTSWays
365 , "cGhcEnableTablesNextToCode :: String"
366 , "cGhcEnableTablesNextToCode = " ++ show cGhcEnableTablesNextToCode
367 , "cLeadingUnderscore :: String"
368 , "cLeadingUnderscore = " ++ show cLeadingUnderscore
369 , "cGHC_UNLIT_PGM :: String"
370 , "cGHC_UNLIT_PGM = " ++ show cGHC_UNLIT_PGM
371 , "cGHC_SPLIT_PGM :: String"
372 , "cGHC_SPLIT_PGM = " ++ show "ghc-split"
373 , "cLibFFI :: Bool"
374 , "cLibFFI = " ++ show cLibFFI
375 , "cGhcThreaded :: Bool"
376 , "cGhcThreaded = " ++ show (any (wayUnit Threaded) rtsWays)
377 , "cGhcDebugged :: Bool"
378 , "cGhcDebugged = " ++ show debugged
379 , "cGhcRtsWithLibdw :: Bool"
380 , "cGhcRtsWithLibdw = " ++ show cGhcRtsWithLibdw ]
381
382 -- | Generate @ghcautoconf.h@ header.
383 generateGhcAutoconfH :: Expr String
384 generateGhcAutoconfH = do
385 trackGenerateHs
386 configHContents <- expr $ map undefinePackage <$> readFileLines configH
387 tablesNextToCode <- expr ghcEnableTablesNextToCode
388 ghcUnreg <- expr $ flag GhcUnregisterised
389 ccLlvmBackend <- getSetting CcLlvmBackend
390 ccClangBackend <- getSetting CcClangBackend
391 return . unlines $
392 [ "#ifndef __GHCAUTOCONF_H__"
393 , "#define __GHCAUTOCONF_H__" ]
394 ++ configHContents ++
395 [ "\n#define TABLES_NEXT_TO_CODE 1" | tablesNextToCode && not ghcUnreg ]
396 ++
397 [ "\n#define llvm_CC_FLAVOR 1" | ccLlvmBackend == "1" ]
398 ++
399 [ "\n#define clang_CC_FLAVOR 1" | ccClangBackend == "1" ]
400 ++
401 [ "#endif /* __GHCAUTOCONF_H__ */" ]
402 where
403 undefinePackage s
404 | "#define PACKAGE_" `isPrefixOf` s
405 = "/* #undef " ++ takeWhile (/=' ') (drop 8 s) ++ " */"
406 | otherwise = s
407
408 -- | Generate @ghc_boot_platform.h@ headers.
409 generateGhcBootPlatformH :: Expr String
410 generateGhcBootPlatformH = do
411 trackGenerateHs
412 stage <- getStage
413 let chooseSetting x y = getSetting $ if stage == Stage0 then x else y
414 buildPlatform <- chooseSetting BuildPlatform HostPlatform
415 buildArch <- chooseSetting BuildArch HostArch
416 buildOs <- chooseSetting BuildOs HostOs
417 buildVendor <- chooseSetting BuildVendor HostVendor
418 hostPlatform <- chooseSetting HostPlatform TargetPlatform
419 hostArch <- chooseSetting HostArch TargetArch
420 hostOs <- chooseSetting HostOs TargetOs
421 hostVendor <- chooseSetting HostVendor TargetVendor
422 targetPlatform <- getSetting TargetPlatform
423 targetArch <- getSetting TargetArch
424 llvmTarget <- getSetting LlvmTarget
425 targetOs <- getSetting TargetOs
426 targetVendor <- getSetting TargetVendor
427 return $ unlines
428 [ "#ifndef __PLATFORM_H__"
429 , "#define __PLATFORM_H__"
430 , ""
431 , "#define BuildPlatform_NAME " ++ show buildPlatform
432 , "#define HostPlatform_NAME " ++ show hostPlatform
433 , "#define TargetPlatform_NAME " ++ show targetPlatform
434 , ""
435 , "#define " ++ cppify buildPlatform ++ "_BUILD 1"
436 , "#define " ++ cppify hostPlatform ++ "_HOST 1"
437 , "#define " ++ cppify targetPlatform ++ "_TARGET 1"
438 , ""
439 , "#define " ++ buildArch ++ "_BUILD_ARCH 1"
440 , "#define " ++ hostArch ++ "_HOST_ARCH 1"
441 , "#define " ++ targetArch ++ "_TARGET_ARCH 1"
442 , "#define BUILD_ARCH " ++ show buildArch
443 , "#define HOST_ARCH " ++ show hostArch
444 , "#define TARGET_ARCH " ++ show targetArch
445 , "#define LLVM_TARGET " ++ show llvmTarget
446 , ""
447 , "#define " ++ buildOs ++ "_BUILD_OS 1"
448 , "#define " ++ hostOs ++ "_HOST_OS 1"
449 , "#define " ++ targetOs ++ "_TARGET_OS 1"
450 , "#define BUILD_OS " ++ show buildOs
451 , "#define HOST_OS " ++ show hostOs
452 , "#define TARGET_OS " ++ show targetOs
453 , ""
454 , "#define " ++ buildVendor ++ "_BUILD_VENDOR 1"
455 , "#define " ++ hostVendor ++ "_HOST_VENDOR 1"
456 , "#define " ++ targetVendor ++ "_TARGET_VENDOR 1"
457 , "#define BUILD_VENDOR " ++ show buildVendor
458 , "#define HOST_VENDOR " ++ show hostVendor
459 , "#define TARGET_VENDOR " ++ show targetVendor
460 , ""
461 , "#endif /* __PLATFORM_H__ */" ]
462
463 -- | Generate @ghcversion.h@ header.
464 generateGhcVersionH :: Expr String
465 generateGhcVersionH = do
466 trackGenerateHs
467 version <- getSetting ProjectVersionInt
468 patchLevel1 <- getSetting ProjectPatchLevel1
469 patchLevel2 <- getSetting ProjectPatchLevel2
470 return . unlines $
471 [ "#ifndef __GHCVERSION_H__"
472 , "#define __GHCVERSION_H__"
473 , ""
474 , "#ifndef __GLASGOW_HASKELL__"
475 , "# define __GLASGOW_HASKELL__ " ++ version
476 , "#endif"
477 , ""]
478 ++
479 [ "#define __GLASGOW_HASKELL_PATCHLEVEL1__ " ++ patchLevel1 | patchLevel1 /= "" ]
480 ++
481 [ "#define __GLASGOW_HASKELL_PATCHLEVEL2__ " ++ patchLevel2 | patchLevel2 /= "" ]
482 ++
483 [ ""
484 , "#define MIN_VERSION_GLASGOW_HASKELL(ma,mi,pl1,pl2) (\\"
485 , " ((ma)*100+(mi)) < __GLASGOW_HASKELL__ || \\"
486 , " ((ma)*100+(mi)) == __GLASGOW_HASKELL__ \\"
487 , " && (pl1) < __GLASGOW_HASKELL_PATCHLEVEL1__ || \\"
488 , " ((ma)*100+(mi)) == __GLASGOW_HASKELL__ \\"
489 , " && (pl1) == __GLASGOW_HASKELL_PATCHLEVEL1__ \\"
490 , " && (pl2) <= __GLASGOW_HASKELL_PATCHLEVEL2__ )"
491 , ""
492 , "#endif /* __GHCVERSION_H__ */" ]
493
494 -- | Generate @Version.hs@ files.
495 generateVersionHs :: Expr String
496 generateVersionHs = do
497 trackGenerateHs
498 projectVersion <- getSetting ProjectVersion
499 targetOs <- getSetting TargetOs
500 targetArch <- getSetting TargetArch
501 return $ unlines
502 [ "module Version where"
503 , "version, targetOS, targetARCH :: String"
504 , "version = " ++ show projectVersion
505 , "targetOS = " ++ show targetOs
506 , "targetARCH = " ++ show targetArch ]