diff --git a/Cabal.cabal b/Cabal.cabal index 686f946c52fed5dbc690cf00d97f9ae4809e59ee..9eea8a56bf8bd7ce9173e196d621a5b05e303996 100644 --- a/Cabal.cabal +++ b/Cabal.cabal @@ -70,6 +70,7 @@ Library { Distribution.Simple.SetupWrapper, Distribution.Simple.SrcDist, Distribution.Simple.Utils, + Distribution.System, Distribution.Verbosity, Distribution.Version, Distribution.Compat.ReadP, diff --git a/Distribution/Program.hs b/Distribution/Program.hs index 6b3afe15c06d9eb2993c706e41846bcc9d39eade..8fcd11625191ee91c26113bc25305b0f349c2669 100644 --- a/Distribution/Program.hs +++ b/Distribution/Program.hs @@ -71,6 +71,7 @@ module Distribution.Program( import qualified Distribution.Compat.Map as Map import Distribution.Compat.Directory (findExecutable) import Distribution.Simple.Utils (die, rawSystemExit, rawSystemStdout) +import Distribution.System import Distribution.Version (Version, readVersion) import Distribution.Verbosity import System.Directory (doesFileExist) @@ -261,11 +262,11 @@ greencardProgram :: Program greencardProgram = simpleProgram "greencard" ldProgram :: Program -#if defined(mingw32_TARGET_OS) || defined(mingw32_HOST_OS) -ldProgram = Program "ld" "ld" [] (FoundOnSystem "<what-your-hs-compiler-shipped-with>") -#else -ldProgram = simpleProgram "ld" -#endif +ldProgram = case os of + Windows MingW -> + Program "ld" "ld" Nothing [] + (FoundOnSystem "<what-your-hs-compiler-shipped-with>") + _ -> simpleProgram "ld" tarProgram :: Program tarProgram = simpleProgram "tar" diff --git a/Distribution/Simple/Build.hs b/Distribution/Simple/Build.hs index 0607bbcaf0a40124d247e10568b83b88560c2646..ce3761932f51c8f92d9a1a9ed10d7fd1e46bebe7 100644 --- a/Distribution/Simple/Build.hs +++ b/Distribution/Simple/Build.hs @@ -65,6 +65,7 @@ import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Configure ( localBuildInfoFile ) import Distribution.Simple.Utils( createDirectoryIfMissingVerbose, die ) +import Distribution.System import System.FilePath ( (</>), pathSeparator ) @@ -242,11 +243,14 @@ buildPathsModule pkg_descr lbi = mkGetDir _ (Just dirrel) = "getPrefixDirRel " ++ show dirrel mkGetDir dir Nothing = "return " ++ show dir -#if mingw32_HOST_OS - absolute = hasLibs pkg_descr || flat_bindirrel == Nothing -#else - absolute = hasLibs pkg_descr || flat_progdirrel == Nothing || not isHugs -#endif + absolute = case os of + Windows MingW -> + hasLibs pkg_descr || + flat_bindirrel == Nothing + _ -> + hasLibs pkg_descr || + flat_progdirrel == Nothing || + not isHugs paths_modulename = autogenModuleName pkg_descr paths_filename = paths_modulename ++ ".hs" @@ -319,18 +323,14 @@ filename_stuff = " _ -> path1\n"++ "\n"++ "pathSeparator :: Char\n"++ -#if mingw32_HOST_OS - "pathSeparator = '\\\\'\n"++ -#else - "pathSeparator = '/'\n"++ -#endif + (case os of + Windows _ -> "pathSeparator = '\\\\'\n" + _ -> "pathSeparator = '/'\n") ++ "\n"++ "isPathSeparator :: Char -> Bool\n"++ -#if mingw32_HOST_OS - "isPathSeparator c = c == '/' || c == '\\\\'\n" -#else - "isPathSeparator c = c == '/'\n" -#endif + (case os of + Windows _ -> "isPathSeparator c = c == '/' || c == '\\\\'\n" + _ -> "isPathSeparator c = c == '/'\n") -- ------------------------------------------------------------ -- * Testing diff --git a/Distribution/Simple/Configure.hs b/Distribution/Simple/Configure.hs index fca822df9fe4d14ab7dfa3c4605ebcfba790e801..8460ed844a26d9ff59d465e44c3e755c18b63d04 100644 --- a/Distribution/Simple/Configure.hs +++ b/Distribution/Simple/Configure.hs @@ -67,6 +67,7 @@ module Distribution.Simple.Configure (configure, import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Register (removeInstalledConfig) import Distribution.Setup(ConfigFlags(..), CopyDest(..)) +import Distribution.System import Distribution.Compiler(CompilerFlavor(..), Compiler(..), compilerVersion, compilerPath, compilerPkgToolPath, extensionsToFlags) @@ -78,7 +79,7 @@ import Distribution.PackageDescription( finalizePackageDescription, HookedBuildInfo, sanityCheckPackage, updatePackageDescription, BuildInfo(..), Executable(..), setupMessage, - satisfyDependency) + satisfyDependency, hasLibs) import Distribution.Simple.Utils (die, warn, rawSystemStdout) import Distribution.Version (Version(..), Dependency(..), VersionRange(ThisVersion), showVersion, showVersionRange) @@ -113,10 +114,6 @@ import Distribution.Compat.ReadP import Distribution.Compat.Directory (createDirectoryIfMissing) import Prelude hiding (catch) -#ifdef mingw32_HOST_OS -import Distribution.PackageDescription (hasLibs) -#endif - #ifdef DEBUG import Test.HUnit #endif @@ -316,23 +313,15 @@ messageDir :: PackageDescription -> LocalBuildInfo -> String -> (PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath) -> (PackageDescription -> LocalBuildInfo -> CopyDest -> Maybe FilePath) -> IO () -messageDir pkg_descr lbi name mkDir -#if mingw32_HOST_OS - mkDirRel -#else - _ -#endif +messageDir pkg_descr lbi name mkDir mkDirRel = message (name ++ " installed in: " ++ mkDir pkg_descr lbi NoCopyDest ++ rel_note) where -#if mingw32_HOST_OS - rel_note - | not (hasLibs pkg_descr) && - mkDirRel pkg_descr lbi NoCopyDest == Nothing - = " (fixed location)" - | otherwise = "" -#else - rel_note = "" -#endif + rel_note = case os of + Windows MingW + | not (hasLibs pkg_descr) && + mkDirRel pkg_descr lbi NoCopyDest == Nothing + -> " (fixed location)" + _ -> "" -- |Converts build dependencies to a versioned dependency. only sets -- version information for exact versioned dependencies. diff --git a/Distribution/Simple/GHC.hs b/Distribution/Simple/GHC.hs index 8f285477566c15b745443a48130dd80242515e3b..5cb5cf9424e9c1f8ca44d067a8d667dc05ebefbe 100644 --- a/Distribution/Simple/GHC.hs +++ b/Distribution/Simple/GHC.hs @@ -76,6 +76,7 @@ import Distribution.Version ( Version(..) ) import qualified Distribution.Simple.GHCPackageConfig as GHC ( localPackageConfig, canReadLocalPackageConfig ) +import Distribution.System import Distribution.Verbosity import Language.Haskell.Extension (Extension(..)) @@ -271,14 +272,11 @@ build pkg_descr lbi verbosity = do runAr = rawSystemProgramConf verbosity "ar" (withPrograms lbi) -#if defined(mingw32_TARGET_OS) || defined(mingw32_HOST_OS) - rawSystemLd = rawSystemExit - maxCommandLineSize = 30 * 1024 -#else - rawSystemLd = rawSystemPathExit + rawSystemLd = case os of + Windows MingW -> rawSystemExit + _ -> rawSystemPathExit --TODO: discover this at configure time on unix maxCommandLineSize = 30 * 1024 -#endif ifVanillaLib False $ xargs maxCommandLineSize runAr arArgs arObjArgs @@ -430,22 +428,18 @@ mkGHCiLibName pref lib = pref </> ("HS" ++ lib) <.> ".o" findLdProgram :: LocalBuildInfo -> IO FilePath -#if defined(mingw32_TARGET_OS) || defined(mingw32_HOST_OS) -findLdProgram lbi = - let - compilerDir = takeDirectory $ compilerPath (compiler lbi) - baseDir = takeDirectory compilerDir - binInstallLd = baseDir </> "gcc-lib" </> "ld.exe" - in do - mb <- lookupProgram "ld" (withPrograms lbi) - case fmap programLocation mb of - Just (UserSpecified s) -> return s - -- assume we're using an installed copy of GHC.. - _ -> return binInstallLd -#else -findLdProgram _ = - return "ld" -#endif +findLdProgram lbi + = case os of + Windows MingW -> + do let compilerDir = takeDirectory $ compilerPath (compiler lbi) + baseDir = takeDirectory compilerDir + binInstallLd = baseDir </> "gcc-lib" </> "ld.exe" + mb <- lookupProgram "ld" (withPrograms lbi) + case fmap programLocation mb of + Just (UserSpecified s) -> return s + -- assume we're using an installed copy of GHC.. + _ -> return binInstallLd + _ -> return "ld" -- ----------------------------------------------------------------------------- -- Building a Makefile diff --git a/Distribution/Simple/Hugs.hs b/Distribution/Simple/Hugs.hs index 26cf11cb211e8da2e3458342c2f26c067ac86244..925227cfa3dc94360f8b3c11b2dc78e559c7acb0 100644 --- a/Distribution/Simple/Hugs.hs +++ b/Distribution/Simple/Hugs.hs @@ -66,6 +66,7 @@ import Distribution.Compat.Directory ( copyFile, removeDirectoryRecursive ) import System.FilePath ( (</>), takeExtension, (<.>), searchPathSeparator, normalise, takeDirectory ) +import Distribution.System import Distribution.Verbosity import Distribution.Package ( PackageIdentifier(..) ) @@ -343,17 +344,18 @@ install verbosity libDir installProgDir binDir targetProgDir buildPref pkg_descr -- FIX (HUGS): use extensions, and options from file too? -- see http://hackage.haskell.org/trac/hackage/ticket/43 let hugsOptions = hcOptions Hugs (options (buildInfo exe)) -#if mingw32_HOST_OS || mingw32_TARGET_OS - let exeFile = binDir </> exeName exe <.> ".bat" - let script = unlines [ - "@echo off", - unwords ("runhugs" : hugsOptions ++ [targetName, "%*"])] -#else - let exeFile = binDir </> exeName exe - let script = unlines [ - "#! /bin/sh", - unwords ("runhugs" : hugsOptions ++ [targetName, "\"$@\""])] -#endif + let exeFile = case os of + Windows _ -> binDir </> exeName exe <.> ".bat" + _ -> binDir </> exeName exe + let script = case os of + Windows _ -> + let args = hugsOptions ++ [targetName, "%*"] + in unlines ["@echo off", + unwords ("runhugs" : args)] + _ -> + let args = hugsOptions ++ [targetName, "\"$@\""] + in unlines ["#! /bin/sh", + unwords ("runhugs" : args)] writeFile exeFile script perms <- getPermissions exeFile setPermissions exeFile perms { executable = True, readable = True } diff --git a/Distribution/Simple/LocalBuildInfo.hs b/Distribution/Simple/LocalBuildInfo.hs index 9cbab211a13d55d8580d7491dab21b678b84aead..f53bd1b2033de473d725f91d364489dfce109db4 100644 --- a/Distribution/Simple/LocalBuildInfo.hs +++ b/Distribution/Simple/LocalBuildInfo.hs @@ -73,6 +73,7 @@ import Distribution.PackageDescription (PackageDescription(..)) import Distribution.Package (PackageIdentifier(..), showPackageId) import Distribution.Compiler (Compiler(..), CompilerFlavor(..), showCompilerId) import Distribution.Setup (CopyDest(..)) +import Distribution.System import Distribution.Version (showVersion) import System.FilePath #if mingw32_HOST_OS || mingw32_TARGET_OS @@ -222,35 +223,29 @@ foreign import stdcall unsafe "shlobj.h SHGetFolderPathA" #endif default_bindir :: FilePath -default_bindir = "$prefix" </> -#if mingw32_HOST_OS || mingw32_TARGET_OS - "Haskell" </> "bin" -#else - "bin" -#endif +default_bindir = "$prefix" </> path + where path = case os of + Windows _ -> "Haskell" </> "bin" + _ -> "bin" default_libdir :: Compiler -> FilePath -default_libdir _ = "$prefix" </> -#if mingw32_HOST_OS || mingw32_TARGET_OS - "Haskell" -#else - "lib" -#endif +default_libdir _ = "$prefix" </> path + where path = case os of + Windows _ -> "Haskell" + _ -> "lib" default_libsubdir :: Compiler -> FilePath default_libsubdir hc = case compilerFlavor hc of - Hugs -> "hugs" </> "packages" </> "$pkg" + Hugs -> "hugs" </> "packages" </> "$pkg" JHC -> "$compiler" - _ -> "$pkgid" </> "$compiler" + _ -> "$pkgid" </> "$compiler" default_libexecdir :: FilePath -default_libexecdir = "$prefix" </> -#if mingw32_HOST_OS || mingw32_TARGET_OS - "$pkgid" -#else - "libexec" -#endif +default_libexecdir = "$prefix" </> path + where path = case os of + Windows _ -> "$pkgid" + _ -> "libexec" default_datadir :: PackageDescription -> IO FilePath #if mingw32_HOST_OS || mingw32_TARGET_OS @@ -333,18 +328,7 @@ absolutePath pkg_descr lbi copydest s = case copydest of NoCopyDest -> substDir (package pkg_descr) lbi s CopyPrefix d -> substDir (package pkg_descr) lbi{prefix=d} s - CopyTo p -> p </> (dropAbsolutePrefix (substDir (package pkg_descr) lbi s)) - where - -- | If the function is applied to an absolute path then it returns a local path droping - -- the absolute prefix in the path. Under Windows the prefix is \"\\\", \"c:\" or \"c:\\\". Under - -- Unix the prefix is always \"\/\". - dropAbsolutePrefix :: FilePath -> FilePath - dropAbsolutePrefix (c:cs) | isPathSeparator c = cs -#if mingw32_HOST_OS || mingw32_TARGET_OS - dropAbsolutePrefix (_:':':c:cs) | isPathSeparator c = cs -- path with drive letter - dropAbsolutePrefix (_:':':cs) = cs -#endif - dropAbsolutePrefix cs = cs + CopyTo p -> p </> (dropDrive (substDir (package pkg_descr) lbi s)) substDir :: PackageIdentifier -> LocalBuildInfo -> String -> String substDir pkgId lbi xs = loop xs diff --git a/Distribution/Simple/Register.hs b/Distribution/Simple/Register.hs index 02b097d95364d465946f25e065fb539d928732af..1293b9a9b5a26ce31ff5f79692c2025a1280e2c7 100644 --- a/Distribution/Simple/Register.hs +++ b/Distribution/Simple/Register.hs @@ -81,6 +81,7 @@ import Distribution.Simple.Utils (createDirectoryIfMissingVerbose, import Distribution.Simple.GHCPackageConfig (mkGHCPackageConfig, showGHCPackageConfig) import qualified Distribution.Simple.GHCPackageConfig as GHC (localPackageConfig, canWriteLocalPackageConfig, maybeCreateLocalPackageConfig) +import Distribution.System import Distribution.Compat.Directory (removeDirectoryRecursive, setPermissions, getPermissions, Permissions(executable) @@ -100,18 +101,14 @@ import Test.HUnit (Test) #endif regScriptLocation :: FilePath -#if mingw32_HOST_OS || mingw32_TARGET_OS -regScriptLocation = "register.bat" -#else -regScriptLocation = "register.sh" -#endif +regScriptLocation = case os of + Windows _ -> "register.bat" + _ -> "register.sh" unregScriptLocation :: FilePath -#if mingw32_HOST_OS || mingw32_TARGET_OS -unregScriptLocation = "unregister.bat" -#else -unregScriptLocation = "unregister.sh" -#endif +unregScriptLocation = case os of + Windows _ -> "unregister.bat" + _ -> "unregister.sh" -- ----------------------------------------------------------------------------- -- Registration @@ -165,23 +162,19 @@ register pkg_descr lbi regFlags putStrLn ("create " ++ instConf) writeInstalledConfig pkg_descr lbi inplace (Just instConf) - let register_flags - | ghc_63_plus = "update": -#if !(mingw32_HOST_OS || mingw32_TARGET_OS) - if genScript - then [] - else -#endif - [instConf] - | otherwise = "--update-package": -#if !(mingw32_HOST_OS || mingw32_TARGET_OS) - if genScript - then [] - else -#endif - ["--input-file="++instConf] - - let allFlags = register_flags + let register_flags + | ghc_63_plus = let conf = case os of + Windows MingW + | genScript -> [] + _ -> [instConf] + in "update" : conf + | otherwise = let conf = case os of + Windows MingW + | genScript -> [] + _ -> ["--input-file="++instConf] + in "--update-package" : conf + + let allFlags = register_flags ++ config_flags ++ if ghc_63_plus && genScript then ["-"] else [] let pkgTool = compilerPkgToolPath hc @@ -374,16 +367,15 @@ rawSystemEmit :: FilePath -- ^Script name -> IO () rawSystemEmit _ False verbosity path args = rawSystemExit verbosity path args -rawSystemEmit scriptName True _ path args = do -#if mingw32_HOST_OS || mingw32_TARGET_OS - writeFile scriptName ("@" ++ path ++ concatMap (' ':) args) -#else - writeFile scriptName ("#!/bin/sh\n\n" - ++ (path ++ concatMap (' ':) args) - ++ "\n") - p <- getPermissions scriptName - setPermissions scriptName p{executable=True} -#endif +rawSystemEmit scriptName True _ path args + = case os of + Windows _ -> + writeFile scriptName ("@" ++ path ++ concatMap (' ':) args) + _ -> do writeFile scriptName ("#!/bin/sh\n\n" + ++ (path ++ concatMap (' ':) args) + ++ "\n") + p <- getPermissions scriptName + setPermissions scriptName p{executable=True} -- |Like rawSystemEmit, except it has string for pipeFrom. FIX: chmod +x rawSystemPipe :: FilePath -- ^Script location @@ -392,18 +384,17 @@ rawSystemPipe :: FilePath -- ^Script location -> FilePath -- ^Program to run -> [String] -- ^Args -> IO () -rawSystemPipe scriptName _ pipeFrom path args = do -#if mingw32_HOST_OS || mingw32_TARGET_OS - writeFile scriptName ("@" ++ path ++ concatMap (' ':) args) -#else - writeFile scriptName ("#!/bin/sh\n\n" - ++ "echo '" ++ escapeForShell pipeFrom - ++ "' | " - ++ (path ++ concatMap (' ':) args) - ++ "\n") - p <- getPermissions scriptName - setPermissions scriptName p{executable=True} -#endif +rawSystemPipe scriptName _ pipeFrom path args + = case os of + Windows _ -> + writeFile scriptName ("@" ++ path ++ concatMap (' ':) args) + _ -> do writeFile scriptName ("#!/bin/sh\n\n" + ++ "echo '" ++ escapeForShell pipeFrom + ++ "' | " + ++ (path ++ concatMap (' ':) args) + ++ "\n") + p <- getPermissions scriptName + setPermissions scriptName p{executable=True} where escapeForShell [] = [] escapeForShell ('\'':cs) = "'\\''" ++ escapeForShell cs escapeForShell (c :cs) = c : escapeForShell cs diff --git a/Distribution/Simple/Utils.hs b/Distribution/Simple/Utils.hs index 53b0b7b4f01b34beca2c53b4d70b25791565a26e..43495ccf6d0bb7d212c29462a860ed012528e29b 100644 --- a/Distribution/Simple/Utils.hs +++ b/Distribution/Simple/Utils.hs @@ -84,6 +84,7 @@ module Distribution.Simple.Utils ( import Distribution.Compat.RawSystem (rawSystem) import Distribution.Compat.Exception (bracket) +import Distribution.System #if __GLASGOW_HASKELL__ >= 604 import Control.Exception (evaluate) @@ -470,11 +471,9 @@ findHookedPackageDesc dir = do -- | Extension for executable files -- (typically @\"\"@ on Unix and @\"exe\"@ on Windows or OS\/2) exeExtension :: String -#if mingw32_HOST_OS || mingw32_TARGET_OS -exeExtension = "exe" -#else -exeExtension = "" -#endif +exeExtension = case os of + Windows _ -> "exe" + _ -> "" -- ToDo: This should be determined via autoconf (AC_OBJEXT) -- | Extension for object files. For GHC and NHC the extension is @\"o\"@. @@ -485,12 +484,9 @@ objExtension = "o" -- | Extension for dynamically linked (or shared) libraries -- (typically @\"so\"@ on Unix and @\"dll\"@ on Windows) dllExtension :: String -#if mingw32_HOST_OS || mingw32_TARGET_OS -dllExtension = "dll" -#else -dllExtension = "so" -#endif - +dllExtension = case os of + Windows _ -> "dll" + _ -> "so" -- ------------------------------------------------------------ -- * Testing diff --git a/Distribution/System.hs b/Distribution/System.hs new file mode 100644 index 0000000000000000000000000000000000000000..a382aaef9281182f6a2fddc10e5f94644d6acbc4 --- /dev/null +++ b/Distribution/System.hs @@ -0,0 +1,16 @@ + +module Distribution.System where + +data OS = Linux | Windows Windows | Other String +data Windows = MingW + +os :: OS +os = +#if defined(linux_HOST_OS) + Linux +#elif defined(mingw32_HOST_OS) + Windows MingW +#else + Other System.Info.os +#endif +