LocalBuildInfo.hs 12.1 KB
Newer Older
1
{-# OPTIONS -cpp -fffi #-}
ijones's avatar
ijones committed
2 3 4 5 6 7 8
-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Simple.LocalBuildInfo
-- Copyright   :  Isaac Jones 2003-2004
-- 
-- Maintainer  :  Isaac Jones <ijones@syntaxpolice.org>
-- Stability   :  alpha
ijones's avatar
ijones committed
9
-- Portability :  portable
ijones's avatar
ijones committed
10
--
11 12 13 14 15
-- Definition of the 'LocalBuildInfo' data type.  This is basically
-- the information that is gathered by the end of the configuration
-- step which could include package information from ghc-pkg, flags
-- the user passed to configure, and the location of tools in the
-- PATH.
ijones's avatar
ijones committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

{- All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of Isaac Jones nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -}

47 48 49 50 51 52 53 54 55
module Distribution.Simple.LocalBuildInfo ( 
	LocalBuildInfo(..),
	default_prefix,
	default_bindir,
	default_libdir,
	default_libsubdir,
	default_libexecdir,
	default_datadir,
	default_datasubdir,
Duncan Coutts's avatar
Duncan Coutts committed
56 57 58 59 60 61
	mkLibDir, mkLibDirRel,
	mkBinDir, mkBinDirRel,
	mkLibexecDir, mkLibexecDirRel,
	mkDataDir, mkDataDirRel,
	mkHaddockDir,
	mkProgDirRel, mkProgDir,
62
	absolutePath, prefixRelPath,
63
	substDir,
Duncan Coutts's avatar
Duncan Coutts committed
64 65 66 67
	distPref, srcPref,
	hscolourPref, haddockPref,
	autogenModulesDir,
	mkIncludeDir
68
  ) where
ijones's avatar
ijones committed
69

ijones's avatar
ijones committed
70

Simon Marlow's avatar
Simon Marlow committed
71 72
import Distribution.Program (ProgramConfiguration)
import Distribution.PackageDescription (PackageDescription(..))
ijones's avatar
ijones committed
73 74 75
import Distribution.Package (PackageIdentifier(..), showPackageId)
import Distribution.Compiler (Compiler(..), CompilerFlavor(..), showCompilerId)
import Distribution.Setup (CopyDest(..))
76
import Distribution.System
77
import Distribution.Version (showVersion)
78
import System.FilePath
ijones's avatar
ijones committed
79
#if mingw32_HOST_OS || mingw32_TARGET_OS
simonmar's avatar
simonmar committed
80 81
import Data.Maybe (fromMaybe)
import Distribution.PackageDescription (hasLibs)
ijones's avatar
ijones committed
82 83 84
import Foreign
import Foreign.C
#endif
ijones's avatar
ijones committed
85

86 87
-- |Data cached after configuration step.  See also
-- 'Distribution.Setup.ConfigFlags'.
ijones's avatar
ijones committed
88
data LocalBuildInfo = LocalBuildInfo {
89
  	prefix	      :: FilePath,
90 91
		-- ^ The installation directory (eg. @\/usr\/local@, or
		-- @C:\/Program Files\/foo-1.2@ on Windows.
92 93 94 95 96 97 98 99 100 101 102 103
	bindir        :: FilePath,
		-- ^ The bin directory
	libdir        :: FilePath,
		-- ^ The lib directory
	libsubdir     :: FilePath,
		-- ^ Subdirectory of libdir into which libraries are installed
	libexecdir    :: FilePath,
		-- ^ The lib directory
	datadir       :: FilePath,
		-- ^ The data directory
	datasubdir    :: FilePath,
		-- ^ Subdirectory of datadir into which data files are installed
104
	compiler      :: Compiler,
ijones's avatar
ijones committed
105
		-- ^ The compiler we're building with
106
	buildDir      :: FilePath,
107 108 109
		-- ^ Where to build the package.
	scratchDir    :: FilePath,
		-- ^ Where to put the result of the Hugs build.
110
	packageDeps   :: [PackageIdentifier],
ijones's avatar
ijones committed
111 112 113
		-- ^ Which packages we depend on, /exactly/.
		-- The 'Distribution.PackageDescription.PackageDescription'
		-- specifies a set of build dependencies
ijones's avatar
ijones committed
114 115 116
		-- that must be satisfied in terms of version ranges.  This
		-- field fixes those dependencies to the specific versions
		-- available on this machine for this compiler.
117 118 119
        localPkgDescr :: PackageDescription,
                -- ^ The resolved package description, that does not contain
                -- any conditionals.
120
        withPrograms  :: ProgramConfiguration, -- location and args for all programs
121
        userConf      :: Bool,           -- ^Was this package configured with --user?
122 123 124
        withVanillaLib:: Bool,  -- ^Whether to build normal libs.
        withProfLib   :: Bool,  -- ^Whether to build profiling versions of libs.
        withProfExe   :: Bool,  -- ^Whether to build executables for profiling.
125
        withOptimization :: Bool, -- ^Whether to build with optimization (if available).
126
        withGHCiLib   :: Bool,  -- ^Whether to build libs suitable for use with GHCi.
127
	splitObjs     :: Bool 	-- ^Use -split-objs with GHC, if available
128

ijones's avatar
ijones committed
129
  } deriving (Read, Show)
ijones's avatar
ijones committed
130

131 132 133 134 135 136 137 138
-- ------------------------------------------------------------
-- * Some Paths
-- ------------------------------------------------------------

distPref :: FilePath
distPref = "dist"

srcPref :: FilePath
139
srcPref = distPref </> "src"
140

Roberto Zunino's avatar
Roberto Zunino committed
141 142 143
hscolourPref :: PackageDescription -> FilePath
hscolourPref = haddockPref

144 145
haddockPref :: PackageDescription -> FilePath
haddockPref pkg_descr
146
    = foldl1 (</>) [distPref, "doc", "html", pkgName (package pkg_descr)]
Simon Marlow's avatar
Simon Marlow committed
147

148 149
-- |The directory in which we put auto-generated modules
autogenModulesDir :: LocalBuildInfo -> String
150
autogenModulesDir lbi = buildDir lbi </> "autogen"
151

152 153
-- |The place where install-includes are installed, relative to libdir
mkIncludeDir :: FilePath -> FilePath
154
mkIncludeDir = (</> "include")
155

156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
-- -----------------------------------------------------------------------------
-- Default directories

{-
The defaults are as follows:

Windows:
	prefix	   = C:\Program Files
	bindir     = $prefix\$pkgid
	libdir     = $prefix\Haskell
	libsubdir  = $pkgid\$compiler
	datadir    = $prefix			(for an executable)
	           = $prefix\Common Files	(for a library)
	datasubdir = $pkgid
	libexecdir = $prefix\$pkgid

Unix:
	prefix	   = /usr/local
	bindir	   = $prefix/bin
	libdir	   = $prefix/lib/$pkgid/$compiler
	libsubdir  = $pkgid/$compiler
	datadir	   = $prefix/share/$pkgid
	datasubdir = $pkgid
	libexecdir = $prefix/libexec
-}

default_prefix :: IO String
#if mingw32_HOST_OS || mingw32_TARGET_OS
# if __HUGS__
default_prefix = return "C:\\Program Files"
# else
default_prefix = getProgramFilesDir
# endif
#else
default_prefix = return "/usr/local"
#endif

#if mingw32_HOST_OS || mingw32_TARGET_OS
getProgramFilesDir = do
  m <- shGetFolderPath csidl_PROGRAM_FILES
  return (fromMaybe "C:\\Program Files" m)

getCommonFilesDir = do
  m <- shGetFolderPath csidl_PROGRAM_FILES_COMMON
  case m of
   Nothing -> getProgramFilesDir
   Just s  -> return s

shGetFolderPath id =
  allocaBytes long_path_size $ \pPath -> do
     r <- c_SHGetFolderPath nullPtr id nullPtr 0 pPath
     if (r /= 0) 
	then return Nothing
	else do s <- peekCString pPath; return (Just s)
  where
    long_path_size      = 1024

Ross Paterson's avatar
Ross Paterson committed
213 214
csidl_PROGRAM_FILES = 0x0026 :: CInt
csidl_PROGRAM_FILES_COMMON = 0x002b :: CInt
215 216 217 218 219 220 221 222 223 224

foreign import stdcall unsafe "shlobj.h SHGetFolderPathA" 
            c_SHGetFolderPath :: Ptr () 
                              -> CInt 
                              -> Ptr () 
                              -> CInt 
                              -> CString 
                              -> IO CInt
#endif

Simon Marlow's avatar
Simon Marlow committed
225
default_bindir :: FilePath
226 227 228 229
default_bindir = "$prefix" </> path
    where path = case os of
                     Windows _ -> "Haskell" </> "bin"
                     _         -> "bin"
230

Simon Marlow's avatar
Simon Marlow committed
231
default_libdir :: Compiler -> FilePath
232 233 234 235
default_libdir _ = "$prefix" </> path
    where path = case os of
                     Windows _ -> "Haskell"
                     _         -> "lib"
236

Simon Marlow's avatar
Simon Marlow committed
237
default_libsubdir :: Compiler -> FilePath
238 239
default_libsubdir hc =
  case compilerFlavor hc of
240
        Hugs -> "hugs" </> "packages" </> "$pkg"
ekarttun's avatar
ekarttun committed
241
        JHC  -> "$compiler"
242
        _    -> "$pkgid" </> "$compiler"
243

Simon Marlow's avatar
Simon Marlow committed
244
default_libexecdir :: FilePath
245 246 247 248
default_libexecdir = "$prefix" </> path
    where path = case os of
                     Windows _ -> "$pkgid"
                     _         -> "libexec"
249 250 251

default_datadir :: PackageDescription -> IO FilePath
#if mingw32_HOST_OS || mingw32_TARGET_OS
Ian Lynagh's avatar
Ian Lynagh committed
252
default_datadir pkg_descr
253
	| hasLibs pkg_descr = getCommonFilesDir
254
	| otherwise = return ("$prefix" </> "Haskell")
255
#else
Ian Lynagh's avatar
Ian Lynagh committed
256
default_datadir _
257
	= return  ("$prefix" </> "share")
258 259
#endif

Simon Marlow's avatar
Simon Marlow committed
260
default_datasubdir :: FilePath
261 262 263
default_datasubdir = "$pkgid"

mkBinDir :: PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath
ijones's avatar
ijones committed
264 265 266 267 268 269
mkBinDir pkg_descr lbi copydest = 
  absolutePath  pkg_descr lbi copydest (bindir lbi)

mkBinDirRel :: PackageDescription -> LocalBuildInfo -> CopyDest -> Maybe FilePath
mkBinDirRel pkg_descr lbi copydest = 
  prefixRelPath pkg_descr lbi copydest (bindir lbi)
270 271

mkLibDir :: PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath
ijones's avatar
ijones committed
272
mkLibDir pkg_descr lbi copydest = 
273
  absolutePath  pkg_descr lbi copydest (libdir lbi </> libsubdir lbi)
ijones's avatar
ijones committed
274 275 276

mkLibDirRel :: PackageDescription -> LocalBuildInfo -> CopyDest -> Maybe FilePath
mkLibDirRel pkg_descr lbi copydest = 
277
  prefixRelPath pkg_descr lbi copydest (libdir lbi </> libsubdir lbi)
278 279

mkLibexecDir :: PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath
ijones's avatar
ijones committed
280 281 282 283 284 285
mkLibexecDir pkg_descr lbi copydest = 
  absolutePath  pkg_descr lbi copydest (libexecdir lbi)

mkLibexecDirRel :: PackageDescription -> LocalBuildInfo -> CopyDest -> Maybe FilePath
mkLibexecDirRel pkg_descr lbi copydest = 
  prefixRelPath pkg_descr lbi copydest (libexecdir lbi)
286 287

mkDataDir :: PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath
ijones's avatar
ijones committed
288
mkDataDir pkg_descr lbi copydest = 
289
  absolutePath  pkg_descr lbi copydest (datadir lbi </> datasubdir lbi)
ijones's avatar
ijones committed
290 291 292

mkDataDirRel :: PackageDescription -> LocalBuildInfo -> CopyDest -> Maybe FilePath
mkDataDirRel pkg_descr lbi copydest = 
293
  prefixRelPath pkg_descr lbi copydest (datadir lbi </> datasubdir lbi)
294

295 296
mkHaddockDir :: PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath
mkHaddockDir pkg_descr lbi copydest =
297
  foldl1 (</>) [mkDataDir pkg_descr lbi copydest,
298
                    "doc", "html", pkgName (package pkg_descr)]
299 300 301



302 303
-- | Directory for program modules (Hugs only).
mkProgDir :: PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath
ijones's avatar
ijones committed
304
mkProgDir pkg_descr lbi copydest = 
305
  absolutePath pkg_descr lbi copydest
306
    (libdir lbi </> "hugs" </> "programs")
307 308 309 310

mkProgDirRel :: PackageDescription -> LocalBuildInfo -> CopyDest -> Maybe FilePath
mkProgDirRel pkg_descr lbi copydest =
  prefixRelPath pkg_descr lbi copydest
311
    (libdir lbi </> "hugs" </> "programs")
312

Simon Marlow's avatar
Simon Marlow committed
313 314
prefixRelPath :: PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath
  -> Maybe FilePath
ijones's avatar
ijones committed
315 316
prefixRelPath pkg_descr lbi0 copydest ('$':'p':'r':'e':'f':'i':'x':s) = Just $
  case s of
317 318
    (c:s') | isPathSeparator c -> substDir (package pkg_descr) lbi s'
    _                          -> substDir (package pkg_descr) lbi s
ijones's avatar
ijones committed
319 320 321 322
  where
    lbi = case copydest of 
            CopyPrefix d -> lbi0{prefix=d}
            _otherwise   -> lbi0
Ian Lynagh's avatar
Ian Lynagh committed
323
prefixRelPath _         _   _        _ = Nothing
ijones's avatar
ijones committed
324

Simon Marlow's avatar
Simon Marlow committed
325 326
absolutePath :: PackageDescription -> LocalBuildInfo -> CopyDest -> FilePath
	-> FilePath
ijones's avatar
ijones committed
327 328
absolutePath pkg_descr lbi copydest s =
  case copydest of
329 330
    NoCopyDest   -> substDir (package pkg_descr) lbi s
    CopyPrefix d -> substDir (package pkg_descr) lbi{prefix=d} s
331
    CopyTo     p -> p </> (dropDrive (substDir (package pkg_descr) lbi s))
332

333 334
substDir :: PackageIdentifier -> LocalBuildInfo -> String -> String
substDir pkgId lbi xs = loop xs
335 336 337 338 339 340 341
 where
  loop "" = ""
  loop ('$':'p':'r':'e':'f':'i':'x':s) 
	= prefix lbi ++ loop s
  loop ('$':'c':'o':'m':'p':'i':'l':'e':'r':s) 
	= showCompilerId (compiler lbi) ++ loop s
  loop ('$':'p':'k':'g':'i':'d':s) 
342
	= showPackageId pkgId ++ loop s
343
  loop ('$':'p':'k':'g':s) 
344
	= pkgName pkgId ++ loop s
345
  loop ('$':'v':'e':'r':'s':'i':'o':'n':s) 
346
	= showVersion (pkgVersion pkgId) ++ loop s
347 348
  loop ('$':'$':s) = '$' : loop s
  loop (c:s) = c : loop s
Ian Lynagh's avatar
Ian Lynagh committed
349