@@ -3,18 +3,21 @@
3#ifndef MIN_VERSION_Cabal
3#ifndef MIN_VERSION_Cabal
4#define MIN_VERSION_Cabal(x,y,z) 0
4#define MIN_VERSION_Cabal(x,y,z) 0
6+#if MIN_VERSION_Cabal(1,24,0)
7+#define InstalledPackageId UnitId
6module Main (main) where
9module Main (main) where
8import Data.List ( nub )
11import Data.List ( nub )
9import Distribution.Package ( InstalledPackageId )
12import Distribution.Package ( InstalledPackageId )
10import Distribution.Package ( PackageId, Package (..), packageVersion, packageName )
13import Distribution.Package ( PackageId, Package (..), packageVersion, packageName )
11−import Distribution.PackageDescription ( PackageDescription(), TestSuite(..) )
14+import Distribution.PackageDescription ( PackageDescription(), TestSuite(..) , Library (..), BuildInfo (..))
12import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )
15import Distribution.Simple ( defaultMainWithHooks, UserHooks(..), simpleUserHooks )
13import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose, copyFiles )
16import Distribution.Simple.Utils ( rewriteFile, createDirectoryIfMissingVerbose, copyFiles )
14import Distribution.Simple.BuildPaths ( autogenModulesDir )
17import Distribution.Simple.BuildPaths ( autogenModulesDir )
15−import Distribution.Simple.Setup ( BuildFlags(buildVerbosity), Flag(..), fromFlag, HaddockFlags(haddockDistPref))
18+import Distribution.Simple.Setup ( BuildFlags(buildDistPref, buildVerbosity), Flag(..), fromFlag, HaddockFlags(haddockDistPref))
16−import Distribution.Simple.LocalBuildInfo ( withLibLBI, withTestLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps), compiler, buildDir )
19+import Distribution.Simple.LocalBuildInfo ( withPackageDB, withLibLBI, withTestLBI, LocalBuildInfo(), ComponentLocalBuildInfo(componentPackageDeps), compiler, buildDir )
17−import Distribution.Simple.Compiler ( showCompilerId )
20+import Distribution.Simple.Compiler ( showCompilerId , PackageDB (..))
18import Distribution.Text ( display , simpleParse )
21import Distribution.Text ( display , simpleParse )
19import Distribution.Verbosity ( Verbosity, normal )
22import Distribution.Verbosity ( Verbosity, normal )
20import System.FilePath ( (</>) )
23import System.FilePath ( (</>) )
@@ -26,7 +29,7 @@ import Distribution.Simple.BuildPaths ( autogenComponentModulesDir )
26main :: IO ()
29main :: IO ()
27main = defaultMainWithHooks simpleUserHooks
30main = defaultMainWithHooks simpleUserHooks
28 { buildHook = \pkg lbi hooks flags -> do
31 { buildHook = \pkg lbi hooks flags -> do
29− generateBuildModule (fromFlag (buildVerbosity flags)) pkg lbi
32+ generateBuildModule flags pkg lbi
30 buildHook simpleUserHooks pkg lbi hooks flags
33 buildHook simpleUserHooks pkg lbi hooks flags
@@ -37,41 +40,57 @@ haddockOutputDir flags pkg = destDir where
37 Flag x -> x
40 Flag x -> x
38 destDir = baseDir </> "doc" </> "html" </> display (packageName pkg)
41 destDir = baseDir </> "doc" </> "html" </> display (packageName pkg)
40−generateBuildModule :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ()
43+generateBuildModule :: BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()
41−generateBuildModule verbosity pkg lbi = do
44+generateBuildModule flags pkg lbi = do
42− let dir = autogenModulesDir lbi
45+ let verbosity = fromFlag (buildVerbosity flags)
46+ let distPref = fromFlag (buildDistPref flags)
49+ let dbStack = withPackageDB lbi ++ [ SpecificPackageDB $ distPref </> "package.conf.inplace" ]
50+ let dbFlags = "-hide-all-packages" : packageDbArgs dbStack
43 let bdir = buildDir lbi
52 let bdir = buildDir lbi
44− createDirectoryIfMissingVerbose verbosity True dir
45− withLibLBI pkg lbi $ \_ libcfg -> do
53+ withLibLBI pkg lbi $ \lib libcfg -> do
54+ let libBI = libBuildInfo lib
56+ -- Lib sources and includes
57+ let iArgs = map ("-i"++) $ hsSourceDirs libBI
58+ let includeArgs = map ("-I"++) $ includeDirs libBI
46 -- We need the directory with library's cabal_macros.h!
60 -- We need the directory with library's cabal_macros.h!
47#if MIN_VERSION_Cabal(1,25,0)
61#if MIN_VERSION_Cabal(1,25,0)
48− let dir2 = autogenComponentModulesDir lbi libcfg
62+ let libAutogenDir = autogenComponentModulesDir lbi libcfg
50− let dir2 = dir
64+ let libAutogenDir = autogenModulesDir lbi
67+ -- CPP includes, i.e. include cabal_macros.h
68+ let cppFlags = [ "-optP-include", "-optP" ++ libAutogenDir ++ "/cabal_macros.h" ]
52 withTestLBI pkg lbi $ \suite suitecfg -> do
70 withTestLBI pkg lbi $ \suite suitecfg -> do
53− -- when (testName suite == "doctest") $ we need IsString instance
71+ -- when (testName suite == "doctests") $ we need IsString instance
73+ -- get and create autogen dir
74+#if MIN_VERSION_Cabal(1,25,0)
75+ let testAutogenDir = autogenComponentModulesDir lbi suitecfg
77+ let testAutogenDir = autogenModulesDir lbi
79+ createDirectoryIfMissingVerbose verbosity True testAutogenDir
81+ -- write autogen'd file
54− rewriteFile (dir </> "Build_doctests.hs") $ unlines
82+ rewriteFile (testAutogenDir </> "Build_doctests.hs") $ unlines
55 [ "module Build_doctests where"
83 [ "module Build_doctests where"
57− , "autogen_dir :: String"
58− , "autogen_dir = " ++ show dir
60− , "component_autogen_dir :: String"
61− , "component_autogen_dir = " ++ show dir2
63− , "build_dir :: String"
64− , "build_dir = " ++ show bdir
66 -- -package-id etc. flags
85 -- -package-id etc. flags
67 , "pkgs :: [String]"
86 , "pkgs :: [String]"
68 , "pkgs = " ++ (show $ formatDeps $ testDeps libcfg suitecfg)
87 , "pkgs = " ++ (show $ formatDeps $ testDeps libcfg suitecfg)
70− , "compiler :: String"
89+ , "flags :: [String]"
71− , "compiler = " ++ (show $ showCompilerId $ compiler lbi)
90+ , "flags = " ++ show (iArgs ++ includeArgs ++ dbFlags ++ cppFlags)
73− , "isOldCompiler :: Bool"
92+ , "src_dirs :: [String]"
74− , "isOldCompiler = " ++ show isOldCompiler
93+ , "src_dirs = " ++ show (hsSourceDirs libBI)
77 -- we do this check in Setup, as then doctests don't need to depend on Cabal
96 -- we do this check in Setup, as then doctests don't need to depend on Cabal
@@ -87,6 +106,43 @@ generateBuildModule verbosity pkg lbi = do
87 | packageId pkg == pkgId = "-package=" ++ display pkgId
106 | packageId pkg == pkgId = "-package=" ++ display pkgId
88 | otherwise = "-package-id=" ++ display installedPkgId
107 | otherwise = "-package-id=" ++ display installedPkgId
109+ -- From Distribution.Simple.Program.GHC
110+ packageDbArgs :: [PackageDB] -> [String]
111+ packageDbArgs | isOldCompiler = packageDbArgsConf
112+ | otherwise = packageDbArgsDb
114+ -- GHC <7.6 uses '-package-conf' instead of '-package-db'.
115+ packageDbArgsConf :: [PackageDB] -> [String]
116+ packageDbArgsConf dbstack = case dbstack of
117+ (GlobalPackageDB:UserPackageDB:dbs) -> concatMap specific dbs
118+ (GlobalPackageDB:dbs) -> ("-no-user-package-conf")
119+ : concatMap specific dbs
122+ specific (SpecificPackageDB db) = [ "-package-conf=" ++ db ]
124+ ierror = error $ "internal error: unexpected package db stack: "
127+ -- GHC >= 7.6 uses the '-package-db' flag. See
128+ -- https://ghc.haskell.org/trac/ghc/ticket/5977.
129+ packageDbArgsDb :: [PackageDB] -> [String]
130+ -- special cases to make arguments prettier in common scenarios
131+ packageDbArgsDb dbstack = case dbstack of
132+ (GlobalPackageDB:UserPackageDB:dbs)
133+ | all isSpecific dbs -> concatMap single dbs
134+ (GlobalPackageDB:dbs)
135+ | all isSpecific dbs -> "-no-user-package-db"
136+ : concatMap single dbs
137+ dbs -> "-clear-package-db"
138+ : concatMap single dbs
140+ single (SpecificPackageDB db) = [ "-package-db=" ++ db ]
141+ single GlobalPackageDB = [ "-global-package-db" ]
142+ single UserPackageDB = [ "-user-package-db" ]
143+ isSpecific (SpecificPackageDB _) = True
144+ isSpecific _ = False
90testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]
146testDeps :: ComponentLocalBuildInfo -> ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId)]
91testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys
147testDeps xs ys = nub $ componentPackageDeps xs ++ componentPackageDeps ys