1 {-# LANGUAGE DeriveGeneric #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE RankNTypes #-}
5 -----------------------------------------------------------------------------
7 -- Module : Distribution.Simple.LocalBuildInfo
8 -- Copyright : Isaac Jones 2003-2004
11 -- Maintainer : cabal-devel@haskell.org
12 -- Portability : portable
14 -- Once a package has been configured we have resolved conditionals and
15 -- dependencies, configured the compiler and other needed external programs.
16 -- The 'LocalBuildInfo' is used to hold all this information. It holds the
17 -- install dirs, the compiler, the exact package dependencies, the configured
18 -- programs, the package database to use and a bunch of miscellaneous configure
19 -- flags. It gets saved and reloaded from a file (@dist\/setup-config@). It gets
20 -- passed in to very many subsequent build actions.
22 module Distribution
.Simple
.LocalBuildInfo
(
27 localCompatPackageKey
,
29 -- * Buildable package components
35 ComponentLocalBuildInfo
(..),
42 pkgBuildableComponents
,
45 getComponentLocalBuildInfo
,
46 allComponentsInBuildOrder
,
47 componentsInBuildOrder
,
51 withAllComponentsInBuildOrder
,
52 withComponentsInBuildOrder
,
61 -- * Installation directories
62 module Distribution
.Simple
.InstallDirs
,
63 absoluteInstallDirs
, prefixRelativeInstallDirs
,
64 absoluteComponentInstallDirs
, prefixRelativeComponentInstallDirs
,
69 import Distribution
.Compat
.Prelude
71 import Distribution
.Types
.Component
72 import Distribution
.Types
.PackageId
73 import Distribution
.Types
.UnitId
74 import Distribution
.Types
.ComponentName
75 import Distribution
.Types
.UnqualComponentName
76 import Distribution
.Types
.PackageDescription
77 import Distribution
.Types
.ComponentLocalBuildInfo
78 import Distribution
.Types
.LocalBuildInfo
79 import Distribution
.Types
.TargetInfo
81 import Distribution
.Simple
.InstallDirs
hiding (absoluteInstallDirs
,
82 prefixRelativeInstallDirs
,
84 import qualified Distribution
.Simple
.InstallDirs
as InstallDirs
85 import Distribution
.PackageDescription
86 import qualified Distribution
.InstalledPackageInfo
as Installed
87 import Distribution
.Package
88 import Distribution
.ModuleName
89 import Distribution
.Simple
.Compiler
90 import Distribution
.Simple
.PackageIndex
91 import Distribution
.Simple
.Utils
92 import Distribution
.Text
93 import qualified Distribution
.Compat
.Graph
as Graph
95 import Data
.List
(stripPrefix
)
96 import System
.FilePath
97 import qualified Data
.Map
as Map
99 import System
.Directory
(doesDirectoryExist, canonicalizePath
)
101 -- -----------------------------------------------------------------------------
102 -- Configuration information of buildable components
104 componentBuildDir
:: LocalBuildInfo
-> ComponentLocalBuildInfo
-> FilePath
105 -- For now, we assume that libraries/executables/test-suites/benchmarks
106 -- are only ever built once. With Backpack, we need a special case for
107 -- libraries so that we can handle building them multiple times.
108 componentBuildDir lbi clbi
110 case componentLocalName clbi
of
112 if display
(componentUnitId clbi
) == display
(componentComponentId clbi
)
114 else display
(componentUnitId clbi
)
116 if display
(componentUnitId clbi
) == display
(componentComponentId clbi
)
117 then unUnqualComponentName s
118 else display
(componentUnitId clbi
)
119 CFLibName s
-> unUnqualComponentName s
120 CExeName s
-> unUnqualComponentName s
121 CTestName s
-> unUnqualComponentName s
122 CBenchName s
-> unUnqualComponentName s
124 {-# DEPRECATED getComponentLocalBuildInfo "This function is not well-defined, because a 'ComponentName' does not uniquely identify a 'ComponentLocalBuildInfo'. If you have a 'TargetInfo', you should use 'targetCLBI' to get the 'ComponentLocalBuildInfo'. Otherwise, use 'componentNameTargets' to get all possible 'ComponentLocalBuildInfo's. This will be removed in Cabal 2.2." #-}
125 getComponentLocalBuildInfo
:: LocalBuildInfo
-> ComponentName
-> ComponentLocalBuildInfo
126 getComponentLocalBuildInfo lbi cname
=
127 case componentNameCLBIs lbi cname
of
130 error $ "internal error: there is no configuration data "
131 ++ "for component " ++ show cname
133 error $ "internal error: the component name " ++ show cname
134 ++ "is ambiguous. Refers to: "
135 ++ intercalate
", " (map (display
. componentUnitId
) clbis
)
137 -- | Perform the action on each enabled 'library' in the package
138 -- description with the 'ComponentLocalBuildInfo'.
139 withLibLBI
:: PackageDescription
-> LocalBuildInfo
140 -> (Library
-> ComponentLocalBuildInfo
-> IO ()) -> IO ()
141 withLibLBI pkg lbi f
=
142 withAllTargetsInBuildOrder
' pkg lbi
$ \target
->
143 case targetComponent target
of
144 CLib lib
-> f lib
(targetCLBI target
)
147 -- | Perform the action on each enabled 'Executable' in the package
148 -- description. Extended version of 'withExe' that also gives corresponding
150 withExeLBI
:: PackageDescription
-> LocalBuildInfo
151 -> (Executable
-> ComponentLocalBuildInfo
-> IO ()) -> IO ()
152 withExeLBI pkg lbi f
=
153 withAllTargetsInBuildOrder
' pkg lbi
$ \target
->
154 case targetComponent target
of
155 CExe exe
-> f exe
(targetCLBI target
)
158 -- | Perform the action on each enabled 'Benchmark' in the package
160 withBenchLBI
:: PackageDescription
-> LocalBuildInfo
161 -> (Benchmark
-> ComponentLocalBuildInfo
-> IO ()) -> IO ()
162 withBenchLBI pkg lbi f
=
163 sequence_ [ f test clbi |
(test
, clbi
) <- enabledBenchLBIs pkg lbi
]
165 withTestLBI
:: PackageDescription
-> LocalBuildInfo
166 -> (TestSuite
-> ComponentLocalBuildInfo
-> IO ()) -> IO ()
167 withTestLBI pkg lbi f
=
168 sequence_ [ f test clbi |
(test
, clbi
) <- enabledTestLBIs pkg lbi
]
170 enabledTestLBIs
:: PackageDescription
-> LocalBuildInfo
171 -> [(TestSuite
, ComponentLocalBuildInfo
)]
172 enabledTestLBIs pkg lbi
=
173 [ (test
, targetCLBI target
)
174 | target
<- allTargetsInBuildOrder
' pkg lbi
175 , CTest test
<- [targetComponent target
] ]
177 enabledBenchLBIs
:: PackageDescription
-> LocalBuildInfo
178 -> [(Benchmark
, ComponentLocalBuildInfo
)]
179 enabledBenchLBIs pkg lbi
=
180 [ (bench
, targetCLBI target
)
181 | target
<- allTargetsInBuildOrder
' pkg lbi
182 , CBench bench
<- [targetComponent target
] ]
184 {-# DEPRECATED withComponentsLBI "Use withAllComponentsInBuildOrder" #-}
185 withComponentsLBI
:: PackageDescription
-> LocalBuildInfo
186 -> (Component
-> ComponentLocalBuildInfo
-> IO ())
188 withComponentsLBI
= withAllComponentsInBuildOrder
190 -- | Perform the action on each buildable 'Library' or 'Executable' (Component)
191 -- in the PackageDescription, subject to the build order specified by the
192 -- 'compBuildOrder' field of the given 'LocalBuildInfo'
193 withAllComponentsInBuildOrder
:: PackageDescription
-> LocalBuildInfo
194 -> (Component
-> ComponentLocalBuildInfo
-> IO ())
196 withAllComponentsInBuildOrder pkg lbi f
=
197 withAllTargetsInBuildOrder
' pkg lbi
$ \target
->
198 f
(targetComponent target
) (targetCLBI target
)
200 {-# DEPRECATED withComponentsInBuildOrder "You have got a 'TargetInfo' right? Use 'withNeededTargetsInBuildOrder' on the 'UnitId's you can 'nodeKey' out." #-}
201 withComponentsInBuildOrder
:: PackageDescription
-> LocalBuildInfo
203 -> (Component
-> ComponentLocalBuildInfo
-> IO ())
205 withComponentsInBuildOrder pkg lbi cnames f
=
206 withNeededTargetsInBuildOrder
' pkg lbi uids
$ \target
->
207 f
(targetComponent target
) (targetCLBI target
)
208 where uids
= concatMap (componentNameToUnitIds lbi
) cnames
210 allComponentsInBuildOrder
:: LocalBuildInfo
211 -> [ComponentLocalBuildInfo
]
212 allComponentsInBuildOrder lbi
=
213 Graph
.topSort
(componentGraph lbi
)
215 -- | Private helper function for some of the deprecated implementations.
216 componentNameToUnitIds
:: LocalBuildInfo
-> ComponentName
-> [UnitId
]
217 componentNameToUnitIds lbi cname
=
218 case Map
.lookup cname
(componentNameMap lbi
) of
219 Just clbis
-> map componentUnitId clbis
220 Nothing
-> error $ "componentNameToUnitIds " ++ display cname
222 {-# DEPRECATED componentsInBuildOrder "You've got 'TargetInfo' right? Use 'neededTargetsInBuildOrder' on the 'UnitId's you can 'nodeKey' out." #-}
223 componentsInBuildOrder
:: LocalBuildInfo
-> [ComponentName
]
224 -> [ComponentLocalBuildInfo
]
225 componentsInBuildOrder lbi cnames
226 -- NB: use of localPkgDescr here is safe because we throw out the
227 -- result immediately afterwards
228 = map targetCLBI
(neededTargetsInBuildOrder
' (localPkgDescr lbi
) lbi uids
)
229 where uids
= concatMap (componentNameToUnitIds lbi
) cnames
231 -- -----------------------------------------------------------------------------
232 -- A random function that has no business in this module
234 -- | Determine the directories containing the dynamic libraries of the
235 -- transitive dependencies of the component we are building.
237 -- When wanted, and possible, returns paths relative to the installDirs 'prefix'
238 depLibraryPaths
:: Bool -- ^ Building for inplace?
239 -> Bool -- ^ Generate prefix-relative library paths
241 -> ComponentLocalBuildInfo
-- ^ Component that is being built
242 -> NoCallStackIO
[FilePath]
243 depLibraryPaths inplace relative lbi clbi
= do
244 let pkgDescr
= localPkgDescr lbi
245 installDirs
= absoluteComponentInstallDirs pkgDescr lbi
(componentUnitId clbi
) NoCopyDest
246 executable = case clbi
of
247 ExeComponentLocalBuildInfo
{} -> True
249 relDir |
executable = bindir installDirs
250 |
otherwise = libdir installDirs
252 let -- TODO: this is kind of inefficient
254 |
(uid
, _
) <- componentPackageDeps clbi
255 -- Test that it's internal
256 , sub_target
<- allTargetsInBuildOrder
' pkgDescr lbi
257 , componentUnitId
(targetCLBI
(sub_target
)) == uid
]
258 internalLibs
= [ getLibDir
(targetCLBI sub_target
)
259 | sub_target
<- neededTargetsInBuildOrder
'
260 pkgDescr lbi internalDeps
]
262 -- This is better, but it doesn't work, because we may be passed a
263 -- CLBI which doesn't actually exist, and was faked up when we
264 -- were building a test suite/benchmark. See #3599 for proposal
266 let internalCLBIs = filter ((/= componentUnitId clbi) . componentUnitId)
268 $ neededTargetsInBuildOrder lbi [componentUnitId clbi]
269 internalLibs = map getLibDir internalCLBIs
272 | inplace
= componentBuildDir lbi sub_clbi
273 |
otherwise = dynlibdir
(absoluteComponentInstallDirs pkgDescr lbi
(componentUnitId sub_clbi
) NoCopyDest
)
275 -- Why do we go through all the trouble of a hand-crafting
276 -- internalLibs, when 'installedPkgs' actually contains the
277 -- internal libraries? The trouble is that 'installedPkgs'
278 -- may contain *inplace* entries, which we must NOT use for
279 -- not inplace 'depLibraryPaths' (e.g., for RPATH calculation).
280 -- See #4025 for more details. This is all horrible but it
281 -- is a moot point if you are using a per-component build,
282 -- because you never have any internal libraries in this case;
283 -- they're all external.
284 let external_ipkgs
= filter is_external
(allPackages
(installedPkgs lbi
))
285 is_external ipkg
= not (installedUnitId ipkg `
elem` internalDeps
)
286 -- First look for dynamic libraries in `dynamic-library-dirs`, and use
287 -- `library-dirs` as a fall back.
288 getDynDir pkg
= case Installed
.libraryDynDirs pkg
of
289 [] -> Installed
.libraryDirs pkg
291 allDepLibDirs
= concatMap getDynDir external_ipkgs
293 allDepLibDirs
' = internalLibs
++ allDepLibDirs
294 allDepLibDirsC
<- traverse canonicalizePathNoFail allDepLibDirs
'
296 let p
= prefix installDirs
297 prefixRelative l
= isJust (stripPrefix p l
)
300 prefixRelative relDir
= map (\l
->
302 then shortRelativePath relDir l
305 |
otherwise = allDepLibDirsC
309 -- 'canonicalizePath' fails on UNIX when the directory does not exists.
310 -- So just don't canonicalize when it doesn't exist.
311 canonicalizePathNoFail p
= do
312 exists
<- doesDirectoryExist p
314 then canonicalizePath p
317 -- | Get all module names that needed to be built by GHC; i.e., all
318 -- of these 'ModuleName's have interface files associated with them
319 -- that need to be installed.
320 allLibModules
:: Library
-> ComponentLocalBuildInfo
-> [ModuleName
]
321 allLibModules lib clbi
=
323 explicitLibModules lib
++
325 LibComponentLocalBuildInfo
{ componentInstantiatedWith
= insts
} -> map fst insts
328 -- -----------------------------------------------------------------------------
329 -- Wrappers for a couple functions from InstallDirs
331 -- | Backwards compatibility function which computes the InstallDirs
332 -- assuming that @$libname@ points to the public library (or some fake
333 -- package identifier if there is no public library.) IF AT ALL
334 -- POSSIBLE, please use 'absoluteComponentInstallDirs' instead.
335 absoluteInstallDirs
:: PackageDescription
-> LocalBuildInfo
337 -> InstallDirs
FilePath
338 absoluteInstallDirs pkg lbi copydest
=
339 absoluteComponentInstallDirs pkg lbi
(localUnitId lbi
) copydest
341 -- | See 'InstallDirs.absoluteInstallDirs'.
342 absoluteComponentInstallDirs
:: PackageDescription
-> LocalBuildInfo
345 -> InstallDirs
FilePath
346 absoluteComponentInstallDirs pkg lbi uid copydest
=
347 InstallDirs
.absoluteInstallDirs
350 (compilerInfo
(compiler lbi
))
353 (installDirTemplates lbi
)
355 -- | Backwards compatibility function which computes the InstallDirs
356 -- assuming that @$libname@ points to the public library (or some fake
357 -- package identifier if there is no public library.) IF AT ALL
358 -- POSSIBLE, please use 'prefixRelativeComponentInstallDirs' instead.
359 prefixRelativeInstallDirs
:: PackageId
-> LocalBuildInfo
360 -> InstallDirs
(Maybe FilePath)
361 prefixRelativeInstallDirs pkg_descr lbi
=
362 prefixRelativeComponentInstallDirs pkg_descr lbi
(localUnitId lbi
)
364 -- |See 'InstallDirs.prefixRelativeInstallDirs'
365 prefixRelativeComponentInstallDirs
:: PackageId
-> LocalBuildInfo
367 -> InstallDirs
(Maybe FilePath)
368 prefixRelativeComponentInstallDirs pkg_descr lbi uid
=
369 InstallDirs
.prefixRelativeInstallDirs
370 (packageId pkg_descr
)
372 (compilerInfo
(compiler lbi
))
374 (installDirTemplates lbi
)
376 substPathTemplate
:: PackageId
-> LocalBuildInfo
378 -> PathTemplate
-> FilePath
379 substPathTemplate pkgid lbi uid
= fromPathTemplate
380 . ( InstallDirs
.substPathTemplate env
)
381 where env
= initialPathTemplateEnv
384 (compilerInfo
(compiler lbi
))