Commit 64acd525 authored by Duncan Coutts's avatar Duncan Coutts
Browse files

Add support for building libs and exes with nhc98 via hmake

Doesn't do installation yet or check for existence of dependent packages.
parent 28c99725
......@@ -45,20 +45,30 @@ module Distribution.Simple.NHC
{-, install -}
) where
import Distribution.Package
( PackageIdentifier(..) )
import Distribution.PackageDescription
( PackageDescription(..), BuildInfo(..),
Library(..), libModules, hcOptions)
( PackageDescription(..), BuildInfo(..), Library(..), Executable(..),
withLib, withExe, hcOptions )
import Distribution.Simple.LocalBuildInfo
( LocalBuildInfo(..) )
import Distribution.Simple.Compiler ( Compiler(..), CompilerFlavor(..), Flag,
extensionsToFlags )
import Language.Haskell.Extension (Extension(..))
import Distribution.Simple.Program ( ProgramConfiguration, userMaybeSpecifyPath,
requireProgram, hmakeProgram,
rawSystemProgramConf )
import Distribution.Version ( VersionRange(AnyVersion) )
( LocalBuildInfo(..) )
import Distribution.Simple.Compiler
( Compiler(..), CompilerFlavor(..), Flag, extensionsToFlags )
import Language.Haskell.Extension
( Extension(..) )
import Distribution.Simple.Program
( ProgramConfiguration, userMaybeSpecifyPath, requireProgram,
lookupProgram, ConfiguredProgram(programVersion), programPath,
nhcProgram, hmakeProgram, rawSystemProgramConf )
import Distribution.Simple.Utils
( die, createDirectoryIfMissingVerbose, moduleToFilePath )
import Distribution.Version
( Version(..), orLaterVersion )
import Distribution.Verbosity
import System.FilePath
( (</>), normalise, takeDirectory, dropExtension )
import Data.List ( nub )
import Control.Monad ( when )
-- -----------------------------------------------------------------------------
-- Configuring
......@@ -67,15 +77,20 @@ configure :: Verbosity -> Maybe FilePath -> Maybe FilePath
-> ProgramConfiguration -> IO (Compiler, ProgramConfiguration)
configure verbosity hcPath _hcPkgPath conf = do
(_hmakeProg, conf') <- requireProgram verbosity hmakeProgram AnyVersion
(userMaybeSpecifyPath "hmake" hcPath conf)
(nhcProg, conf') <- requireProgram verbosity nhcProgram
(orLaterVersion (Version [1,20] []))
(userMaybeSpecifyPath "nhc98" hcPath conf)
let Just nhcVersion = programVersion nhcProg
(_hmakeProg, conf'') <- requireProgram verbosity hmakeProgram
(orLaterVersion (Version [3,13] [])) conf'
let comp = Compiler {
compilerFlavor = NHC,
compilerId = error "TODO: nhc98 compilerId", --PackageIdentifier "nhc98" version
compilerId = PackageIdentifier "nhc98" nhcVersion,
compilerExtensions = nhcLanguageExtensions
}
return (comp, conf')
return (comp, conf'')
-- | The flags for the supported extensions
nhcLanguageExtensions :: [(Extension, Flag)]
......@@ -95,15 +110,63 @@ nhcLanguageExtensions =
-- |FIX: For now, the target must contain a main module. Not used
-- ATM. Re-add later.
build :: PackageDescription -> LocalBuildInfo -> Verbosity -> IO ()
build pkg_descr lbi verbosity =
-- Unsupported extensions have already been checked by configure
let flags = ( extensionsToFlags (compiler lbi)
. maybe [] (extensions . libBuildInfo)
. library ) pkg_descr in
rawSystemProgramConf verbosity hmakeProgram (withPrograms lbi)
(["-hc=nhc98"]
++ flags
++ maybe [] (hcOptions NHC . options . libBuildInfo)
(library pkg_descr)
++ libModules pkg_descr)
build pkg_descr lbi verbosity = do
let conf = withPrograms lbi
Just nhcProg = lookupProgram nhcProgram conf
withLib pkg_descr () $ \lib -> do
let bi = libBuildInfo lib
modules = exposedModules lib ++ otherModules bi
-- Unsupported extensions have already been checked by configure
extensionFlags = extensionsToFlags (compiler lbi) (extensions bi)
inFiles <- getModulePaths lbi bi modules
let srcDirs = nub (map takeDirectory inFiles)
destDirs = map (buildDir lbi </>) srcDirs
print destDirs
mapM_ (createDirectoryIfMissingVerbose verbosity True) destDirs
rawSystemProgramConf verbosity hmakeProgram conf $
["-hc=" ++ programPath nhcProg]
++ nhcVerbosityOptions verbosity
++ ["-d", buildDir lbi]
++ extensionFlags
++ maybe [] (hcOptions NHC . options . libBuildInfo)
(library pkg_descr)
++ concat [ ["-package", pkgName pkg] | pkg <- packageDeps lbi ]
++ inFiles
withExe pkg_descr $ \exe -> do
when (dropExtension (modulePath exe) /= exeName exe) $
die $ "hmake does not support exe names that do not match the name of\n"
++ "the 'main-is' file. You will have to rename your executable to "
++ show (dropExtension (modulePath exe))
let bi = buildInfo exe
modules = otherModules bi
-- Unsupported extensions have already been checked by configure
extensionFlags = extensionsToFlags (compiler lbi) (extensions bi)
inFiles <- getModulePaths lbi bi modules
let targetDir = buildDir lbi </> exeName exe
exeDir = targetDir </> (exeName exe ++ "-tmp")
srcDirs = nub (map takeDirectory (modulePath exe : inFiles))
destDirs = map (exeDir </>) srcDirs
mapM_ (createDirectoryIfMissingVerbose verbosity True) destDirs
rawSystemProgramConf verbosity hmakeProgram conf $
["-hc=" ++ programPath nhcProg]
++ nhcVerbosityOptions verbosity
++ ["-d", targetDir]
++ extensionFlags
++ maybe [] (hcOptions NHC . options . libBuildInfo)
(library pkg_descr)
++ concat [ ["-package", pkgName pkg] | pkg <- packageDeps lbi ]
++ inFiles
++ [exeName exe]
nhcVerbosityOptions :: Verbosity -> [String]
nhcVerbosityOptions verbosity
| verbosity >= deafening = ["-v"]
| verbosity >= normal = []
| otherwise = ["-q"]
--TODO: where to put this? it's duplicated in .Simple too
getModulePaths :: LocalBuildInfo -> BuildInfo -> [String] -> IO [FilePath]
getModulePaths lbi bi =
fmap (map normalise . concat) .
mapM (flip (moduleToFilePath (buildDir lbi : hsSourceDirs bi)) ["hs", "lhs"])
......@@ -492,7 +492,15 @@ ghcPkgProgram = (simpleProgram "ghc-pkg") {
}
nhcProgram :: Program
nhcProgram = simpleProgram "nhc98"
nhcProgram = (simpleProgram "nhc98") {
programFindVersion = findProgramVersion "--version" $ \str ->
-- Invoking "nhc98 --version" gives a string like
-- /usr/local/bin/nhc98: v1.20 (2007-11-22)
-- [ config: ix86-Linux/ghc by user@host on Fri Nov 23 14:11:17 GMT 2007 ]
case words str of
(_:('v':ver):_) -> ver
_ -> ""
}
hmakeProgram :: Program
hmakeProgram = (simpleProgram "hmake") {
......
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