summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lynagh <igloo@earth.li>2009-04-29 18:19:09 +0000
committerIan Lynagh <igloo@earth.li>2009-04-29 18:19:09 +0000
commit71dcc642edcfc3bfeef2619d66183cc08ae90a43 (patch)
tree45be2dcb65cb5e9d9673a355308c21553872d79a
parentd611f0b5e71134cdbc8749aa3c02476d0db5283a (diff)
downloadhaskell-71dcc642edcfc3bfeef2619d66183cc08ae90a43.tar.gz
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.
-rw-r--r--utils/ghc-cabal/ghc-cabal.hs84
1 files changed, 82 insertions, 2 deletions
diff --git a/utils/ghc-cabal/ghc-cabal.hs b/utils/ghc-cabal/ghc-cabal.hs
index c806d3cf16..c19217e5e0 100644
--- a/utils/ghc-cabal/ghc-cabal.hs
+++ b/utils/ghc-cabal/ghc-cabal.hs
@@ -1,6 +1,7 @@
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;"
+ , "}"
+ ]
+