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