on master help sign in
Install and use build tools first
commit594c88e0a8b912b75919994eeb55ec111fd29003 authorMichael Snoyman <michael@snoyman.com> dateWed 5 Dec 2012, 10:50 (14 years ago) parentaf5e010
5 files changed+85−25
Stackage/Build.hs+45−3 Stackage/LoadDatabase.hs+15−4 Stackage/Test.hs+2−15 Stackage/Types.hs+4−3 Stackage/Util.hs+19
Stackage/Build.hs+45−3
@@ -20,6 +20,8 @@ import System.Directory (createDirectoryIfMissing, canonicalizePat
2020import Distribution.Version (thisVersion, withinRange)
2121import Control.Exception (assert)
2222import Data.Set (empty)
23+import qualified Data.Map as Map
24+import qualified Data.Set as Set
2325
2426defaultBuildSettings :: BuildSettings
2527defaultBuildSettings = BuildSettings
@@ -76,7 +78,30 @@ build settings' = do
7678 | v `withinRange` vr -> return ()
7779 | otherwise -> error $ "Unsupported Cabal version: " ++ libVersion
7880
79− ph <- withBinaryFile "build.log" WriteMode $ \handle ->
81+ menv <- fmap Just $ getModifiedEnv settings
82+ let runCabal args handle = runProcess "cabal" args Nothing menv Nothing (Just handle) (Just handle)
83+
84+ -- First install build tools so they can be used below.
85+ case iiBuildTools ii of
86+ [] -> putStrLn "No build tools required"
87+ tools -> do
88+ putStrLn $ "Installing the following build tools: " ++ unwords tools
89+ ph1 <- withBinaryFile "build-tools.log" WriteMode $ \handle -> do
90+ let args = addCabalArgs settings
91+ $ "install"
92+ : ("--cabal-lib-version=" ++ libVersion)
93+ : "--build-log=logs-tools/$pkg.log"
94+ : "-j"
95+ : iiBuildTools ii
96+ hPutStrLn handle ("cabal " ++ unwords (map (\s -> "'" ++ s ++ "'") args))
97+ runCabal args handle
98+ ec1 <- waitForProcess ph1
99+ unless (ec1 == ExitSuccess) $ do
100+ putStrLn "Building of build tools failed, please see build-tools.log"
101+ exitWith ec1
102+ putStrLn "Build tools built"
103+
104+ ph <- withBinaryFile "build.log" WriteMode $ \handle -> do
80105 let args = addCabalArgs settings
81106 $ "install"
82107 : ("--cabal-lib-version=" ++ libVersion)
@@ -87,8 +112,8 @@ build settings' = do
87112 , extraArgs settings
88113 , iiPackageList ii
89114 ]
90− in do hPutStrLn handle ("cabal " ++ unwords (map (\s -> "'" ++ s ++ "'") args))
91− runProcess "cabal" args Nothing Nothing Nothing (Just handle) (Just handle)
115+ hPutStrLn handle ("cabal " ++ unwords (map (\s -> "'" ++ s ++ "'") args))
116+ runCabal args handle
92117 ec <- waitForProcess ph
93118 unless (ec == ExitSuccess) $ do
94119 putStrLn "Build failed, please see build.log"
@@ -99,3 +124,20 @@ build settings' = do
99124
100125 putStrLn "All test suites that were expected to pass did pass, building tarballs."
101126 makeTarballs ii
127+
128+-- | Get all of the build tools required.
129+iiBuildTools :: InstallInfo -> [String]
130+iiBuildTools InstallInfo { iiPackageDB = PackageDB m, iiPackages = packages } =
131+ -- FIXME possible improvement: track the dependencies between the build
132+ -- tools themselves, and install them in the correct order.
133+ map unPackageName
134+ $ filter (flip Map.member m)
135+ $ Set.toList
136+ $ Set.unions
137+ $ map piBuildTools
138+ $ Map.elems
139+ $ Map.filterWithKey isSelected m
140+ where
141+ unPackageName (PackageName pn) = pn
142+ isSelected name _ = name `Set.member` selected
143+ selected = Set.fromList $ Map.keys packages
Stackage/LoadDatabase.hs+15−4
@@ -12,7 +12,7 @@ import Distribution.PackageDescription (condExecutables,
1212 condLibrary,
1313 condTestSuites,
1414 condBenchmarks,
15− condTreeConstraints, condTreeComponents, ConfVar (..), Condition(..), flagName, flagDefault, genPackageFlags)
15+ condTreeConstraints, condTreeComponents, ConfVar (..), Condition(..), flagName, flagDefault, genPackageFlags, allBuildInfo, packageDescription, buildTools, libBuildInfo, condTreeData, buildInfo, testBuildInfo, benchmarkBuildInfo)
1616import Distribution.PackageDescription.Parse (ParseResult (ParseOk),
1717 parsePackageDescription)
1818import Distribution.Version (withinRange)
@@ -59,11 +59,12 @@ loadPackageDB core deps = do
5959 _ ->
6060 case Tar.entryContent e of
6161 Tar.NormalFile bs _ -> do
62− let (deps', hasTests) = parseDeps bs
62+ let (deps', hasTests, buildTools) = parseDeps bs
6363 return $ mappend pdb $ PackageDB $ Map.singleton p PackageInfo
6464 { piVersion = v
6565 , piDeps = deps'
6666 , piHasTests = hasTests
67+ , piBuildTools = buildTools
6768 }
6869 _ -> return pdb
6970
@@ -74,9 +75,19 @@ loadPackageDB core deps = do
7475 , mconcat $ map (go gpd . snd) $ condExecutables gpd
7576 , mconcat $ map (go gpd . snd) $ condTestSuites gpd
7677 , mconcat $ map (go gpd . snd) $ condBenchmarks gpd
77− ], not $ null $ condTestSuites gpd)
78− _ -> (mempty, defaultHasTestSuites)
78+ ], not $ null $ condTestSuites gpd
79+ , Set.fromList $ map depName $ allBuildInfo gpd)
80+ _ -> (mempty, defaultHasTestSuites, Set.empty)
7981 where
82+ allBuildInfo gpd = concat
83+ [ maybe mempty (goBI libBuildInfo) $ condLibrary gpd
84+ , concat $ map (goBI buildInfo . snd) $ condExecutables gpd
85+ , concat $ map (goBI testBuildInfo . snd) $ condTestSuites gpd
86+ , concat $ map (goBI benchmarkBuildInfo . snd) $ condBenchmarks gpd
87+ ]
88+ where
89+ goBI f x = buildTools $ f $ condTreeData x
90+ depName (Dependency p _) = p
8091 go gpd tree
8192 = Set.unions
8293 $ Set.fromList (map (\(Dependency p _) -> p) $ condTreeConstraints tree)
Stackage/Test.hs+2−15
@@ -1,4 +1,3 @@
1−{-# LANGUAGE CPP #-}
21{-# LANGUAGE DeriveDataTypeable #-}
32module Stackage.Test
43 ( runTestSuites
@@ -32,18 +31,6 @@ runTestSuites settings ii = do
3231
3332 hasTestSuites name = maybe defaultHasTestSuites piHasTests $ Map.lookup name pdb
3433
35−-- | Separate for the PATH environment variable
36−pathSep :: Char
37−#ifdef mingw32_HOST_OS
38−pathSep = ';'
39−#else
40−pathSep = ':'
41−#endif
42−
43−fixEnv :: FilePath -> (String, String) -> (String, String)
44−fixEnv bin (p@"PATH", x) = (p, bin ++ pathSep : x)
45−fixEnv _ x = x
46−
4734data TestException = TestException
4835 deriving (Show, Typeable)
4936instance Exception TestException
@@ -56,11 +43,11 @@ runTestSuite :: BuildSettings
5643 -> IO Bool
5744runTestSuite settings testdir hasTestSuites prevPassed (packageName, (version, Maintainer maintainer)) = do
5845 -- Set up a new environment that includes the sandboxed bin folder in PATH.
59− env' <- getEnvironment
46+ env' <- getModifiedEnv settings
6047 let menv addGPP
6148 = Just $ (if addGPP then (("GHC_PACKAGE_PATH", packageDir settings ++ ":"):) else id)
6249 $ ("HASKELL_PACKAGE_SANDBOX", packageDir settings)
63− : map (fixEnv $ binDir settings) env'
50+ : env'
6451
6552 let runGen addGPP cmd args wdir handle = do
6653 ph <- runProcess cmd args (Just wdir) (menv addGPP) Nothing (Just handle) (Just handle)
Stackage/Types.hs+4−3
@@ -25,9 +25,10 @@ instance Monoid PackageDB where
2525 | otherwise = pi2
2626
2727data PackageInfo = PackageInfo
28− { piVersion :: Version
29− , piDeps :: Set PackageName
30− , piHasTests :: Bool
28+ { piVersion :: Version
29+ , piDeps :: Set PackageName
30+ , piHasTests :: Bool
31+ , piBuildTools :: Set PackageName
3132 }
3233 deriving (Show, Eq, Ord)
3334
Stackage/Util.hs+19
@@ -1,3 +1,4 @@
1+{-# LANGUAGE CPP #-}
12module Stackage.Util where
23
34import qualified Codec.Archive.Tar as Tar
@@ -14,6 +15,7 @@ import System.Directory (doesDirectoryExist,
1415 removeDirectoryRecursive)
1516import System.Directory (getAppUserDataDirectory)
1617import System.FilePath ((</>))
18+import System.Environment (getEnvironment)
1719
1820identsToRanges :: Set PackageIdentifier -> Map PackageName (VersionRange, Maintainer)
1921identsToRanges =
@@ -84,3 +86,20 @@ addCabalArgs settings rest
8486 : ("--datadir=" ++ dataDir settings)
8587 : ("--docdir=" ++ docDir settings)
8688 : extraArgs settings ++ rest
89+
90+-- | Modified environment that adds our sandboxed bin folder to PATH.
91+getModifiedEnv :: BuildSettings -> IO [(String, String)]
92+getModifiedEnv settings = do
93+ fmap (map $ fixEnv $ binDir settings) getEnvironment
94+ where
95+ fixEnv :: FilePath -> (String, String) -> (String, String)
96+ fixEnv bin (p@"PATH", x) = (p, bin ++ pathSep : x)
97+ fixEnv _ x = x
98+
99+ -- | Separate for the PATH environment variable
100+ pathSep :: Char
101+#ifdef mingw32_HOST_OS
102+ pathSep = ';'
103+#else
104+ pathSep = ':'
105+#endif