Commit 7ffb2940 authored by Andrey Mokhov's avatar Andrey Mokhov
Browse files

Add Targets.hs for specifying targets, clean up code.

parent 229d5cbd
......@@ -5,25 +5,18 @@ import Package.Data
import Package.Compile
import Package.Library
import Package.Dependencies
import Targets
-- See Package.Base for definitions of basic types
-- These are the packages we build:
packages :: [Package]
packages = [ libraryPackage "array" [ Stage1] defaultSettings
, libraryPackage "bin-package-db" [Stage0, Stage1] defaultSettings
, libraryPackage "binary" [Stage0, Stage1] defaultSettings
, libraryPackage "deepseq" [ Stage1] defaultSettings
, libraryPackage "Cabal/Cabal" [ Stage1] defaultSettings
, libraryPackage "containers" [ Stage1] defaultSettings
, libraryPackage "filepath" [ Stage1] defaultSettings
, libraryPackage "hoopl" [Stage0, Stage1] defaultSettings
, libraryPackage "hpc" [Stage0, Stage1] defaultSettings
, libraryPackage "parallel" [ Stage1] defaultSettings
, libraryPackage "pretty" [ Stage1] defaultSettings
, libraryPackage "stm" [ Stage1] defaultSettings
, libraryPackage "template-haskell" [ Stage1] defaultSettings
, libraryPackage "transformers" [Stage0, Stage1] defaultSettings ]
packages = map lib $ libraryPackageNames Stage1
where
lib name =
libraryPackage
name
[s | s <- [Stage0, Stage1], name `elem` (libraryPackageNames s)]
defaultSettings
-- Rule buildPackageX is defined in module Package.X
buildPackage :: Package -> TodoItem -> Rules ()
......@@ -35,15 +28,21 @@ buildPackage = buildPackageData
packageRules :: Rules ()
packageRules = do
-- TODO: control targets from command line arguments
forM_ packages $ \pkg @ (Package name path todo) -> do
forM_ todo $ \todoItem @ (stage, dist, settings) -> do
action $ putNormal $ "package = " ++ name ++ ", dist = " ++ dist
-- Want top .o and .a files for the pkg/todo combo
-- TODO: Check BUILD_GHCI_LIB flag to decide if .o is needed
action $ do
alwaysRerun
let buildDir = path </> dist </> "build"
pkgData = path </> dist </> "package-data.mk"
-- need [pkgData]
[key] <- arg (PackageKey pkgData)
putNormal $ "key = " ++ key
let oFile = buildDir </> "Hs" ++ key <.> "o"
ways' <- ways settings
aFiles <- forM ways' $ \way -> do
......
......@@ -7,11 +7,12 @@ module Package.Base (
Package (..), Settings (..), TodoItem (..),
defaultSettings, libraryPackage,
commonCcArgs, commonLdArgs, commonCppArgs, commonCcWarninigArgs,
bootPkgConstraints,
pathArgs, packageArgs, includeArgs, pkgHsSources,
pkgDepObjects, pkgLibObjects,
argSizeLimit,
sourceDependecies, argList, argListPath
sourceDependecies,
argList, argListWithComment,
argListPath
) where
import Base
......@@ -52,13 +53,10 @@ libraryPackage name stages settings =
Package
name
(toStandard $ "libraries" </> name)
[
( stage
[ (stage
, if stage == Stage0 then "dist-boot" else "dist-install"
, settings stage
)
| stage <- stages
]
, settings stage)
| stage <- stages ]
commonCcArgs :: Args
commonCcArgs = when Validating $ arg ["-Werror", "-Wall"]
......@@ -76,16 +74,6 @@ commonCcWarninigArgs = when Validating $ arg
, when (GccIsClang && not GccLt46 && windowsHost) $
arg "-Werror=unused-but-set-variable" ]
bootPkgConstraints :: Args
bootPkgConstraints = mempty
-- TODO: implement bootPkgConstraints oracle
-- BOOT_PKG_CONSTRAINTS := \
-- $(foreach d,$(PACKAGES_STAGE0),\
-- $(foreach p,$(basename $(notdir $(wildcard libraries/$d/*.cabal))),\
-- --constraint "$p == $(shell grep -i "^Version:" libraries/$d/$p.cabal |
-- sed "s/[^0-9.]//g")"))
pathArgs :: ShowArgs a => String -> FilePath -> a -> Args
pathArgs key path as =
map (\a -> key ++ toStandard (normaliseEx $ path </> a)) <$> arg as
......@@ -93,9 +81,12 @@ pathArgs key path as =
packageArgs :: Stage -> FilePath -> Args
packageArgs stage pkgData = do
usePackageKey <- SupportsPackageKey || stage /= Stage0
arg ["-hide-all-packages", "-no-user-package-db", "-include-pkg-deps"]
<> (stage == Stage0) <?> arg "-package-db libraries/bootstrapping.conf"
<> keyArgs usePackageKey
arg [ arg "-hide-all-packages"
, arg "-no-user-package-db"
, arg "-include-pkg-deps"
, when (stage == Stage0) $
arg "-package-db libraries/bootstrapping.conf"
, keyArgs usePackageKey ]
where
keyArgs True = productArgs "-this-package-key" (PackageKey pkgData) <>
productArgs "-package-key" (DepKeys pkgData)
......@@ -106,12 +97,14 @@ includeArgs :: FilePath -> FilePath -> Args
includeArgs path dist =
let pkgData = toStandard $ path </> dist </> "package-data.mk"
buildDir = toStandard $ path </> dist </> "build"
in arg "-i"
<> pathArgs "-i" path (SrcDirs pkgData)
<> concatArgs ["-i", "-I"] [buildDir, toStandard $ buildDir </> "autogen"]
<> pathArgs "-I" path (IncludeDirs pkgData)
<> arg "-optP-include" -- TODO: Shall we also add -cpp?
<> concatArgs "-optP" (toStandard $ buildDir </> "autogen/cabal_macros.h")
in arg [ arg "-i"
, pathArgs "-i" path $ SrcDirs pkgData
, concatArgs ["-i", "-I"]
[buildDir, toStandard $ buildDir </> "autogen"]
, pathArgs "-I" path $ IncludeDirs pkgData
, arg "-optP-include" -- TODO: Shall we also add -cpp?
, concatArgs "-optP" $
toStandard $ buildDir </> "autogen/cabal_macros.h" ]
pkgHsSources :: FilePath -> FilePath -> Action [FilePath]
pkgHsSources path dist = do
......@@ -162,7 +155,7 @@ argSizeLimit = do
windows <- windowsHost
return $ if windows
then 31000
else 1048576 -- surely, 1MB should be enough?
else 4194304 -- Cabal needs a bit more than 2MB!
-- List of source files, which need to be tracked by the build system
-- to make sure the argument lists have not changed.
......@@ -175,16 +168,18 @@ sourceDependecies = [ "shake/src/Package/Base.hs"
, "shake/src/Oracles/PackageData.hs"
, "shake/src/Ways.hs"
, "shake/src/Util.hs"
, "shake/src/Oracles.hs"
]
, "shake/src/Oracles.hs" ]
-- Convert Builder's argument list to a String
argList :: Builder -> Args -> String -> Action String
argList builder args comment = do
list <- args
-- Convert Builder's argument list to a printable String
argListWithComment :: String -> Builder -> Args -> Action String
argListWithComment comment builder args = do
args' <- args
return $ show builder ++ " arguments"
++ if comment == "" then "" else ("(" ++ comment ++ ")")
++ ":\n" ++ concatMap (\s -> " " ++ s ++ "\n") list
++ (if null comment then "" else " (" ++ comment ++ ")")
++ ":\n" ++ concatMap (\s -> " " ++ s ++ "\n") args'
argList :: Builder -> Args -> Action String
argList = argListWithComment ""
-- Path to argument list for a given Package/Stage combination
argListPath :: FilePath -> Package -> Stage -> FilePath
......
......@@ -8,27 +8,26 @@ argListDir :: FilePath
argListDir = "shake/arg/buildPackageCompile"
suffixArgs :: Way -> Args
suffixArgs way = arg ["-hisuf", hisuf way]
<> arg [ "-osuf", osuf way]
<> arg ["-hcsuf", hcsuf way]
suffixArgs way =
return ["-hisuf", hisuf way, "-osuf", osuf way, "-hcsuf", hcsuf way]
ghcArgs :: Package -> TodoItem -> Way -> [FilePath] -> FilePath -> Args
ghcArgs (Package _ path _) (stage, dist, _) way srcs result =
let buildDir = toStandard $ path </> dist </> "build"
pkgData = path </> dist </> "package-data.mk"
in suffixArgs way
<> wayHcArgs way
<> arg SrcHcOpts
<> packageArgs stage pkgData
<> includeArgs path dist
<> concatArgs ["-optP"] (CppOpts pkgData)
<> arg (HsOpts pkgData)
-- TODO: now we have both -O and -O2
-- <> arg ["-O2"]
<> productArgs ["-odir", "-hidir", "-stubdir"] buildDir
<> when (splitObjects stage) (arg "-split-objs")
<> arg ("-c":srcs)
<> arg ["-o", result]
in arg [ suffixArgs way
, wayHcArgs way
, arg SrcHcArgs
, packageArgs stage pkgData
, includeArgs path dist
, concatArgs ["-optP"] $ CppOpts pkgData
, arg $ HsOpts pkgData
-- TODO: now we have both -O and -O2
-- <> arg ["-O2"]
, productArgs ["-odir", "-hidir", "-stubdir"] buildDir
, when (splitObjects stage) $ arg "-split-objs"
, arg ("-c":srcs)
, arg ["-o", result] ]
buildRule :: Package -> TodoItem -> Rules ()
buildRule pkg @ (Package name path _) todo @ (stage, dist, _) =
......@@ -50,9 +49,10 @@ argListRule pkg todo @ (stage, _, settings) =
need $ ["shake/src/Package/Compile.hs"] ++ sourceDependecies
ways' <- ways settings
ghcList <- forM ways' $ \way ->
argList (Ghc stage)
argListWithComment
("way '" ++ tag way ++ "'")
(Ghc stage)
(ghcArgs pkg todo way ["input.hs"] $ "output" <.> osuf way)
$ "way '" ++ tag way ++ "'"
writeFileChanged out $ unlines ghcList
buildPackageCompile :: Package -> TodoItem -> Rules ()
......
......@@ -2,49 +2,49 @@
module Package.Data (buildPackageData) where
import Package.Base
import Targets
argListDir :: FilePath
argListDir = "shake/arg/buildPackageData"
libraryArgs :: [Way] -> Args
libraryArgs ways =
argEnable False "library-for-ghci" -- TODO: why always disable?
<> argEnable (vanilla `elem` ways) "library-vanilla"
<> (ghcWithInterpreter && not DynamicGhcPrograms && vanilla `elem` ways)
<?> argEnable True "library-for-ghci"
<> argEnable (profiling `elem` ways) "library-profiling"
<> argEnable (dynamic `elem` ways) "shared"
where
argEnable x key = arg $ (if x then "--enable-" else "--disable-") ++ key
libraryArgs ways = do
let enable x = ((if x then "--enable-" else "--disable-") ++)
libraryForGhci <- ghcWithInterpreter
&& not DynamicGhcPrograms
&& vanilla `elem` ways
return $
[ enable (vanilla `elem` ways) "library-vanilla"
, enable libraryForGhci "library-for-ghci"
, enable (profiling `elem` ways) "library-profiling"
, enable (dynamic `elem` ways) "shared" ]
configureArgs :: Stage -> Settings -> Args
configureArgs stage settings =
let argConf key as = do
let conf key as = do
s <- unwords <$> arg as
unless (null s) $ arg $ "--configure-option=" ++ key ++ "=" ++ s
cflags = commonCcArgs `filterOut` "-Werror"
<+> ConfCcArgs stage
<+> customCcArgs settings
<+> commonCcWarninigArgs
ldflags = commonLdArgs
<+> ConfGccLinkerArgs stage
<+> customLdArgs settings
cppflags = commonCppArgs
<+> ConfCppArgs stage
<+> customCppArgs settings
in argConf "CFLAGS" cflags
<> argConf "LDFLAGS" ldflags
<> argConf "CPPFLAGS" cppflags
<> arg (concat <$> "--gcc-options=" <+> cflags <+> " " <+> ldflags)
<> argConf "--with-iconv-includes" IconvIncludeDirs
<> argConf "--with-iconv-libraries" IconvLibDirs
<> argConf "--with-gmp-includes" GmpIncludeDirs
<> argConf "--with-gmp-libraries" GmpLibDirs
-- TODO: why TargetPlatformFull and not host?
<> when CrossCompiling (argConf "--host" TargetPlatformFull)
<> argConf "--with-cc" Gcc
cflags = [ commonCcArgs `filterOut` "-Werror"
, arg $ ConfCcArgs stage
, customCcArgs settings
, commonCcWarninigArgs ]
ldflags = [ commonLdArgs
, arg $ ConfGccLinkerArgs stage
, customLdArgs settings ]
cppflags = [ commonCppArgs
, arg $ ConfCppArgs stage
, customCppArgs settings ]
in arg [ conf "CFLAGS" cflags
, conf "LDFLAGS" ldflags
, conf "CPPFLAGS" cppflags
, arg $ concat <$> "--gcc-options=" <+> cflags <+> " " <+> ldflags
, conf "--with-iconv-includes" IconvIncludeDirs
, conf "--with-iconv-libraries" IconvLibDirs
, conf "--with-gmp-includes" GmpIncludeDirs
, conf "--with-gmp-libraries" GmpLibDirs
-- TODO: why TargetPlatformFull and not host?
, when CrossCompiling $ conf "--host" $ showArg TargetPlatformFull
, conf "--with-cc" $ showArg Gcc ]
-- Prepare a given 'packaga-data.mk' file for parsing by readConfigFile:
-- 1) Drop lines containing '$'
......@@ -58,32 +58,49 @@ postProcessPackageData file = do
where
(prefix, suffix) = break (== '=') line
bootPkgConstraints :: Package -> TodoItem -> Args
bootPkgConstraints (Package _ path _) (_, dist, _) = do
let pkgData = path </> dist </> "package-data.mk"
deps <- arg $ DepNames pkgData
let depsStage0 = filter ((`elem` deps) . takeBaseName)
$ libraryPackageNames Stage0
putNormal $ "depsStage0 = " ++ show depsStage0
forM depsStage0 $ \dep -> do
let depPkg = libraryPackage dep [Stage0] defaultSettings
(_, depPkgDist, _) = head $ pkgTodo depPkg
depPkgData = pkgPath depPkg </> depPkgDist
</> "package-data.mk"
[version] <- arg $ Version depPkgData
return $ "--constraint " ++ dep ++ " == " ++ version
cabalArgs :: Package -> TodoItem -> Args
cabalArgs (Package _ path _) (stage, dist, settings) =
arg ["configure", path, dist]
cabalArgs pkg @ (Package _ path _) todo @ (stage, dist, settings) = arg
[ arg ["configure", path, dist]
-- this is a positional argument, hence:
-- * if it is empty, we need to emit one empty string argument
-- * otherwise, we must collapse it into one space-separated string
<> arg (unwords <$> customDllArgs settings)
<> with (Ghc stage) -- TODO: used limited to max stage1 GHC
<> with (GhcPkg stage)
<> customConfArgs settings
<> (libraryArgs =<< ways settings)
<> when (specified HsColour) (with HsColour)
<> configureArgs stage settings
<> when (stage == Stage0) bootPkgConstraints
<> with Gcc
<> when (stage /= Stage0) (with Ld)
<> with Ar
<> with Alex
<> with Happy -- TODO: reorder with's
, arg (unwords <$> customDllArgs settings)
, with (Ghc stage) -- TODO: used limited to max stage1 GHC
, with (GhcPkg stage)
, customConfArgs settings
, libraryArgs =<< ways settings
, when (specified HsColour) $ with HsColour
, configureArgs stage settings
, when (stage == Stage0) $ bootPkgConstraints pkg todo
, with Gcc
, when (stage /= Stage0) $ with Ld
, with Ar
, with Alex
, with Happy ] -- TODO: reorder with's
ghcPkgArgs :: Package -> TodoItem -> Args
ghcPkgArgs (Package _ path _) (stage, dist, _) =
arg ["update", "--force"]
<> (stage == Stage0) <?>
arg "--package-db=libraries/bootstrapping.conf"
<> arg (toStandard $ path </> dist </> "inplace-pkg-config")
ghcPkgArgs (Package _ path _) (stage, dist, _) = return $
[ "update"
, "--force"
, toStandard $ path </> dist </> "inplace-pkg-config" ]
++
[ "--package-db=libraries/bootstrapping.conf" | stage == Stage0 ]
buildRule :: Package -> TodoItem -> Rules ()
buildRule pkg @ (Package name path _) todo @ (stage, dist, settings) =
......@@ -111,8 +128,8 @@ argListRule :: Package -> TodoItem -> Rules ()
argListRule pkg todo @ (stage, _, _) =
(argListPath argListDir pkg stage) %> \out -> do
need $ ["shake/src/Package/Data.hs"] ++ sourceDependecies
cabalList <- argList GhcCabal (cabalArgs pkg todo) ""
ghcPkgList <- argList (GhcPkg stage) (ghcPkgArgs pkg todo) ""
cabalList <- argList GhcCabal $ cabalArgs pkg todo
ghcPkgList <- argList (GhcPkg stage) $ ghcPkgArgs pkg todo
writeFileChanged out $ cabalList ++ "\n" ++ ghcPkgList
buildPackageData :: Package -> TodoItem -> Rules ()
......
......@@ -11,15 +11,15 @@ ghcArgs (Package name path _) (stage, dist, settings) =
let buildDir = toStandard $ path </> dist </> "build"
pkgData = path </> dist </> "package-data.mk"
depFile = buildDir </> takeBaseName name <.> "m"
in arg "-M"
<> packageArgs stage pkgData
<> includeArgs path dist
<> concatArgs ["-optP"] (CppOpts pkgData)
<> productArgs ["-odir", "-stubdir", "-hidir"] buildDir
<> arg ["-dep-makefile", depFile <.> "new"]
<> productArgs "-dep-suffix" (map wayPrefix <$> ways settings)
<> arg (HsOpts pkgData)
<> arg (pkgHsSources path dist)
in arg [ arg "-M"
, packageArgs stage pkgData
, includeArgs path dist
, concatArgs ["-optP"] $ CppOpts pkgData
, productArgs ["-odir", "-stubdir", "-hidir"] buildDir
, arg ["-dep-makefile", depFile <.> "new"]
, productArgs "-dep-suffix" $ map wayPrefix <$> ways settings
, arg $ HsOpts pkgData
, arg $ pkgHsSources path dist ]
buildRule :: Package -> TodoItem -> Rules ()
buildRule pkg @ (Package name path _) todo @ (stage, dist, settings) =
......@@ -38,7 +38,7 @@ argListRule :: Package -> TodoItem -> Rules ()
argListRule pkg todo @ (stage, _, _) =
(argListPath argListDir pkg stage) %> \out -> do
need $ ["shake/src/Package/Dependencies.hs"] ++ sourceDependecies
ghcList <- argList (Ghc stage) (ghcArgs pkg todo) ""
ghcList <- argList (Ghc stage) $ ghcArgs pkg todo
writeFileChanged out ghcList
buildPackageDependencies :: Package -> TodoItem -> Rules ()
......
......@@ -7,9 +7,9 @@ argListDir :: FilePath
argListDir = "shake/arg/buildPackageLibrary"
arArgs :: [FilePath] -> FilePath -> Args
arArgs objs result = arg $ [ arg "q"
, arg result
, arg objs ]
arArgs objs result = arg [ arg "q"
, arg result
, arg objs ]
arRule :: Package -> TodoItem -> Rules ()
arRule pkg @ (Package _ path _) todo @ (stage, dist, _) =
......@@ -30,11 +30,11 @@ ldArgs :: Package -> TodoItem -> FilePath -> Args
ldArgs (Package _ path _) (stage, dist, _) result = do
depObjs <- pkgDepObjects path dist vanilla
need depObjs
arg $ [arg (ConfLdLinkerArgs stage)
, arg "-r"
, arg "-o"
, arg result
, arg depObjs ]
arg [ arg $ ConfLdLinkerArgs stage
, arg "-r"
, arg "-o"
, arg result
, arg depObjs ]
ldRule :: Package -> TodoItem -> Rules ()
ldRule pkg @ (Package name path _) todo @ (stage, dist, _) =
......@@ -55,14 +55,16 @@ argListRule pkg @ (Package _ path _) todo @ (stage, dist, settings) =
(argListPath argListDir pkg stage) %> \out -> do
need $ ["shake/src/Package/Library.hs"] ++ sourceDependecies
ways' <- ways settings
ldList <- argList Ld (ldArgs pkg todo "output.o") ""
ldList <- argList Ld (ldArgs pkg todo "output.o")
arList <- forM ways' $ \way -> do
depObjs <- pkgDepObjects path dist way
need depObjs
libObjs <- pkgLibObjects path dist stage way
extension <- libsuf way
argList Ar (arArgs libObjs $ "output" <.> extension)
$ "way '" ++ tag way ++ "'"
argListWithComment
("way '" ++ tag way ++ "'")
Ar
(arArgs libObjs $ "output" <.> extension)
writeFileChanged out $ unlines $ [ldList] ++ arList
buildPackageLibrary :: Package -> TodoItem -> Rules ()
......
module Targets (libraryPackageNames) where
import Base
-- These are the packages we build:
-- TODO: this should eventually be removed and replaced by the top-level
-- target, i.e. GHC (and perhaps, something else)
libraryPackageNames :: Stage -> [String]
libraryPackageNames Stage0 =
[ "bin-package-db"
, "binary"
, "hoopl"
, "hpc"
, "transformers" ]
libraryPackageNames Stage1 = libraryPackageNames Stage0 ++
[ "array"
, "deepseq"
, "Cabal/Cabal"
, "containers"
, "filepath"
, "parallel"
, "pretty"
, "stm"
, "template-haskell" ]
libraryPackageNames _ = error "Not implemented"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment