Commit d23d418f authored by ijones's avatar ijones
Browse files

make executables build

* lots of work on making executables build
- added tests case for wash2hs
- added -i hsSourceDir
- added build dependencies
- since we have to fix dependencies at configure time, I added
  executableDeps to localBuildInfo
  (caused change in format for localBuildInfo)
- added code for actually putting the executables into place.

* libraries

- also added check to make sure there are libraries when building &
  installing the archive and such (hasLibs)
- don't register if hasLibs is false.
parent 17a1b0a1
......@@ -108,7 +108,20 @@ assertCmd command comment
= system command >>= assertEqual (command ++ ":" ++ comment) ExitSuccess
tests :: [Test]
tests = [TestLabel "testing the HUnit package" $ TestCase $
tests = [TestLabel "testing the wash2hs package" $ TestCase $
do oldDir <- getCurrentDirectory
setCurrentDirectory "test/wash2hs"
system "make clean"
system "make"
assertCmd "./setup configure --prefix=\",tmp\"" "wash2hs configure"
assertCmd "./setup build" "wash2hs build"
doesFileExist "dist/build/wash2hs"
>>= assertBool "wash2hs build didn't create executable!"
assertCmd "./setup install --user" "wash2hs install"
doesFileExist ",tmp/bin/wash2hs"
>>= assertBool "wash2hs didn't put executable into place."
setCurrentDirectory oldDir,
TestLabel "testing the HUnit package" $ TestCase $
do oldDir <- getCurrentDirectory
setCurrentDirectory "test/HUnit-1.0"
(pkgConf, pkgConfExists) <- GHC.localPackageConfig
......
......@@ -50,6 +50,7 @@ module Distribution.Package (
Executable(..),
emptyPackageDescription,
parsePackageDesc,
hasLibs,
#ifdef DEBUG
hunitTests,
test
......@@ -165,6 +166,14 @@ setOptions :: CompilerFlavor -> [String] -> BuildInfo -> BuildInfo
setOptions c xs desc@BuildInfo{options=opts}
= desc{options=(c,xs):opts}
-- |does this package have any libraries?
hasLibs :: PackageDescription -> Bool
hasLibs p = case library p of
Just l -> if null (cSources l) && null (modules l)
then False else True
Nothing -> False
-- ------------------------------------------------------------
-- * Parsing
-- ------------------------------------------------------------
......
......@@ -128,7 +128,8 @@ defaultMainNoRead pkg_descr
no_extra_flags extra_flags
localbuildinfo <- getPersistBuildConfig
install buildPref pkg_descr localbuildinfo install_prefixM
when (isNothing install_prefixM) (register pkg_descr localbuildinfo userInst)
when (isNothing install_prefixM && hasLibs pkg_descr)
(register pkg_descr localbuildinfo userInst)
Right (SDistCmd, extra_flags) -> do
no_extra_flags extra_flags
......@@ -138,7 +139,7 @@ defaultMainNoRead pkg_descr
Right (RegisterCmd userFlag, extra_flags) -> do
no_extra_flags extra_flags
localbuildinfo <- getPersistBuildConfig
register pkg_descr localbuildinfo userFlag
when (hasLibs pkg_descr) (register pkg_descr localbuildinfo userFlag)
Right (UnregisterCmd, extra_flags) -> do
no_extra_flags extra_flags
......
......@@ -50,8 +50,8 @@ module Distribution.Simple.Build (
import Distribution.Misc (Extension(..), extensionsToNHCFlag, extensionsToGHCFlag)
import Distribution.Setup (CompilerFlavor(..), compilerFlavor, compilerPath)
import Distribution.Package (PackageDescription(..), BuildInfo(..),
showPackageId, pkgName, Executable(..))
import Distribution.Simple.Configure (LocalBuildInfo(..), compiler)
showPackageId, pkgName, Executable(..), hasLibs)
import Distribution.Simple.Configure (LocalBuildInfo(..), compiler, exeDeps)
import Distribution.Simple.Utils (rawSystemExit, setupMessage,
die, rawSystemPathExit,
split, createIfNotExists,
......@@ -106,7 +106,8 @@ buildGHC pref pkg_descr lbi = do
unless pkgConfExists $ writeFile pkgConf "[]\n"
let args = ["-package-conf", pkgConf]
++ constructGHCCmdLine pref pkg_descr lbi
rawSystemExit (compilerPath (compiler lbi)) args
when (not (null (maybe [] modules (library pkg_descr)))) $
rawSystemExit (compilerPath (compiler lbi)) args
-- build any C sources
when (not (null (maybe [] cSources (library pkg_descr)))) $
......@@ -114,14 +115,22 @@ buildGHC pref pkg_descr lbi = do
-- build any executables
sequence_ [rawSystemExit (compilerPath (compiler lbi))
["--make", pathJoin [hsSourceDir bi, modPath], "-o", pathJoin [pref, exeName]]
| (Executable exeName modPath bi) <- executables pkg_descr]
-- now, build the library
let hObjs = map (++objsuffix) (map dotToSep (maybe [] modules (library pkg_descr)))
cObjs = [file ++ objsuffix | (file, _) <- (map splitExt (maybe [] cSources (library pkg_descr)))]
lib = mkLibName pref (showPackageId (package pkg_descr))
rawSystemPathExit "ar" (["q", lib] ++ [pathJoin [pref, x] | x <- hObjs ++ cObjs])
(["--make", pathJoin [hsSourceDir exeBi, modPath],
"-i" ++ (hsSourceDir exeBi), "-o", pathJoin [pref, exeName]]
++ (concat [ ["-package", pkgName pkg] | pkg <- exeDeps exeName lbi]))
| Executable exeName modPath exeBi <- executables pkg_descr]
when (hasLibs pkg_descr) (buildLibGhc (library pkg_descr) pkg_descr pref)
buildLibGhc (Just l) pkg_descr pref
= do let hObjs = map (++objsuffix) (map dotToSep (modules l))
cObjs = [file ++ objsuffix | (file, _)
<- (map splitExt (cSources l))]
lib = mkLibName pref (showPackageId (package pkg_descr))
unless (null hObjs && null cObjs)
(rawSystemPathExit "ar" (["q", lib] ++ [pathJoin [pref, x] | x <- hObjs ++ cObjs]))
buildLibGhc _ _ _ = return ()
constructGHCCmdLine :: FilePath -> PackageDescription -> LocalBuildInfo -> [String]
constructGHCCmdLine pref pkg_descr lbi =
......
......@@ -47,20 +47,22 @@ module Distribution.Simple.Configure (writePersistBuildConfig,
LocalBuildInfo(..),
configure,
hunitTests,
localBuildInfoFile
localBuildInfoFile,
exeDeps
)
where
import Distribution.Misc(Dependency(..))
import Distribution.Setup(ConfigFlags,CompilerFlavor(..), Compiler(..))
import Distribution.Package(PackageDescription(..), emptyPackageDescription,
PackageIdentifier(..), BuildInfo(..)
PackageIdentifier(..), BuildInfo(..), Executable(..)
)
import Distribution.Simple.Utils (die, setupMessage,
findBinary, splitFilenameDir)
import Distribution.Package ( PackageIdentifier )
import Distribution.Version (Version(..), VersionRange(..))
import Data.Maybe(fromJust)
import System.IO hiding (catch)
import System.Directory
import Control.Monad ( when )
......@@ -78,15 +80,20 @@ data LocalBuildInfo = LocalBuildInfo {
-- @C:/Program Files/foo-1.2@ on Windows.
compiler :: Compiler,
-- ^ The compiler we're building with
packageDeps :: [PackageIdentifier]
packageDeps :: [PackageIdentifier],
-- ^ Which packages we depend on, *exactly*, The
-- 'PackageDescription' specifies a set of build dependencies
-- that must be satisfied in terms of version ranges. This
-- field fixes those dependencies to the specific versions
-- available on this machine for this compiler.
executableDeps :: [(String,[PackageIdentifier])]
}
deriving (Show, Read, Eq)
-- |Throws an error if it's not found.
exeDeps :: String -> LocalBuildInfo -> [PackageIdentifier]
exeDeps s d = fromJust $ lookup s (executableDeps d)
emptyLocalBuildInfo :: LocalBuildInfo
emptyLocalBuildInfo = undefined
......@@ -125,7 +132,10 @@ configure pkg_descr (maybe_hc_flavor, maybe_hc_path, maybe_prefix)
message $ "Using compiler: " ++ p'
message $ "Using package tool: " ++ pkg
return LocalBuildInfo{prefix=prefix, compiler=compiler,
packageDeps=map buildDepToDep (maybe [] buildDepends lib)}
packageDeps=map buildDepToDep (maybe [] buildDepends lib),
executableDeps = [(n, map buildDepToDep (buildDepends exeBi))
| Executable n _ exeBi <- executables pkg_descr]
}
-- |Converts build dependencies to real dependencies. FIX: doesn't
-- set any version information.
......@@ -230,7 +240,7 @@ hunitTests
assertEqual "finding ghc, etc on simonMar's machine failed"
(LocalBuildInfo "/usr" (Compiler GHC
simonMarGHCLoc
(simonMarGHCLoc ++ "-pkg")) [])
(simonMarGHCLoc ++ "-pkg")) [] [])
simonMarGHC
]
#endif
......@@ -50,14 +50,16 @@ module Distribution.Simple.Install (
#endif
) where
import Distribution.Package (PackageDescription(..), BuildInfo(..), showPackageId)
import Distribution.Package (PackageDescription(..), BuildInfo(..), Executable(..),
showPackageId, hasLibs)
import Distribution.Simple.Configure(LocalBuildInfo(..))
import Distribution.Simple.Utils(setupMessage, moveSources,
mkLibName, pathJoin,
copyFile, die
copyFile, die, createIfNotExists
)
import Distribution.Setup (CompilerFlavor(..), Compiler(..))
import Control.Monad(when)
import System.Cmd(system)
#ifdef DEBUG
......@@ -70,24 +72,36 @@ install :: FilePath -- ^build location
-> Maybe FilePath -- ^install-prefix
-> IO ()
install buildPref pkg_descr lbi install_prefixM = do
let pref = pathJoin [(maybe (prefix lbi) id install_prefixM), "lib",
(showPackageId $ package pkg_descr)]
setupMessage ("Installing: " ++ pref) pkg_descr
let libPref = pathJoin [(maybe (prefix lbi) id install_prefixM), "lib",
(showPackageId $ package pkg_descr)]
let binPref = pathJoin [(maybe (prefix lbi) id install_prefixM), "bin"]
setupMessage ("Installing: " ++ libPref ++ "&" ++ binPref) pkg_descr
case compilerFlavor (compiler lbi) of
GHC -> installGHC pref buildPref pkg_descr
Hugs -> installHugs pref buildPref pkg_descr
GHC -> do when (hasLibs pkg_descr) (installLibGHC libPref buildPref pkg_descr)
installExeGhc binPref buildPref pkg_descr
Hugs -> installHugs libPref buildPref pkg_descr
_ -> die ("only installing with GHC or Hugs is implemented")
return ()
-- register step should be performed by caller.
-- |Install executables for GHC. FIX: doesn't make it executable!
installExeGhc :: FilePath -- ^install location
-> FilePath -- ^Build location
-> PackageDescription -> IO ()
installExeGhc pref buildPref pkg_descr
= do createIfNotExists True pref
sequence_ [copyFile (pathJoin [buildPref, e]) (pathJoin [pref, e])
| Executable e _ _ <- executables pkg_descr]
-- |Install for ghc, .hi and .a
installGHC :: FilePath -- ^install location
-> FilePath -- ^Build location
-> PackageDescription -> IO ()
installGHC pref buildPref pkg_descr
= do moveSources buildPref pref (maybe [] modules (library pkg_descr)) ["hi"]
copyFile (mkLibName buildPref (showPackageId (package pkg_descr)))
(mkLibName pref (showPackageId (package pkg_descr)))
installLibGHC :: FilePath -- ^install location
-> FilePath -- ^Build location
-> PackageDescription -> IO ()
installLibGHC pref buildPref pkg_descr@PackageDescription{library=Just l,
package=p}
= do moveSources buildPref pref (modules l) ["hi"]
copyFile (mkLibName buildPref (showPackageId p))
(mkLibName pref (showPackageId p))
-- |Install for hugs, .lhs and .hs
installHugs :: FilePath -- ^Install location
......
* 0.1
** if library is Nothing, then don't build the library. sanity check
for both library and executables == nothing.
HIGH:
** grep for "FIX"
** make installed binaries executable! (posix?)
** under what conditions does library == Nothing?
** make sure tests will work on other machines. why doesn't make work
in test/A on lex?
** fix test cases so a single failure doesn't cascade
** sanity check for both library and executables == nothing.
- also, if they have Nothing, and yet BuildInfo is non-empty, this
should probably be a warning.
*** add test case for no libraries
** Extensions
- complain if their use makes the code non-portable?
- constructorless data-types
- integrate suggestions from libraries@
** grep for "FIX"
** does clean remove installed-pkg-config and .setup-config or
whatever?
** should .installed-pkg-config be removed after successful register?
** Clean up field parsers (Martin: what else goes here?)
*** license parser parses either known strings, or a filename.
LOW
** clean
- does clean remove installed-pkg-config and .setup-config or whatever?
- should .installed-pkg-config be removed after successful register?
** add "clean" to doc?
** add description file format to doc.
** Change name of Setup.description?
** the ./setup -h output should document which commands exist, and
which options are relevant to which commands.
** refactor createGhcCommandLine?
* 1.0
** HC-PKG (see "Depends on HC-PKG" below)
......
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