summaryrefslogtreecommitdiff
path: root/hadrian/src/Rules/PackageData.hs
diff options
context:
space:
mode:
Diffstat (limited to 'hadrian/src/Rules/PackageData.hs')
-rw-r--r--hadrian/src/Rules/PackageData.hs119
1 files changed, 119 insertions, 0 deletions
diff --git a/hadrian/src/Rules/PackageData.hs b/hadrian/src/Rules/PackageData.hs
new file mode 100644
index 0000000000..2442b03de3
--- /dev/null
+++ b/hadrian/src/Rules/PackageData.hs
@@ -0,0 +1,119 @@
+module Rules.PackageData (buildPackageData) where
+
+import Base
+import Context
+import Expression
+import Oracles.Setting
+import Rules.Generate
+import Settings.Packages.Rts
+import Target
+import Utilities
+
+-- | Build @package-data.mk@ by using ghc-cabal utility to process .cabal files.
+buildPackageData :: Context -> Rules ()
+buildPackageData context@Context {..} = do
+ let dir = "//" ++ contextDir context
+ cabalFile = unsafePkgCabalFile package -- TODO: improve
+ configure = pkgPath package -/- "configure"
+ -- TODO: Get rid of hardcoded file paths.
+ [dir -/- "package-data.mk", dir -/- "setup-config"] &%> \[mk, setupConfig] -> do
+ -- Make sure all generated dependencies are in place before proceeding.
+ orderOnly =<< interpretInContext context generatedDependencies
+
+ -- GhcCabal may run the configure script, so we depend on it.
+ whenM (doesFileExist $ configure <.> "ac") $ need [configure]
+
+ -- Before we configure a package its dependencies need to be registered.
+ need =<< mapM pkgConfFile =<< contextDependencies context
+
+ need [cabalFile]
+ build $ target context GhcCabal [cabalFile] [mk, setupConfig]
+ postProcessPackageData context mk
+
+ -- TODO: Get rid of hardcoded file paths.
+ dir -/- "inplace-pkg-config" %> \conf -> do
+ path <- buildPath context
+ dataFile <- pkgDataFile context
+ need [dataFile] -- ghc-cabal builds inplace package configuration file
+ if package == rts
+ then do
+ genPath <- buildRoot <&> (-/- generatedDir)
+ rtsPath <- rtsBuildPath
+ need [rtsConfIn]
+ build $ target context HsCpp [rtsConfIn] [conf]
+ fixFile conf $ unlines
+ . map
+ ( replace "\"\"" ""
+ . replace "rts/dist/build" rtsPath
+ . replace "includes/dist-derivedconstants/header" genPath )
+ . lines
+ else
+ fixFile conf $ unlines . map (replace (path </> "build") path) . lines
+
+ priority 2.0 $ when (nonCabalContext context) $ dir -/- "package-data.mk" %>
+ generatePackageData context
+
+generatePackageData :: Context -> FilePath -> Action ()
+generatePackageData context@Context {..} file = do
+ orderOnly =<< interpretInContext context generatedDependencies
+ asmSrcs <- packageAsmSources package
+ cSrcs <- packageCSources package
+ cmmSrcs <- packageCmmSources package
+ genPath <- buildRoot <&> (-/- generatedDir)
+ writeFileChanged file . unlines $
+ [ "S_SRCS = " ++ unwords asmSrcs ] ++
+ [ "C_SRCS = " ++ unwords cSrcs ] ++
+ [ "CMM_SRCS = " ++ unwords cmmSrcs ] ++
+ [ "DEP_EXTRA_LIBS = m" | package == hp2ps ] ++
+ [ "CC_OPTS = -I" ++ genPath | package `elem` [hp2ps, rts]] ++
+ [ "MODULES = Main" | package == ghcCabal ] ++
+ [ "HS_SRC_DIRS = ." | package == ghcCabal ]
+ putSuccess $ "| Successfully generated " ++ file
+
+packageCSources :: Package -> Action [FilePath]
+packageCSources pkg
+ | pkg /= rts = getDirectoryFiles (pkgPath pkg) ["*.c"]
+ | otherwise = do
+ windows <- windowsHost
+ rtsPath <- rtsBuildPath
+ sources <- fmap (map unifyPath) . getDirectoryFiles (pkgPath pkg) .
+ map (-/- "*.c") $ [ ".", "hooks", "sm", "eventlog", "linker" ] ++
+ [ if windows then "win32" else "posix" ]
+ return $ sources ++ [ rtsPath -/- "c/sm/Evac_thr.c" ]
+ ++ [ rtsPath -/- "c/sm/Scav_thr.c" ]
+
+packageAsmSources :: Package -> Action [FilePath]
+packageAsmSources pkg
+ | pkg /= rts = return []
+ | otherwise = do
+ buildAdjustor <- anyTargetArch ["i386", "powerpc", "powerpc64"]
+ buildStgCRunAsm <- anyTargetArch ["powerpc64le"]
+ return $ [ "AdjustorAsm.S" | buildAdjustor ]
+ ++ [ "StgCRunAsm.S" | buildStgCRunAsm ]
+
+packageCmmSources :: Package -> Action [FilePath]
+packageCmmSources pkg
+ | pkg /= rts = return []
+ | otherwise = do
+ rtsPath <- rtsBuildPath
+ sources <- getDirectoryFiles (pkgPath pkg) ["*.cmm"]
+ return $ sources ++ [ rtsPath -/- "cmm/AutoApply.cmm" ]
+
+-- Prepare a given 'packaga-data.mk' file for parsing by readConfigFile:
+-- 1) Drop lines containing '$'. For example, get rid of
+-- @libraries/Win32_dist-install_CMM_SRCS := $(addprefix cbits/,$(notdir ...@
+-- and replace it with a tracked call to getDirectoryFiles.
+-- 2) Drop path prefixes to individual settings.
+-- For example, @libraries/deepseq/dist-install_VERSION = 1.4.0.0@
+-- is replaced by @VERSION = 1.4.0.0@.
+-- Reason: Shake's built-in makefile parser doesn't recognise slashes
+-- TODO (izgzhen): should fix DEP_LIB_REL_DIRS_SEARCHPATH
+postProcessPackageData :: Context -> FilePath -> Action ()
+postProcessPackageData context@Context {..} file = do
+ top <- topDirectory
+ cmmSrcs <- getDirectoryFiles (pkgPath package) ["cbits/*.cmm"]
+ path <- buildPath context
+ let len = length (pkgPath package) + length (top -/- path) + 2
+ fixFile file $ unlines
+ . (++ ["CMM_SRCS = " ++ unwords (map unifyPath cmmSrcs) ])
+ . map (drop len) . filter ('$' `notElem`) . lines