698326bfdc49778733e9902113cf60757d2a1879
[ghc.git] / src / Hadrian / Package.hs
1 -----------------------------------------------------------------------------
2 -- |
3 -- Module : Hadrian.Package
4 -- Copyright : (c) Andrey Mokhov 2014-2017
5 -- License : MIT (see the file LICENSE)
6 -- Maintainer : andrey.mokhov@gmail.com
7 -- Stability : experimental
8 --
9 -- A /package/ is a collection of files. We currently only support C and Haskell
10 -- packages and treat a package as either a library or a program. The latter is
11 -- a gross oversimplification as, for example, Haskell packages can be both.
12 -- This works for now, but should be improved in future.
13 -----------------------------------------------------------------------------
14 module Hadrian.Package (
15 -- * Data types
16 Package (..), PackageName, PackageLanguage, PackageType,
17
18 -- * Construction and properties
19 cLibrary, cProgram, hsLibrary, hsProgram, dummyPackage,
20 isLibrary, isProgram, isCPackage, isHsPackage,
21
22 -- * Package directory structure
23 pkgCabalFile, unsafePkgCabalFile
24 ) where
25
26 import Data.Maybe
27 import Development.Shake.FilePath
28 import GHC.Stack
29 import Hadrian.Package.Type
30 import Hadrian.Utilities
31
32 -- | Construct a C library package.
33 cLibrary :: PackageName -> FilePath -> Package
34 cLibrary = Package C Library
35
36 -- | Construct a C program package.
37 cProgram :: PackageName -> FilePath -> Package
38 cProgram = Package C Program
39
40 -- | Construct a Haskell library package.
41 hsLibrary :: PackageName -> FilePath -> Package
42 hsLibrary = Package Haskell Library
43
44 -- | Construct a Haskell program package.
45 hsProgram :: PackageName -> FilePath -> Package
46 hsProgram = Package Haskell Program
47
48 -- | A dummy package, which we never try to build
49 -- but just use as a better @undefined@ in code
50 -- where we need a 'Package' to set up a Context
51 -- but will not really operate over one.
52 dummyPackage :: Package
53 dummyPackage = hsLibrary "dummy" "dummy/path/"
54
55 -- | Is this a library package?
56 isLibrary :: Package -> Bool
57 isLibrary (Package _ Library _ _) = True
58 isLibrary _ = False
59
60 -- | Is this a program package?
61 isProgram :: Package -> Bool
62 isProgram (Package _ Program _ _) = True
63 isProgram _ = False
64
65 -- | Is this a C package?
66 isCPackage :: Package -> Bool
67 isCPackage (Package C _ _ _) = True
68 isCPackage _ = False
69
70 -- | Is this a Haskell package?
71 isHsPackage :: Package -> Bool
72 isHsPackage (Package Haskell _ _ _) = True
73 -- we consider the RTS as a haskell package because we
74 -- use information from its Cabal file to build it,
75 -- and we e.g want 'pkgCabalFile' to point us to
76 -- 'rts/rts.cabal' when passed the rts package as argument.
77 isHsPackage (Package _ _ "rts" _) = True
78 isHsPackage _ = False
79
80 -- | The path to the Cabal file of a Haskell package, e.g. @ghc/ghc-bin.cabal@,
81 -- or @Nothing@ if the argument is not a Haskell package.
82 pkgCabalFile :: Package -> Maybe FilePath
83 pkgCabalFile p | isHsPackage p = Just $ pkgPath p -/- pkgName p <.> "cabal"
84 | otherwise = Nothing
85
86 -- | Like 'pkgCabalFile' but raises an error on a non-Haskell package.
87 unsafePkgCabalFile :: HasCallStack => Package -> FilePath
88 unsafePkgCabalFile p = fromMaybe (error msg) (pkgCabalFile p)
89 where
90 msg = "[unsafePkgCabalFile] Not a Haskell package: " ++ show p