Add test compiler option to test (#621)
[hadrian.git] / src / Context.hs
1 module Context (
2 -- * Context
3 Context (..), vanillaContext, stageContext,
4
5 -- * Expressions
6 getStage, getPackage, getWay, getStagedSettingList, getBuildPath,
7 withHsPackage,
8
9 -- * Paths
10 contextDir, buildPath, buildDir, pkgInplaceConfig, pkgSetupConfigFile,
11 pkgHaddockFile, pkgLibraryFile, pkgGhciLibraryFile, pkgConfFile, objectPath,
12 contextPath, getContextPath, libDir, libPath
13 ) where
14
15 import Base
16 import Context.Paths
17 import Context.Type
18 import Hadrian.Expression
19 import Hadrian.Haskell.Cabal
20 import Oracles.Setting
21
22 -- | Most targets are built only one way, hence the notion of 'vanillaContext'.
23 vanillaContext :: Stage -> Package -> Context
24 vanillaContext s p = Context s p vanilla
25
26 -- | Partial context with undefined 'Package' field. Useful for 'Packages'
27 -- expressions that only read the environment and current 'Stage'.
28 stageContext :: Stage -> Context
29 stageContext s = vanillaContext s $ error "stageContext: package not set"
30
31 -- | Get the 'Stage' of the current 'Context'.
32 getStage :: Expr Context b Stage
33 getStage = stage <$> getContext
34
35 -- | Get the 'Package' of the current 'Context'.
36 getPackage :: Expr Context b Package
37 getPackage = package <$> getContext
38
39 -- | Get the 'Way' of the current 'Context'.
40 getWay :: Expr Context b Way
41 getWay = way <$> getContext
42
43 -- | Get a list of configuration settings for the current stage.
44 getStagedSettingList :: (Stage -> SettingList) -> Args Context b
45 getStagedSettingList f = getSettingList . f =<< getStage
46
47 -- | Construct an expression that depends on the Cabal file of the current
48 -- package and is empty in a non-Haskell context.
49 withHsPackage :: (Monoid a, Semigroup a) => (Context -> Expr Context b a) -> Expr Context b a
50 withHsPackage expr = do
51 pkg <- getPackage
52 ctx <- getContext
53 case pkgCabalFile pkg of
54 Just _ -> expr ctx
55 Nothing -> mempty
56
57 pkgId :: Context -> Action FilePath
58 pkgId ctx@Context {..} = case pkgCabalFile package of
59 Just _ -> pkgIdentifier ctx
60 Nothing -> return (pkgName package) -- Non-Haskell packages, e.g. rts
61
62 libDir :: Context -> FilePath
63 libDir Context {..} = stageString stage -/- "lib"
64
65 -- | Path to the directory containg the final artifact in a given 'Context'
66 libPath :: Context -> Action FilePath
67 libPath context = buildRoot <&> (-/- libDir context)
68
69 pkgFile :: Context -> String -> String -> Action FilePath
70 pkgFile context@Context {..} prefix suffix = do
71 path <- buildPath context
72 pid <- pkgId context
73 return $ path -/- prefix ++ pid ++ suffix
74
75 -- | Path to inplace package configuration file of a given 'Context'.
76 pkgInplaceConfig :: Context -> Action FilePath
77 pkgInplaceConfig context = do
78 path <- contextPath context
79 return $ path -/- "inplace-pkg-config"
80
81 -- | Path to the @setup-config@ of a given 'Context'.
82 pkgSetupConfigFile :: Context -> Action FilePath
83 pkgSetupConfigFile context = do
84 path <- contextPath context
85 return $ path -/- "setup-config"
86
87 -- | Path to the haddock file of a given 'Context', e.g.:
88 -- @_build/stage1/libraries/array/doc/html/array/array.haddock@.
89 pkgHaddockFile :: Context -> Action FilePath
90 pkgHaddockFile Context {..} = do
91 root <- buildRoot
92 let name = pkgName package
93 return $ root -/- "docs/html/libraries" -/- name -/- name <.> "haddock"
94
95 -- | Path to the library file of a given 'Context', e.g.:
96 -- @_build/stage1/libraries/array/build/libHSarray-0.5.1.0.a@.
97 pkgLibraryFile :: Context -> Action FilePath
98 pkgLibraryFile context@Context {..} = do
99 extension <- libsuf way
100 pkgFile context "libHS" extension
101
102 -- | Path to the GHCi library file of a given 'Context', e.g.:
103 -- @_build/stage1/libraries/array/build/HSarray-0.5.1.0.o@.
104 pkgGhciLibraryFile :: Context -> Action FilePath
105 pkgGhciLibraryFile context = pkgFile context "HS" ".o"
106
107 -- | Path to the configuration file of a given 'Context'.
108 pkgConfFile :: Context -> Action FilePath
109 pkgConfFile ctx@Context {..} = do
110 root <- buildRoot
111 pid <- pkgId ctx
112 return $ root -/- relativePackageDbPath stage -/- pid <.> "conf"
113
114 -- | Given a 'Context' and a 'FilePath' to a source file, compute the 'FilePath'
115 -- to its object file. For example:
116 -- * "Task.c" -> "_build/stage1/rts/Task.thr_o"
117 -- * "_build/stage1/rts/cmm/AutoApply.cmm" -> "_build/stage1/rts/cmm/AutoApply.o"
118 objectPath :: Context -> FilePath -> Action FilePath
119 objectPath context@Context {..} src = do
120 isGenerated <- isGeneratedSource src
121 path <- buildPath context
122 let extension = drop 1 $ takeExtension src
123 obj = src -<.> osuf way
124 result | isGenerated = obj
125 | "*hs*" ?== extension = path -/- obj
126 | otherwise = path -/- extension -/- obj
127 return result