1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE RankNTypes #-}
5 -----------------------------------------------------------------------------
8 -- Module : Distribution.Simple.Install
9 -- Copyright : Isaac Jones 2003-2004
12 -- Maintainer : cabal-devel@haskell.org
13 -- Portability : portable
15 -- This is the entry point into installing a built package. Performs the
16 -- \"@.\/setup install@\" and \"@.\/setup copy@\" actions. It moves files into
17 -- place based on the prefix argument. It does the generic bits and then calls
18 -- compiler-specific functions to do the rest.
19 module Distribution
.Simple
.Install
24 import Distribution
.Compat
.Prelude
27 import Distribution
.CabalSpecVersion
(CabalSpecVersion
)
29 import Distribution
.Types
.ExecutableScope
30 import Distribution
.Types
.ForeignLib
31 import Distribution
.Types
.LocalBuildInfo
32 import Distribution
.Types
.PackageDescription
33 import Distribution
.Types
.TargetInfo
34 import Distribution
.Types
.UnqualComponentName
36 import Distribution
.Package
37 import Distribution
.PackageDescription
38 import Distribution
.Simple
.BuildPaths
(haddockName
, haddockPref
)
39 import Distribution
.Simple
.BuildTarget
40 import Distribution
.Simple
.Compiler
44 import Distribution
.Simple
.Glob
(matchDirFileGlob
)
45 import Distribution
.Simple
.LocalBuildInfo
46 import Distribution
.Simple
.Setup
.Config
47 import Distribution
.Simple
.Setup
.Copy
50 import Distribution
.Simple
.Setup
.Haddock
51 ( HaddockTarget
(ForDevelopment
)
53 import Distribution
.Simple
.Utils
54 ( createDirectoryIfMissingVerbose
57 , installDirectoryContents
59 , isAbsoluteOnAnyPlatform
64 import Distribution
.Utils
.Path
66 import Distribution
.Compat
.Graph
(IsNode
(..))
67 import Distribution
.Simple
.Errors
68 import qualified Distribution
.Simple
.GHC
as GHC
69 import qualified Distribution
.Simple
.GHCJS
as GHCJS
70 import qualified Distribution
.Simple
.HaskellSuite
as HaskellSuite
71 import Distribution
.Simple
.Setup
.Common
72 import qualified Distribution
.Simple
.UHC
as UHC
74 import System
.Directory
78 import System
.FilePath
83 import Distribution
.Pretty
86 import Distribution
.Verbosity
88 -- | Perform the \"@.\/setup install@\" and \"@.\/setup copy@\"
89 -- actions. Move files into place based on the prefix argument.
91 -- This does NOT register libraries, you should call 'register'
95 -- ^ information from the .cabal file
97 -- ^ information from the configure step
99 -- ^ flags sent to copy or install
101 install pkg_descr lbi flags
= do
103 targets
<- readTargetInfos verbosity pkg_descr lbi
(copyTargets flags
)
105 copyPackage verbosity pkg_descr lbi distPref copydest
107 -- It's not necessary to do these in build-order, but it's harmless
108 withNeededTargetsInBuildOrder
' pkg_descr lbi
(map nodeKey targets
) $ \target
->
109 let comp
= targetComponent target
110 clbi
= targetCLBI target
111 in copyComponent verbosity pkg_descr lbi comp clbi copydest
113 common
= copyCommonFlags flags
114 distPref
= fromFlag
$ setupDistPref common
115 verbosity
= fromFlag
$ setupVerbosity common
116 copydest
= fromFlag
(copyDest flags
)
119 unless (hasLibs pkg_descr || hasForeignLibs pkg_descr || hasExes pkg_descr
) $
120 dieWithException verbosity NoLibraryFound
122 -- | Copy package global files.
125 -> PackageDescription
127 -> SymbolicPath Pkg
(Dir Dist
)
130 copyPackage verbosity pkg_descr lbi distPref copydest
= do
132 -- This is a bit of a hack, to handle files which are not
133 -- per-component (data files and Haddock files.)
138 , haddockdir
= interfacePref
139 } = absoluteInstallCommandDirs pkg_descr lbi
(localUnitId lbi
) copydest
140 mbWorkDir
= mbWorkDirLBI lbi
141 i
= interpretSymbolicPath mbWorkDir
-- See Note [Symbolic paths] in Distribution.Utils.Path
143 -- Install (package-global) data files
144 installDataFiles verbosity mbWorkDir pkg_descr
$ makeSymbolicPath dataPref
146 -- Install (package-global) Haddock files
147 -- TODO: these should be done per-library
148 docExists
<- doesDirectoryExist $ i
$ haddockPref ForDevelopment distPref pkg_descr
152 ++ getSymbolicPath
(haddockPref ForDevelopment distPref pkg_descr
)
157 -- TODO: this is a bit questionable, Haddock files really should
158 -- be per library (when there are convenience libraries.)
160 createDirectoryIfMissingVerbose verbosity
True htmlPref
161 installDirectoryContents
163 (i
$ haddockPref ForDevelopment distPref pkg_descr
)
165 -- setPermissionsRecursive [Read] htmlPref
166 -- The haddock interface file actually already got installed
167 -- in the recursive copy, but now we install it where we actually
168 -- want it to be (normally the same place). We could remove the
169 -- copy in htmlPref first.
170 let haddockInterfaceFileSrc
=
171 haddockPref ForDevelopment distPref pkg_descr
172 </> makeRelativePathEx
(haddockName pkg_descr
)
173 haddockInterfaceFileDest
= interfacePref
</> haddockName pkg_descr
174 -- We only generate the haddock interface file for libs, So if the
175 -- package consists only of executables there will not be one:
176 exists
<- doesFileExist $ i haddockInterfaceFileSrc
178 createDirectoryIfMissingVerbose verbosity
True interfacePref
181 (i haddockInterfaceFileSrc
)
182 haddockInterfaceFileDest
184 let lfiles
= licenseFiles pkg_descr
185 unless (null lfiles
) $ do
186 createDirectoryIfMissingVerbose verbosity
True docPref
187 for_ lfiles
$ \lfile
-> do
191 (docPref
</> takeFileName
(getSymbolicPath lfile
))
193 -- | Copy files associated with a component.
196 -> PackageDescription
199 -> ComponentLocalBuildInfo
202 copyComponent verbosity pkg_descr lbi
(CLib lib
) clbi copydest
= do
205 , dynlibdir
= dynlibPref
206 , includedir
= incPref
207 } = absoluteInstallCommandDirs pkg_descr lbi
(componentUnitId clbi
) copydest
208 buildPref
= interpretSymbolicPathLBI lbi
$ componentBuildDir lbi clbi
211 LMainLibName
-> noticeNoWrap verbosity
("Installing library in " ++ libPref
)
212 LSubLibName n
-> noticeNoWrap verbosity
("Installing internal library " ++ prettyShow n
++ " in " ++ libPref
)
214 -- install include files for all compilers - they may be needed to compile
215 -- haskell files (using the CPP extension)
216 installIncludeFiles verbosity
(libBuildInfo lib
) lbi buildPref incPref
218 case compilerFlavor
(compiler lbi
) of
219 GHC
-> GHC
.installLib verbosity lbi libPref dynlibPref buildPref pkg_descr lib clbi
220 GHCJS
-> GHCJS
.installLib verbosity lbi libPref dynlibPref buildPref pkg_descr lib clbi
221 UHC
-> UHC
.installLib verbosity lbi libPref dynlibPref buildPref pkg_descr lib clbi
223 HaskellSuite
.installLib
233 dieWithException verbosity
$ CompilerNotInstalled
(compilerFlavor
(compiler lbi
))
234 copyComponent verbosity pkg_descr lbi
(CFLib flib
) clbi copydest
= do
237 , includedir
= incPref
238 } = absoluteComponentInstallDirs pkg_descr lbi
(componentUnitId clbi
) copydest
239 buildPref
= interpretSymbolicPathLBI lbi
$ componentBuildDir lbi clbi
241 noticeNoWrap verbosity
("Installing foreign library " ++ unUnqualComponentName
(foreignLibName flib
) ++ " in " ++ flibPref
)
242 installIncludeFiles verbosity
(foreignLibBuildInfo flib
) lbi buildPref incPref
244 case compilerFlavor
(compiler lbi
) of
245 GHC
-> GHC
.installFLib verbosity lbi flibPref buildPref pkg_descr flib
246 GHCJS
-> GHCJS
.installFLib verbosity lbi flibPref buildPref pkg_descr flib
247 _
-> dieWithException verbosity
$ CompilerNotInstalled
(compilerFlavor
(compiler lbi
))
248 copyComponent verbosity pkg_descr lbi
(CExe exe
) clbi copydest
= do
249 let installDirs
= absoluteComponentInstallDirs pkg_descr lbi
(componentUnitId clbi
) copydest
250 -- the installers know how to find the actual location of the
252 buildPref
= interpretSymbolicPathLBI lbi
$ buildDir lbi
253 uid
= componentUnitId clbi
254 pkgid
= packageId pkg_descr
256 | ExecutablePrivate
<- exeScope exe
= libexecdir installDirs
257 |
otherwise = bindir installDirs
258 progPrefixPref
= substPathTemplate pkgid lbi uid
(progPrefix lbi
)
259 progSuffixPref
= substPathTemplate pkgid lbi uid
(progSuffix lbi
)
260 progFix
= (progPrefixPref
, progSuffixPref
)
263 ( "Installing executable "
264 ++ prettyShow
(exeName exe
)
268 inPath
<- isInSearchPath binPref
274 ++ " is not in the system search path."
276 case compilerFlavor
(compiler lbi
) of
277 GHC
-> GHC
.installExe verbosity lbi binPref buildPref progFix pkg_descr exe
278 GHCJS
-> GHCJS
.installExe verbosity lbi binPref buildPref progFix pkg_descr exe
280 HaskellSuite
{} -> return ()
282 dieWithException verbosity
$ CompilerNotInstalled
(compilerFlavor
(compiler lbi
))
284 -- Nothing to do for benchmark/testsuite
285 copyComponent _ _ _
(CBench _
) _ _
= return ()
286 copyComponent _ _ _
(CTest _
) _ _
= return ()
288 -- | Install the files listed in data-files
291 -> Maybe (SymbolicPath CWD
(Dir Pkg
))
292 -> PackageDescription
293 -> SymbolicPath Pkg
(Dir DataDir
)
295 installDataFiles verbosity mbWorkDir pkg_descr destDataDir
=
297 (installFileGlob verbosity
(specVersion pkg_descr
) mbWorkDir
(srcDataDir
, destDataDir
))
298 (dataFiles pkg_descr
)
300 srcDataDirRaw
= getSymbolicPath
$ dataDir pkg_descr
301 srcDataDir
:: Maybe (SymbolicPath CWD
(Dir DataDir
))
303 |
null srcDataDirRaw
=
305 | isAbsoluteOnAnyPlatform srcDataDirRaw
=
306 Just
$ makeSymbolicPath srcDataDirRaw
308 Just
$ fromMaybe sameDirectory mbWorkDir
</> makeRelativePathEx srcDataDirRaw
310 -- | Install the files specified by the given glob pattern.
314 -> Maybe (SymbolicPath CWD
(Dir Pkg
))
315 -> (Maybe (SymbolicPath CWD
(Dir DataDir
)), SymbolicPath Pkg
(Dir DataDir
))
316 -- ^ @(src_dir, dest_dir)@
317 -> RelativePath DataDir File
318 -- ^ file glob pattern
320 installFileGlob verbosity spec_version mbWorkDir
(srcDir
, destDir
) glob
= do
321 files
<- matchDirFileGlob verbosity spec_version srcDir glob
322 for_ files
$ \file
' -> do
323 let src
= getSymbolicPath
(fromMaybe sameDirectory srcDir
</> file
')
324 dst
= interpretSymbolicPath mbWorkDir
(destDir
</> file
')
325 createDirectoryIfMissingVerbose verbosity
True (takeDirectory dst
)
326 installOrdinaryFile verbosity src dst
328 -- | Install the files listed in install-includes for a library
329 installIncludeFiles
:: Verbosity
-> BuildInfo
-> LocalBuildInfo
-> FilePath -> FilePath -> IO ()
330 installIncludeFiles verbosity libBi lbi buildPref destIncludeDir
= do
331 let relincdirs
= sameDirectory
: mapMaybe symbolicPathRelative_maybe
(includeDirs libBi
)
333 [ root
</> getSymbolicPath dir
334 |
-- NB: both baseDir and buildPref are already interpreted,
335 -- so we don't need to interpret these paths in the call to findInc.
337 , root
<- [baseDir lbi
, buildPref
]
339 incs
<- traverse
(findInc incdirs
. getSymbolicPath
) (installIncludes libBi
)
342 createDirectoryIfMissingVerbose verbosity
True destDir
343 installOrdinaryFile verbosity srcFile destFile
344 |
(relFile
, srcFile
) <- incs
345 , let destFile
= destIncludeDir
</> relFile
346 destDir
= takeDirectory destFile
349 baseDir lbi
' = packageRoot
$ configCommonFlags
$ configFlags lbi
'
350 findInc
[] file
= dieWithException verbosity
$ CantFindIncludeFile file
351 findInc
(dir
: dirs
) file
= do
352 let path
= dir
</> file
353 exists
<- doesFileExist path
354 if exists
then return (file
, path
) else findInc dirs file