e26e811fe82da54edc18d68effe3368505fc153a
[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.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 -/- "llvm-passes" <~ return "."
168 prefix -/- "platformConstants" <~ (buildRoot <&> (-/- generatedDir))
169 prefix -/- "settings" <~ return "."
170 prefix -/- "template-hsc.h" <~ return (pkgPath hsc2hs)
171 where
172 infixl 1 <~
173 pattern <~ mdir = pattern %> \file -> do
174 dir <- mdir
175 copyFile (dir -/- takeFileName file) file
176
177 generateRules :: Rules ()
178 generateRules = do
179 root <- buildRootRules
180 priority 2.0 $ (root -/- generatedDir -/- "ghcautoconf.h") <~ generateGhcAutoconfH
181 priority 2.0 $ (root -/- generatedDir -/- "ghcplatform.h") <~ generateGhcPlatformH
182 priority 2.0 $ (root -/- generatedDir -/- "ghcversion.h") <~ generateGhcVersionH
183
184 forM_ [Stage0 ..] $ \stage ->
185 root -/- ghcSplitPath stage %> \path -> do
186 generate path emptyTarget generateGhcSplit
187 makeExecutable path
188
189 -- TODO: simplify, get rid of fake rts context
190 root -/- generatedDir ++ "//*" %> \file -> do
191 withTempDir $ \dir -> build $
192 target rtsContext DeriveConstants [] [file, dir]
193 where
194 file <~ gen = file %> \out -> generate out emptyTarget gen
195
196 -- TODO: Use the Types, Luke! (drop partial function)
197 -- We sometimes need to evaluate expressions that do not require knowing all
198 -- information about the context. In this case, we don't want to know anything.
199 emptyTarget :: Context
200 emptyTarget = vanillaContext (error "Rules.Generate.emptyTarget: unknown stage")
201 (error "Rules.Generate.emptyTarget: unknown package")
202
203 -- Generators
204
205 -- | Given a 'String' replace charaters '.' and '-' by underscores ('_') so that
206 -- the resulting 'String' is a valid C preprocessor identifier.
207 cppify :: String -> String
208 cppify = replaceEq '-' '_' . replaceEq '.' '_'
209
210 ghcSplitSource :: FilePath
211 ghcSplitSource = "driver/split/ghc-split.pl"
212
213 -- ref: rules/build-perl.mk
214 -- | Generate the @ghc-split@ Perl script.
215 generateGhcSplit :: Expr String
216 generateGhcSplit = do
217 trackGenerateHs
218 targetPlatform <- getSetting TargetPlatform
219 ghcEnableTNC <- expr $ yesNo <$> ghcEnableTablesNextToCode
220 perlPath <- getBuilderPath Perl
221 contents <- expr $ readFileLines ghcSplitSource
222 return . unlines $
223 [ "#!" ++ perlPath
224 , "my $TARGETPLATFORM = " ++ show targetPlatform ++ ";"
225 -- I don't see where the ghc-split tool uses TNC, but
226 -- it's in the build-perl macro.
227 , "my $TABLES_NEXT_TO_CODE = " ++ show ghcEnableTNC ++ ";"
228 ] ++ contents
229
230 -- | Generate @ghcplatform.h@ header.
231 generateGhcPlatformH :: Expr String
232 generateGhcPlatformH = do
233 trackGenerateHs
234 hostPlatform <- getSetting HostPlatform
235 hostArch <- getSetting HostArch
236 hostOs <- getSetting HostOs
237 hostVendor <- getSetting HostVendor
238 targetPlatform <- getSetting TargetPlatform
239 targetArch <- getSetting TargetArch
240 targetOs <- getSetting TargetOs
241 targetVendor <- getSetting TargetVendor
242 ghcUnreg <- getFlag GhcUnregisterised
243 return . unlines $
244 [ "#ifndef __GHCPLATFORM_H__"
245 , "#define __GHCPLATFORM_H__"
246 , ""
247 , "#define BuildPlatform_TYPE " ++ cppify hostPlatform
248 , "#define HostPlatform_TYPE " ++ cppify targetPlatform
249 , ""
250 , "#define " ++ cppify hostPlatform ++ "_BUILD 1"
251 , "#define " ++ cppify targetPlatform ++ "_HOST 1"
252 , ""
253 , "#define " ++ hostArch ++ "_BUILD_ARCH 1"
254 , "#define " ++ targetArch ++ "_HOST_ARCH 1"
255 , "#define BUILD_ARCH " ++ show hostArch
256 , "#define HOST_ARCH " ++ show targetArch
257 , ""
258 , "#define " ++ hostOs ++ "_BUILD_OS 1"
259 , "#define " ++ targetOs ++ "_HOST_OS 1"
260 , "#define BUILD_OS " ++ show hostOs
261 , "#define HOST_OS " ++ show targetOs
262 , ""
263 , "#define " ++ hostVendor ++ "_BUILD_VENDOR 1"
264 , "#define " ++ targetVendor ++ "_HOST_VENDOR 1"
265 , "#define BUILD_VENDOR " ++ show hostVendor
266 , "#define HOST_VENDOR " ++ show targetVendor
267 , ""
268 , "/* These TARGET macros are for backwards compatibility... DO NOT USE! */"
269 , "#define TargetPlatform_TYPE " ++ cppify targetPlatform
270 , "#define " ++ cppify targetPlatform ++ "_TARGET 1"
271 , "#define " ++ targetArch ++ "_TARGET_ARCH 1"
272 , "#define TARGET_ARCH " ++ show targetArch
273 , "#define " ++ targetOs ++ "_TARGET_OS 1"
274 , "#define TARGET_OS " ++ show targetOs
275 , "#define " ++ targetVendor ++ "_TARGET_VENDOR 1" ]
276 ++
277 [ "#define UnregisterisedCompiler 1" | ghcUnreg ]
278 ++
279 [ "\n#endif /* __GHCPLATFORM_H__ */" ]
280
281 -- | Generate @Config.hs@ files.
282 generateConfigHs :: Expr String
283 generateConfigHs = do
284 trackGenerateHs
285 cProjectName <- getSetting ProjectName
286 cProjectGitCommitId <- getSetting ProjectGitCommitId
287 cProjectVersion <- getSetting ProjectVersion
288 cProjectVersionInt <- getSetting ProjectVersionInt
289 cProjectPatchLevel <- getSetting ProjectPatchLevel
290 cProjectPatchLevel1 <- getSetting ProjectPatchLevel1
291 cProjectPatchLevel2 <- getSetting ProjectPatchLevel2
292 cBooterVersion <- getSetting GhcVersion
293 intLib <- getIntegerPackage
294 debugged <- ghcDebugged <$> expr flavour
295 let cIntegerLibraryType
296 | intLib == integerGmp = "IntegerGMP"
297 | intLib == integerSimple = "IntegerSimple"
298 | otherwise = error $ "Unknown integer library: " ++ pkgName intLib
299 cSupportsSplitObjs <- expr $ yesNo <$> supportsSplitObjects
300 cGhcWithInterpreter <- expr $ yesNo <$> ghcWithInterpreter
301 cGhcWithNativeCodeGen <- expr $ yesNo <$> ghcWithNativeCodeGen
302 cGhcWithSMP <- expr $ yesNo <$> ghcWithSMP
303 cGhcEnableTablesNextToCode <- expr $ yesNo <$> ghcEnableTablesNextToCode
304 cLeadingUnderscore <- expr $ yesNo <$> flag LeadingUnderscore
305 cGHC_UNLIT_PGM <- fmap takeFileName $ getBuilderPath Unlit
306 cLibFFI <- expr useLibFFIForAdjustors
307 rtsWays <- getRtsWays
308 cGhcRtsWithLibdw <- getFlag WithLibdw
309 let cGhcRTSWays = unwords $ map show rtsWays
310 return $ unlines
311 [ "{-# LANGUAGE CPP #-}"
312 , "module Config where"
313 , ""
314 , "import GhcPrelude"
315 , ""
316 , "#include \"ghc_boot_platform.h\""
317 , ""
318 , "data IntegerLibrary = IntegerGMP"
319 , " | IntegerSimple"
320 , " deriving Eq"
321 , ""
322 , "cBuildPlatformString :: String"
323 , "cBuildPlatformString = BuildPlatform_NAME"
324 , "cHostPlatformString :: String"
325 , "cHostPlatformString = HostPlatform_NAME"
326 , "cTargetPlatformString :: String"
327 , "cTargetPlatformString = TargetPlatform_NAME"
328 , ""
329 , "cProjectName :: String"
330 , "cProjectName = " ++ show cProjectName
331 , "cProjectGitCommitId :: String"
332 , "cProjectGitCommitId = " ++ show cProjectGitCommitId
333 , "cProjectVersion :: String"
334 , "cProjectVersion = " ++ show cProjectVersion
335 , "cProjectVersionInt :: String"
336 , "cProjectVersionInt = " ++ show cProjectVersionInt
337 , "cProjectPatchLevel :: String"
338 , "cProjectPatchLevel = " ++ show cProjectPatchLevel
339 , "cProjectPatchLevel1 :: String"
340 , "cProjectPatchLevel1 = " ++ show cProjectPatchLevel1
341 , "cProjectPatchLevel2 :: String"
342 , "cProjectPatchLevel2 = " ++ show cProjectPatchLevel2
343 , "cBooterVersion :: String"
344 , "cBooterVersion = " ++ show cBooterVersion
345 , "cStage :: String"
346 , "cStage = show (STAGE :: Int)"
347 , "cIntegerLibrary :: String"
348 , "cIntegerLibrary = " ++ show (pkgName intLib)
349 , "cIntegerLibraryType :: IntegerLibrary"
350 , "cIntegerLibraryType = " ++ cIntegerLibraryType
351 , "cSupportsSplitObjs :: String"
352 , "cSupportsSplitObjs = " ++ show cSupportsSplitObjs
353 , "cGhcWithInterpreter :: String"
354 , "cGhcWithInterpreter = " ++ show cGhcWithInterpreter
355 , "cGhcWithNativeCodeGen :: String"
356 , "cGhcWithNativeCodeGen = " ++ show cGhcWithNativeCodeGen
357 , "cGhcWithSMP :: String"
358 , "cGhcWithSMP = " ++ show cGhcWithSMP
359 , "cGhcRTSWays :: String"
360 , "cGhcRTSWays = " ++ show cGhcRTSWays
361 , "cGhcEnableTablesNextToCode :: String"
362 , "cGhcEnableTablesNextToCode = " ++ show cGhcEnableTablesNextToCode
363 , "cLeadingUnderscore :: String"
364 , "cLeadingUnderscore = " ++ show cLeadingUnderscore
365 , "cGHC_UNLIT_PGM :: String"
366 , "cGHC_UNLIT_PGM = " ++ show cGHC_UNLIT_PGM
367 , "cGHC_SPLIT_PGM :: String"
368 , "cGHC_SPLIT_PGM = " ++ show "ghc-split"
369 , "cLibFFI :: Bool"
370 , "cLibFFI = " ++ show cLibFFI
371 , "cGhcThreaded :: Bool"
372 , "cGhcThreaded = " ++ show (any (wayUnit Threaded) rtsWays)
373 , "cGhcDebugged :: Bool"
374 , "cGhcDebugged = " ++ show debugged
375 , "cGhcRtsWithLibdw :: Bool"
376 , "cGhcRtsWithLibdw = " ++ show cGhcRtsWithLibdw ]
377
378 -- | Generate @ghcautoconf.h@ header.
379 generateGhcAutoconfH :: Expr String
380 generateGhcAutoconfH = do
381 trackGenerateHs
382 configHContents <- expr $ map undefinePackage <$> readFileLines configH
383 tablesNextToCode <- expr ghcEnableTablesNextToCode
384 ghcUnreg <- getFlag GhcUnregisterised
385 ccLlvmBackend <- getSetting CcLlvmBackend
386 ccClangBackend <- getSetting CcClangBackend
387 return . unlines $
388 [ "#ifndef __GHCAUTOCONF_H__"
389 , "#define __GHCAUTOCONF_H__" ]
390 ++ configHContents ++
391 [ "\n#define TABLES_NEXT_TO_CODE 1" | tablesNextToCode && not ghcUnreg ]
392 ++
393 [ "\n#define llvm_CC_FLAVOR 1" | ccLlvmBackend == "1" ]
394 ++
395 [ "\n#define clang_CC_FLAVOR 1" | ccClangBackend == "1" ]
396 ++
397 [ "#endif /* __GHCAUTOCONF_H__ */" ]
398 where
399 undefinePackage s
400 | "#define PACKAGE_" `isPrefixOf` s
401 = "/* #undef " ++ takeWhile (/=' ') (drop 8 s) ++ " */"
402 | otherwise = s
403
404 -- | Generate @ghc_boot_platform.h@ headers.
405 generateGhcBootPlatformH :: Expr String
406 generateGhcBootPlatformH = do
407 trackGenerateHs
408 stage <- getStage
409 let chooseSetting x y = getSetting $ if stage == Stage0 then x else y
410 buildPlatform <- chooseSetting BuildPlatform HostPlatform
411 buildArch <- chooseSetting BuildArch HostArch
412 buildOs <- chooseSetting BuildOs HostOs
413 buildVendor <- chooseSetting BuildVendor HostVendor
414 hostPlatform <- chooseSetting HostPlatform TargetPlatform
415 hostArch <- chooseSetting HostArch TargetArch
416 hostOs <- chooseSetting HostOs TargetOs
417 hostVendor <- chooseSetting HostVendor TargetVendor
418 targetPlatform <- getSetting TargetPlatform
419 targetArch <- getSetting TargetArch
420 llvmTarget <- getSetting LlvmTarget
421 targetOs <- getSetting TargetOs
422 targetVendor <- getSetting TargetVendor
423 return $ unlines
424 [ "#ifndef __PLATFORM_H__"
425 , "#define __PLATFORM_H__"
426 , ""
427 , "#define BuildPlatform_NAME " ++ show buildPlatform
428 , "#define HostPlatform_NAME " ++ show hostPlatform
429 , "#define TargetPlatform_NAME " ++ show targetPlatform
430 , ""
431 , "#define " ++ cppify buildPlatform ++ "_BUILD 1"
432 , "#define " ++ cppify hostPlatform ++ "_HOST 1"
433 , "#define " ++ cppify targetPlatform ++ "_TARGET 1"
434 , ""
435 , "#define " ++ buildArch ++ "_BUILD_ARCH 1"
436 , "#define " ++ hostArch ++ "_HOST_ARCH 1"
437 , "#define " ++ targetArch ++ "_TARGET_ARCH 1"
438 , "#define BUILD_ARCH " ++ show buildArch
439 , "#define HOST_ARCH " ++ show hostArch
440 , "#define TARGET_ARCH " ++ show targetArch
441 , "#define LLVM_TARGET " ++ show llvmTarget
442 , ""
443 , "#define " ++ buildOs ++ "_BUILD_OS 1"
444 , "#define " ++ hostOs ++ "_HOST_OS 1"
445 , "#define " ++ targetOs ++ "_TARGET_OS 1"
446 , "#define BUILD_OS " ++ show buildOs
447 , "#define HOST_OS " ++ show hostOs
448 , "#define TARGET_OS " ++ show targetOs
449 , ""
450 , "#define " ++ buildVendor ++ "_BUILD_VENDOR 1"
451 , "#define " ++ hostVendor ++ "_HOST_VENDOR 1"
452 , "#define " ++ targetVendor ++ "_TARGET_VENDOR 1"
453 , "#define BUILD_VENDOR " ++ show buildVendor
454 , "#define HOST_VENDOR " ++ show hostVendor
455 , "#define TARGET_VENDOR " ++ show targetVendor
456 , ""
457 , "#endif /* __PLATFORM_H__ */" ]
458
459 -- | Generate @ghcversion.h@ header.
460 generateGhcVersionH :: Expr String
461 generateGhcVersionH = do
462 trackGenerateHs
463 version <- getSetting ProjectVersionInt
464 patchLevel1 <- getSetting ProjectPatchLevel1
465 patchLevel2 <- getSetting ProjectPatchLevel2
466 return . unlines $
467 [ "#ifndef __GHCVERSION_H__"
468 , "#define __GHCVERSION_H__"
469 , ""
470 , "#ifndef __GLASGOW_HASKELL__"
471 , "# define __GLASGOW_HASKELL__ " ++ version
472 , "#endif"
473 , ""]
474 ++
475 [ "#define __GLASGOW_HASKELL_PATCHLEVEL1__ " ++ patchLevel1 | patchLevel1 /= "" ]
476 ++
477 [ "#define __GLASGOW_HASKELL_PATCHLEVEL2__ " ++ patchLevel2 | patchLevel2 /= "" ]
478 ++
479 [ ""
480 , "#define MIN_VERSION_GLASGOW_HASKELL(ma,mi,pl1,pl2) (\\"
481 , " ((ma)*100+(mi)) < __GLASGOW_HASKELL__ || \\"
482 , " ((ma)*100+(mi)) == __GLASGOW_HASKELL__ \\"
483 , " && (pl1) < __GLASGOW_HASKELL_PATCHLEVEL1__ || \\"
484 , " ((ma)*100+(mi)) == __GLASGOW_HASKELL__ \\"
485 , " && (pl1) == __GLASGOW_HASKELL_PATCHLEVEL1__ \\"
486 , " && (pl2) <= __GLASGOW_HASKELL_PATCHLEVEL2__ )"
487 , ""
488 , "#endif /* __GHCVERSION_H__ */" ]
489
490 -- | Generate @Version.hs@ files.
491 generateVersionHs :: Expr String
492 generateVersionHs = do
493 trackGenerateHs
494 projectVersion <- getSetting ProjectVersion
495 targetOs <- getSetting TargetOs
496 targetArch <- getSetting TargetArch
497 return $ unlines
498 [ "module Version where"
499 , "version, targetOS, targetARCH :: String"
500 , "version = " ++ show projectVersion
501 , "targetOS = " ++ show targetOs
502 , "targetARCH = " ++ show targetArch ]