Commit 71dcc642 authored by Ian Lynagh's avatar Ian Lynagh

Add special support for haskeline

The library uses stuff in Setup.hs to determine whether or not it needs
to use -liconv. This patch replicates that logic in ghc-cabal. This
isn't pretty, and we should find a better way to do it, but it works
for now.
parent d611f0b5
module Main (main) where
import Distribution.Compat.Exception
import qualified Distribution.ModuleName as ModuleName
import Distribution.PackageDescription
import Distribution.PackageDescription.Configuration
......@@ -9,9 +10,10 @@ import Distribution.Simple
import Distribution.Simple.Configure
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Program
import Distribution.Simple.Utils (defaultPackageDesc)
import Distribution.Simple.Utils (defaultPackageDesc, withTempFile)
import Distribution.Simple.Build (writeAutogenFiles)
import Distribution.Simple.Register (writeInstalledConfig)
import Distribution.Simple.PackageIndex
import Distribution.Text
import Distribution.Verbosity
import qualified Distribution.InstalledPackageInfo as Installed
......@@ -19,6 +21,7 @@ import qualified Distribution.InstalledPackageInfo as Installed
import qualified Distribution.Simple.PackageIndex as PackageIndex
( topologicalOrder, lookupPackageName, insert )
import Control.Exception
import Control.Monad
import Data.Maybe
import System.IO
......@@ -148,7 +151,7 @@ doInstall ghcpkg ghcpkgconf directory distDir myDestDir myPrefix myLibdir myDocd
generate :: [String] -> FilePath -> FilePath -> IO ()
generate config_args distdir directory
= withCurrentDirectory directory
$ do let verbosity = verbose
$ do let verbosity = normal
gpdFile <- defaultPackageDesc verbosity
gpd <- readPackageDescription verbosity gpdFile
......@@ -164,6 +167,17 @@ generate config_args distdir directory
lbi <- getPersistBuildConfig distdir
let pd0 = localPkgDescr lbi
-- Sigh, haskeline proper uses stuff in Setup.hs to handle whether
-- or not -liconv is used. We don't use Setup.hs, so we replicate
-- what it does here. We should do this better somehow.
when (display (pkgName (package pd0)) == "haskeline") $
case library pd0 of
Nothing -> fail "Can't happen: No haskeline library"
Just lib -> do
d <- getCurrentDirectory
print d
maybeSetLibiconv verbosity (libBuildInfo lib) lbi
hooked_bi <-
if (buildType pd0 == Just Configure)
then do
......@@ -244,3 +258,69 @@ generate config_args distdir directory
writeFile (distdir ++ "/package-data.mk") $ unlines xs
where
escape = foldr (\c xs -> if c == '#' then '\\':'#':xs else c:xs) []
----------------------------------------------------------------------
-- haskeline-specific hacks
-- Sigh, haskeline proper uses stuff in Setup.hs to handle whether
-- or not -liconv is used. We don't use Setup.hs, so we replicate
-- what it does here. We should do this better somehow.
-- Test whether compiling a c program that links against libiconv needs -liconv.
maybeSetLibiconv :: Verbosity -> BuildInfo -> LocalBuildInfo -> IO ()
maybeSetLibiconv verb bi lbi = do
let biWithIconv = addIconv bi
worksWithout <- tryCompile iconv_prog bi lbi verb
if worksWithout
then writeBuildInfo ""
else do
worksWith <- tryCompile iconv_prog biWithIconv lbi verb
if worksWith
then do
writeBuildInfo "iconv"
else fail "Unable to link against the iconv library."
where
-- Cabal (at least 1.6.0.1) won't parse an empty buildinfo file.
writeBuildInfo libs = writeFile "haskeline.buildinfo"
$ unlines ["extra-libraries: " ++ libs]
tryCompile :: String -> BuildInfo -> LocalBuildInfo -> Verbosity -> IO Bool
tryCompile program bi lbi verb = flip catchIO processException $ flip catchExit processExit $ do
tempDir <- getTemporaryDirectory
withTempFile tempDir ".c" $ \fname h -> do
hPutStr h program
hClose h
-- TODO take verbosity from the args.
rawSystemProgramStdoutConf verb gccProgram (withPrograms lbi) (fname : args)
return True
where
processException :: IOException -> IO Bool
processException _ = return False
processExit = return . (==ExitSuccess)
-- Mimicing Distribution.Simple.Configure
deps = topologicalOrder (installedPkgs lbi)
args = concat
[ ccOptions bi
, cppOptions bi
, ldOptions bi
-- --extra-include-dirs and --extra-lib-dirs are included
-- in the below fields.
-- Also sometimes a dependency like rts points to a nonstandard
-- include/lib directory where iconv can be found.
, map ("-I" ++) (includeDirs bi ++ concatMap Installed.includeDirs deps)
, map ("-L" ++) (extraLibDirs bi ++ concatMap Installed.libraryDirs deps)
, map ("-l" ++) (extraLibs bi)
]
addIconv :: BuildInfo -> BuildInfo
addIconv bi = bi {extraLibs = "iconv" : extraLibs bi}
iconv_prog :: String
iconv_prog = unlines $
[ "#include <iconv.h>"
, "int main(void) {"
, " iconv_t t = iconv_open(\"UTF-8\", \"UTF-8\");"
, " return 0;"
, "}"
]
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