2442b03de346e0b37dd0e37e5b7e0a746139fb91
[ghc.git] / hadrian / src / Rules / PackageData.hs
1 module Rules.PackageData (buildPackageData) where
2
3 import Base
4 import Context
5 import Expression
6 import Oracles.Setting
7 import Rules.Generate
8 import Settings.Packages.Rts
9 import Target
10 import Utilities
11
12 -- | Build @package-data.mk@ by using ghc-cabal utility to process .cabal files.
13 buildPackageData :: Context -> Rules ()
14 buildPackageData context@Context {..} = do
15 let dir = "//" ++ contextDir context
16 cabalFile = unsafePkgCabalFile package -- TODO: improve
17 configure = pkgPath package -/- "configure"
18 -- TODO: Get rid of hardcoded file paths.
19 [dir -/- "package-data.mk", dir -/- "setup-config"] &%> \[mk, setupConfig] -> do
20 -- Make sure all generated dependencies are in place before proceeding.
21 orderOnly =<< interpretInContext context generatedDependencies
22
23 -- GhcCabal may run the configure script, so we depend on it.
24 whenM (doesFileExist $ configure <.> "ac") $ need [configure]
25
26 -- Before we configure a package its dependencies need to be registered.
27 need =<< mapM pkgConfFile =<< contextDependencies context
28
29 need [cabalFile]
30 build $ target context GhcCabal [cabalFile] [mk, setupConfig]
31 postProcessPackageData context mk
32
33 -- TODO: Get rid of hardcoded file paths.
34 dir -/- "inplace-pkg-config" %> \conf -> do
35 path <- buildPath context
36 dataFile <- pkgDataFile context
37 need [dataFile] -- ghc-cabal builds inplace package configuration file
38 if package == rts
39 then do
40 genPath <- buildRoot <&> (-/- generatedDir)
41 rtsPath <- rtsBuildPath
42 need [rtsConfIn]
43 build $ target context HsCpp [rtsConfIn] [conf]
44 fixFile conf $ unlines
45 . map
46 ( replace "\"\"" ""
47 . replace "rts/dist/build" rtsPath
48 . replace "includes/dist-derivedconstants/header" genPath )
49 . lines
50 else
51 fixFile conf $ unlines . map (replace (path </> "build") path) . lines
52
53 priority 2.0 $ when (nonCabalContext context) $ dir -/- "package-data.mk" %>
54 generatePackageData context
55
56 generatePackageData :: Context -> FilePath -> Action ()
57 generatePackageData context@Context {..} file = do
58 orderOnly =<< interpretInContext context generatedDependencies
59 asmSrcs <- packageAsmSources package
60 cSrcs <- packageCSources package
61 cmmSrcs <- packageCmmSources package
62 genPath <- buildRoot <&> (-/- generatedDir)
63 writeFileChanged file . unlines $
64 [ "S_SRCS = " ++ unwords asmSrcs ] ++
65 [ "C_SRCS = " ++ unwords cSrcs ] ++
66 [ "CMM_SRCS = " ++ unwords cmmSrcs ] ++
67 [ "DEP_EXTRA_LIBS = m" | package == hp2ps ] ++
68 [ "CC_OPTS = -I" ++ genPath | package `elem` [hp2ps, rts]] ++
69 [ "MODULES = Main" | package == ghcCabal ] ++
70 [ "HS_SRC_DIRS = ." | package == ghcCabal ]
71 putSuccess $ "| Successfully generated " ++ file
72
73 packageCSources :: Package -> Action [FilePath]
74 packageCSources pkg
75 | pkg /= rts = getDirectoryFiles (pkgPath pkg) ["*.c"]
76 | otherwise = do
77 windows <- windowsHost
78 rtsPath <- rtsBuildPath
79 sources <- fmap (map unifyPath) . getDirectoryFiles (pkgPath pkg) .
80 map (-/- "*.c") $ [ ".", "hooks", "sm", "eventlog", "linker" ] ++
81 [ if windows then "win32" else "posix" ]
82 return $ sources ++ [ rtsPath -/- "c/sm/Evac_thr.c" ]
83 ++ [ rtsPath -/- "c/sm/Scav_thr.c" ]
84
85 packageAsmSources :: Package -> Action [FilePath]
86 packageAsmSources pkg
87 | pkg /= rts = return []
88 | otherwise = do
89 buildAdjustor <- anyTargetArch ["i386", "powerpc", "powerpc64"]
90 buildStgCRunAsm <- anyTargetArch ["powerpc64le"]
91 return $ [ "AdjustorAsm.S" | buildAdjustor ]
92 ++ [ "StgCRunAsm.S" | buildStgCRunAsm ]
93
94 packageCmmSources :: Package -> Action [FilePath]
95 packageCmmSources pkg
96 | pkg /= rts = return []
97 | otherwise = do
98 rtsPath <- rtsBuildPath
99 sources <- getDirectoryFiles (pkgPath pkg) ["*.cmm"]
100 return $ sources ++ [ rtsPath -/- "cmm/AutoApply.cmm" ]
101
102 -- Prepare a given 'packaga-data.mk' file for parsing by readConfigFile:
103 -- 1) Drop lines containing '$'. For example, get rid of
104 -- @libraries/Win32_dist-install_CMM_SRCS := $(addprefix cbits/,$(notdir ...@
105 -- and replace it with a tracked call to getDirectoryFiles.
106 -- 2) Drop path prefixes to individual settings.
107 -- For example, @libraries/deepseq/dist-install_VERSION = 1.4.0.0@
108 -- is replaced by @VERSION = 1.4.0.0@.
109 -- Reason: Shake's built-in makefile parser doesn't recognise slashes
110 -- TODO (izgzhen): should fix DEP_LIB_REL_DIRS_SEARCHPATH
111 postProcessPackageData :: Context -> FilePath -> Action ()
112 postProcessPackageData context@Context {..} file = do
113 top <- topDirectory
114 cmmSrcs <- getDirectoryFiles (pkgPath package) ["cbits/*.cmm"]
115 path <- buildPath context
116 let len = length (pkgPath package) + length (top -/- path) + 2
117 fixFile file $ unlines
118 . (++ ["CMM_SRCS = " ++ unwords (map unifyPath cmmSrcs) ])
119 . map (drop len) . filter ('$' `notElem`) . lines