diff --git a/Gtk2HsSetup.hs b/Gtk2HsSetup.hs index 371090a..8c60eec 100644 --- a/Gtk2HsSetup.hs +++ b/Gtk2HsSetup.hs @@ -8,5 +8,5 @@ -- -module Gtk2HsSetup ( - gtk2hsUserHooks, - getPkgConfigPackages, +module Gtk2HsSetup ( + gtk2hsUserHooks, + getPkgConfigPackages, checkGtk2hsBuildtools, @@ -57,4 +57,5 @@ import Distribution.Verbosity import Control.Monad (when, unless, filterM, liftM, forM, forM_) -import Data.Maybe ( isJust, isNothing, fromMaybe, maybeToList ) -import Data.List (isPrefixOf, isSuffixOf, stripPrefix, nub) +import Data.Maybe ( isJust, isNothing, fromMaybe, maybeToList, catMaybes ) +import Data.List (isPrefixOf, isSuffixOf, nub, minimumBy, stripPrefix, tails ) +import Data.Ord as Ord (comparing) import Data.Char (isAlpha, isNumber) @@ -115,5 +116,12 @@ fixLibs dlls = concatMap $ \ lib -> case filter (isLib lib) dlls of - dll:_ -> [dropExtension dll] - _ -> if lib == "z" then [] else [lib] + dlls@(_:_) -> [dropExtension (pickDll dlls)] + _ -> if lib == "z" then [] else [lib] where + -- If there are several .dll files matching the one we're after then we + -- just have to guess. For example for recent Windows cairo builds we get + -- libcairo-2.dll libcairo-gobject-2.dll libcairo-script-interpreter-2.dll + -- Our heuristic is to pick the one with the shortest name. + -- Yes this is a hack but the proper solution is hard: we would need to + -- parse the .a file and see which .dll file(s) it needed to link to. + pickDll = minimumBy (Ord.comparing length) isLib lib dll = @@ -123,3 +131,3 @@ fixLibs dlls = concatMap $ \ lib -> _ -> False - + -- The following code is a big copy-and-paste job from the sources of @@ -156,8 +164,12 @@ register :: PackageDescription -> LocalBuildInfo -> IO () -register pkg@(library -> Just lib ) - lbi@(libraryConfig -> Just clbi) regFlags +register pkg@PackageDescription { library = Just lib } lbi regFlags = do + let clbi = LBI.getComponentLocalBuildInfo lbi LBI.CLibName installedPkgInfoRaw <- generateRegistrationInfo +#if CABAL_VERSION_CHECK(1,22,0) + verbosity pkg lib lbi clbi inplace False distPref packageDb +#else verbosity pkg lib lbi clbi inplace distPref +#endif @@ -170,3 +182,3 @@ register pkg@(library -> Just lib ) case () of - _ | modeGenerateRegFile -> die "Generate Reg File not supported" + _ | modeGenerateRegFile -> writeRegistrationFile installedPkgInfo | modeGenerateRegScript -> die "Generate Reg Script not supported" @@ -182,2 +194,4 @@ register pkg@(library -> Just lib ) modeGenerateRegFile = isJust (flagToMaybe (regGenPkgConf regFlags)) + regFile = fromMaybe (display (packageId pkg) <.> "conf") + (fromFlag (regGenPkgConf regFlags)) modeGenerateRegScript = fromFlag (regGenScript regFlags) @@ -190,2 +204,6 @@ register pkg@(library -> Just lib ) + writeRegistrationFile installedPkgInfo = do + notice verbosity ("Creating package registration file: " ++ regFile) + writeUTF8File regFile (showInstalledPackageInfo installedPkgInfo) + register _ _ regFlags = notice verbosity "No package to register" @@ -249,3 +267,3 @@ getCppOptions bi lbi ++ [opt | opt@('-':c:_) <- PD.cppOptions bi ++ PD.ccOptions bi, c `elem` "DIU"] - ++ ["-D__GLASGOW_HASKELL__="++show (ghcDefine . versionBranch . compilerVersion $ LBI.compiler lbi)] + ++ ["-D__GLASGOW_HASKELL__="++show (ghcDefine . ghcVersion . compilerId $ LBI.compiler lbi)] where @@ -254,2 +272,15 @@ getCppOptions bi lbi + ghcVersion :: CompilerId -> [Int] +-- This version is nicer, but we need to know the Cabal version that includes the new CompilerId +-- #if CABAL_VERSION_CHECK(1,19,2) +-- ghcVersion (CompilerId GHC v _) = versionBranch v +-- ghcVersion (CompilerId _ _ (Just c)) = ghcVersion c +-- #else +-- ghcVersion (CompilerId GHC v) = versionBranch v +-- #endif +-- ghcVersion _ = [] +-- This version should work fine for now + ghcVersion = concat . take 1 . map (read . (++"]") . takeWhile (/=']')) . catMaybes + . map (stripPrefix "CompilerId GHC (Version {versionBranch = ") . tails . show + installCHI :: PackageDescription -- ^information from the .cabal file @@ -264,3 +295,3 @@ installCHI pkg@PD.PackageDescription { library = Just lib } lbi verbosity copyde (PD.libModules lib) - + let files = [ f | Just f <- mFiles ] @@ -268,3 +299,3 @@ installCHI pkg@PD.PackageDescription { library = Just lib } lbi verbosity copyde - + installCHI _ _ _ _ = return () @@ -294,3 +325,2 @@ genSynthezisedFiles :: Verbosity -> PackageDescription -> LocalBuildInfo -> IO ( genSynthezisedFiles verb pd lbi = do - cPkgs <- getPkgConfigPackages verb lbi pd @@ -300,3 +330,3 @@ genSynthezisedFiles verb pd lbi = do typeOpts :: String -> [ProgArg] - typeOpts tag = concat [ map (\val -> '-':'-':drop (length tag) field++'=':val) (words content) + typeOpts tag = concat [ map (\val -> '-':'-':drop (length tag) field ++ '=':val) (words content) | (field,content) <- xList, @@ -308,4 +338,5 @@ genSynthezisedFiles verb pd lbi = do , tag <- name' - : [ name' ++ "-" ++ show major ++ "." ++ show digit - | digit <- [0,2..minor] ] + :[ name' ++ "-" ++ show maj ++ "." ++ show d2 + | (maj, d2) <- [(maj, d2) | maj <- [0..(major-1)], d2 <- [0,2..20]] + ++ [(major, d2) | d2 <- [0,2..minor]] ] ] @@ -400,11 +431,6 @@ fixDeps pd@PD.PackageDescription { modDeps <- mapM extractDeps modDeps - let (expMods, othMods) = span mdExposed $ sortTopological modDeps - badOther = map (fromMaybe "" . mdLocation) $ - filter (not . mdExposed) expMods - unless (null badOther) $ - die ("internal chs modules "++intercalate "," badOther++ - " depend on exposed chs modules; cabal needs to build internal modules first") + let (othMods, expMods) = span (not . mdExposed) $ reverse $ sortTopological modDeps return pd { PD.library = Just lib { - PD.exposedModules = map mdOriginal expMods, - PD.libBuildInfo = bi { PD.otherModules = map mdOriginal othMods } + PD.exposedModules = map mdOriginal (reverse expMods), + PD.libBuildInfo = bi { PD.otherModules = map mdOriginal (reverse othMods) } }} @@ -428,3 +454,3 @@ instance Ord ModDep where -- ignores CPP conditionals. We just require everything which means that the --- existance of a .chs module may not depend on some CPP condition. +-- existance of a .chs module may not depend on some CPP condition. extractDeps :: ModDep -> IO ModDep @@ -435,3 +461,3 @@ extractDeps md@ModDep { mdLocation = Just f } = withUTF8FileContents f $ \con -> case simpleParse (takeWhile ('#' /=) ys) of - Just m -> findImports (m:acc) xxs + Just m -> findImports (m:acc) xxs Nothing -> die ("cannot parse chs import in "++f++":\n"++ @@ -469,3 +495,3 @@ checkGtk2hsBuildtools programs = do let printError name = do - putStrLn $ "Cannot find " ++ name ++ "\n" + putStrLn $ "Cannot find " ++ name ++ "\n" ++ "Please install `gtk2hs-buildtools` first and check that the install directory is in your PATH (e.g. HOME/.cabal/bin)." @@ -473,2 +499,2 @@ checkGtk2hsBuildtools programs = do forM_ programInfos $ \ (name, location) -> - when (isNothing location) (printError name) + when (isNothing location) (printError name) diff --git a/SetupMain.hs b/SetupMain.hs index 201ee8f..2d1a782 100644 --- a/SetupMain.hs +++ b/SetupMain.hs @@ -12,2 +12,2 @@ main = do defaultMainWithHooks gtk2hsUserHooks - + diff --git a/SetupWrapper.hs b/SetupWrapper.hs index aa825ec..44a20f8 100644 --- a/SetupWrapper.hs +++ b/SetupWrapper.hs @@ -11,3 +11,3 @@ import Distribution.Simple.Compiler import Distribution.Simple.BuildPaths (exeExtension) -import Distribution.Simple.Configure (configCompiler) +import Distribution.Simple.Configure (configCompilerEx) import Distribution.Simple.GHC (getInstalledPackages) @@ -20,3 +20,3 @@ import System.Environment import System.Process -import System.Exit +import System.Exit (ExitCode(..), exitWith) import System.FilePath @@ -117,3 +117,3 @@ setupWrapper setupHsFile = do - (comp, conf) <- configCompiler (Just GHC) Nothing Nothing + (comp, _, conf) <- configCompilerEx (Just GHC) Nothing Nothing defaultProgramConfiguration verbosity