PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/main/Packages.lhs

http://github.com/ghc/ghc
Haskell | 1076 lines | 644 code | 154 blank | 278 comment | 19 complexity | 87391a7e50ef176534525b9ad2c79cb6 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, GPL-3.0
  1. %
  2. % (c) The University of Glasgow, 2006
  3. %
  4. \begin{code}
  5. -- | Package manipulation
  6. module Packages (
  7. module PackageConfig,
  8. -- * The PackageConfigMap
  9. PackageConfigMap, emptyPackageConfigMap, lookupPackage,
  10. extendPackageConfigMap, dumpPackages,
  11. -- * Reading the package config, and processing cmdline args
  12. PackageState(..),
  13. initPackages,
  14. getPackageDetails,
  15. lookupModuleInAllPackages, lookupModuleWithSuggestions,
  16. -- * Inspecting the set of packages in scope
  17. getPackageIncludePath,
  18. getPackageLibraryPath,
  19. getPackageLinkOpts,
  20. getPackageExtraCcOpts,
  21. getPackageFrameworkPath,
  22. getPackageFrameworks,
  23. getPreloadPackagesAnd,
  24. collectIncludeDirs, collectLibraryPaths, collectLinkOpts,
  25. packageHsLibs,
  26. -- * Utils
  27. isDllName
  28. )
  29. where
  30. #include "HsVersions.h"
  31. import PackageConfig
  32. import DynFlags
  33. import Config ( cProjectVersion )
  34. import Name ( Name, nameModule_maybe )
  35. import UniqFM
  36. import Module
  37. import Util
  38. import Panic
  39. import Outputable
  40. import Maybes
  41. import System.Environment ( getEnv )
  42. import Distribution.InstalledPackageInfo
  43. import Distribution.InstalledPackageInfo.Binary
  44. import Distribution.Package hiding (PackageId,depends)
  45. import FastString
  46. import ErrUtils ( debugTraceMsg, putMsg, MsgDoc )
  47. import Exception
  48. import System.Directory
  49. import System.FilePath as FilePath
  50. import qualified System.FilePath.Posix as FilePath.Posix
  51. import Control.Monad
  52. import Data.Char (isSpace)
  53. import Data.List as List
  54. import Data.Map (Map)
  55. import qualified Data.Map as Map
  56. import qualified FiniteMap as Map
  57. import qualified Data.Set as Set
  58. -- ---------------------------------------------------------------------------
  59. -- The Package state
  60. -- | Package state is all stored in 'DynFlags', including the details of
  61. -- all packages, which packages are exposed, and which modules they
  62. -- provide.
  63. --
  64. -- The package state is computed by 'initPackages', and kept in DynFlags.
  65. --
  66. -- * @-package <pkg>@ causes @<pkg>@ to become exposed, and all other packages
  67. -- with the same name to become hidden.
  68. --
  69. -- * @-hide-package <pkg>@ causes @<pkg>@ to become hidden.
  70. --
  71. -- * Let @exposedPackages@ be the set of packages thus exposed.
  72. -- Let @depExposedPackages@ be the transitive closure from @exposedPackages@ of
  73. -- their dependencies.
  74. --
  75. -- * When searching for a module from an preload import declaration,
  76. -- only the exposed modules in @exposedPackages@ are valid.
  77. --
  78. -- * When searching for a module from an implicit import, all modules
  79. -- from @depExposedPackages@ are valid.
  80. --
  81. -- * When linking in a compilation manager mode, we link in packages the
  82. -- program depends on (the compiler knows this list by the
  83. -- time it gets to the link step). Also, we link in all packages
  84. -- which were mentioned with preload @-package@ flags on the command-line,
  85. -- or are a transitive dependency of same, or are \"base\"\/\"rts\".
  86. -- The reason for this is that we might need packages which don't
  87. -- contain any Haskell modules, and therefore won't be discovered
  88. -- by the normal mechanism of dependency tracking.
  89. -- Notes on DLLs
  90. -- ~~~~~~~~~~~~~
  91. -- When compiling module A, which imports module B, we need to
  92. -- know whether B will be in the same DLL as A.
  93. -- If it's in the same DLL, we refer to B_f_closure
  94. -- If it isn't, we refer to _imp__B_f_closure
  95. -- When compiling A, we record in B's Module value whether it's
  96. -- in a different DLL, by setting the DLL flag.
  97. data PackageState = PackageState {
  98. pkgIdMap :: PackageConfigMap, -- PackageId -> PackageConfig
  99. -- The exposed flags are adjusted according to -package and
  100. -- -hide-package flags, and -ignore-package removes packages.
  101. preloadPackages :: [PackageId],
  102. -- The packages we're going to link in eagerly. This list
  103. -- should be in reverse dependency order; that is, a package
  104. -- is always mentioned before the packages it depends on.
  105. moduleToPkgConfAll :: UniqFM [(PackageConfig,Bool)], -- ModuleEnv mapping
  106. -- Derived from pkgIdMap.
  107. -- Maps Module to (pkgconf,exposed), where pkgconf is the
  108. -- PackageConfig for the package containing the module, and
  109. -- exposed is True if the package exposes that module.
  110. installedPackageIdMap :: InstalledPackageIdMap
  111. }
  112. -- | A PackageConfigMap maps a 'PackageId' to a 'PackageConfig'
  113. type PackageConfigMap = UniqFM PackageConfig
  114. type InstalledPackageIdMap = Map InstalledPackageId PackageId
  115. type InstalledPackageIndex = Map InstalledPackageId PackageConfig
  116. emptyPackageConfigMap :: PackageConfigMap
  117. emptyPackageConfigMap = emptyUFM
  118. -- | Find the package we know about with the given id (e.g. \"foo-1.0\"), if any
  119. lookupPackage :: PackageConfigMap -> PackageId -> Maybe PackageConfig
  120. lookupPackage = lookupUFM
  121. extendPackageConfigMap
  122. :: PackageConfigMap -> [PackageConfig] -> PackageConfigMap
  123. extendPackageConfigMap pkg_map new_pkgs
  124. = foldl add pkg_map new_pkgs
  125. where add pkg_map p = addToUFM pkg_map (packageConfigId p) p
  126. -- | Looks up the package with the given id in the package state, panicing if it is
  127. -- not found
  128. getPackageDetails :: PackageState -> PackageId -> PackageConfig
  129. getPackageDetails ps pid = expectJust "getPackageDetails" (lookupPackage (pkgIdMap ps) pid)
  130. -- ----------------------------------------------------------------------------
  131. -- Loading the package db files and building up the package state
  132. -- | Call this after 'DynFlags.parseDynFlags'. It reads the package
  133. -- database files, and sets up various internal tables of package
  134. -- information, according to the package-related flags on the
  135. -- command-line (@-package@, @-hide-package@ etc.)
  136. --
  137. -- Returns a list of packages to link in if we're doing dynamic linking.
  138. -- This list contains the packages that the user explicitly mentioned with
  139. -- @-package@ flags.
  140. --
  141. -- 'initPackages' can be called again subsequently after updating the
  142. -- 'packageFlags' field of the 'DynFlags', and it will update the
  143. -- 'pkgState' in 'DynFlags' and return a list of packages to
  144. -- link in.
  145. initPackages :: DynFlags -> IO (DynFlags, [PackageId])
  146. initPackages dflags = do
  147. pkg_db <- case pkgDatabase dflags of
  148. Nothing -> readPackageConfigs dflags
  149. Just db -> return $ setBatchPackageFlags dflags db
  150. (pkg_state, preload, this_pkg)
  151. <- mkPackageState dflags pkg_db [] (thisPackage dflags)
  152. return (dflags{ pkgDatabase = Just pkg_db,
  153. pkgState = pkg_state,
  154. thisPackage = this_pkg },
  155. preload)
  156. -- -----------------------------------------------------------------------------
  157. -- Reading the package database(s)
  158. readPackageConfigs :: DynFlags -> IO [PackageConfig]
  159. readPackageConfigs dflags = do
  160. let system_conf_refs = [UserPkgConf, GlobalPkgConf]
  161. e_pkg_path <- tryIO (getEnv "GHC_PACKAGE_PATH")
  162. let base_conf_refs = case e_pkg_path of
  163. Left _ -> system_conf_refs
  164. Right path
  165. | null (last cs)
  166. -> map PkgConfFile (init cs) ++ system_conf_refs
  167. | otherwise
  168. -> map PkgConfFile cs
  169. where cs = parseSearchPath path
  170. -- if the path ends in a separator (eg. "/foo/bar:")
  171. -- then we tack on the system paths.
  172. let conf_refs = reverse (extraPkgConfs dflags base_conf_refs)
  173. -- later packages shadow earlier ones. extraPkgConfs
  174. -- is in the opposite order to the flags on the
  175. -- command line.
  176. confs <- liftM catMaybes $ mapM (resolvePackageConfig dflags) conf_refs
  177. liftM concat $ mapM (readPackageConfig dflags) confs
  178. resolvePackageConfig :: DynFlags -> PkgConfRef -> IO (Maybe FilePath)
  179. resolvePackageConfig dflags GlobalPkgConf = return $ Just (systemPackageConfig dflags)
  180. resolvePackageConfig _ UserPkgConf = handleIO (\_ -> return Nothing) $ do
  181. appdir <- getAppUserDataDirectory "ghc"
  182. let dir = appdir </> (TARGET_ARCH ++ '-':TARGET_OS ++ '-':cProjectVersion)
  183. pkgconf = dir </> "package.conf.d"
  184. exist <- doesDirectoryExist pkgconf
  185. return $ if exist then Just pkgconf else Nothing
  186. resolvePackageConfig _ (PkgConfFile name) = return $ Just name
  187. readPackageConfig :: DynFlags -> FilePath -> IO [PackageConfig]
  188. readPackageConfig dflags conf_file = do
  189. isdir <- doesDirectoryExist conf_file
  190. proto_pkg_configs <-
  191. if isdir
  192. then do let filename = conf_file </> "package.cache"
  193. debugTraceMsg dflags 2 (text "Using binary package database:" <+> text filename)
  194. conf <- readBinPackageDB filename
  195. return (map installedPackageInfoToPackageConfig conf)
  196. else do
  197. isfile <- doesFileExist conf_file
  198. when (not isfile) $
  199. throwGhcExceptionIO $ InstallationError $
  200. "can't find a package database at " ++ conf_file
  201. debugTraceMsg dflags 2 (text "Using package config file:" <+> text conf_file)
  202. str <- readFile conf_file
  203. case reads str of
  204. [(configs, rest)]
  205. | all isSpace rest -> return (map installedPackageInfoToPackageConfig configs)
  206. _ -> throwGhcExceptionIO $ InstallationError $
  207. "invalid package database file " ++ conf_file
  208. let
  209. top_dir = topDir dflags
  210. pkgroot = takeDirectory conf_file
  211. pkg_configs1 = map (mungePackagePaths top_dir pkgroot) proto_pkg_configs
  212. pkg_configs2 = setBatchPackageFlags dflags pkg_configs1
  213. --
  214. return pkg_configs2
  215. setBatchPackageFlags :: DynFlags -> [PackageConfig] -> [PackageConfig]
  216. setBatchPackageFlags dflags pkgs = (maybeDistrustAll . maybeHideAll) pkgs
  217. where
  218. maybeHideAll pkgs'
  219. | gopt Opt_HideAllPackages dflags = map hide pkgs'
  220. | otherwise = pkgs'
  221. maybeDistrustAll pkgs'
  222. | gopt Opt_DistrustAllPackages dflags = map distrust pkgs'
  223. | otherwise = pkgs'
  224. hide pkg = pkg{ exposed = False }
  225. distrust pkg = pkg{ trusted = False }
  226. -- TODO: This code is duplicated in utils/ghc-pkg/Main.hs
  227. mungePackagePaths :: FilePath -> FilePath -> PackageConfig -> PackageConfig
  228. -- Perform path/URL variable substitution as per the Cabal ${pkgroot} spec
  229. -- (http://www.haskell.org/pipermail/libraries/2009-May/011772.html)
  230. -- Paths/URLs can be relative to ${pkgroot} or ${pkgrooturl}.
  231. -- The "pkgroot" is the directory containing the package database.
  232. --
  233. -- Also perform a similar substitution for the older GHC-specific
  234. -- "$topdir" variable. The "topdir" is the location of the ghc
  235. -- installation (obtained from the -B option).
  236. mungePackagePaths top_dir pkgroot pkg =
  237. pkg {
  238. importDirs = munge_paths (importDirs pkg),
  239. includeDirs = munge_paths (includeDirs pkg),
  240. libraryDirs = munge_paths (libraryDirs pkg),
  241. frameworkDirs = munge_paths (frameworkDirs pkg),
  242. haddockInterfaces = munge_paths (haddockInterfaces pkg),
  243. haddockHTMLs = munge_urls (haddockHTMLs pkg)
  244. }
  245. where
  246. munge_paths = map munge_path
  247. munge_urls = map munge_url
  248. munge_path p
  249. | Just p' <- stripVarPrefix "${pkgroot}" p = pkgroot ++ p'
  250. | Just p' <- stripVarPrefix "$topdir" p = top_dir ++ p'
  251. | otherwise = p
  252. munge_url p
  253. | Just p' <- stripVarPrefix "${pkgrooturl}" p = toUrlPath pkgroot p'
  254. | Just p' <- stripVarPrefix "$httptopdir" p = toUrlPath top_dir p'
  255. | otherwise = p
  256. toUrlPath r p = "file:///"
  257. -- URLs always use posix style '/' separators:
  258. ++ FilePath.Posix.joinPath
  259. (r : -- We need to drop a leading "/" or "\\"
  260. -- if there is one:
  261. dropWhile (all isPathSeparator)
  262. (FilePath.splitDirectories p))
  263. -- We could drop the separator here, and then use </> above. However,
  264. -- by leaving it in and using ++ we keep the same path separator
  265. -- rather than letting FilePath change it to use \ as the separator
  266. stripVarPrefix var path = case stripPrefix var path of
  267. Just [] -> Just []
  268. Just cs@(c : _) | isPathSeparator c -> Just cs
  269. _ -> Nothing
  270. -- -----------------------------------------------------------------------------
  271. -- Modify our copy of the package database based on a package flag
  272. -- (-package, -hide-package, -ignore-package).
  273. applyPackageFlag
  274. :: DynFlags
  275. -> UnusablePackages
  276. -> [PackageConfig] -- Initial database
  277. -> PackageFlag -- flag to apply
  278. -> IO [PackageConfig] -- new database
  279. applyPackageFlag dflags unusable pkgs flag =
  280. case flag of
  281. ExposePackage str ->
  282. case selectPackages (matchingStr str) pkgs unusable of
  283. Left ps -> packageFlagErr dflags flag ps
  284. Right (p:ps,qs) -> return (p':ps')
  285. where p' = p {exposed=True}
  286. ps' = hideAll (pkgName (sourcePackageId p)) (ps++qs)
  287. _ -> panic "applyPackageFlag"
  288. ExposePackageId str ->
  289. case selectPackages (matchingId str) pkgs unusable of
  290. Left ps -> packageFlagErr dflags flag ps
  291. Right (p:ps,qs) -> return (p':ps')
  292. where p' = p {exposed=True}
  293. ps' = hideAll (pkgName (sourcePackageId p)) (ps++qs)
  294. _ -> panic "applyPackageFlag"
  295. HidePackage str ->
  296. case selectPackages (matchingStr str) pkgs unusable of
  297. Left ps -> packageFlagErr dflags flag ps
  298. Right (ps,qs) -> return (map hide ps ++ qs)
  299. where hide p = p {exposed=False}
  300. -- we trust all matching packages. Maybe should only trust first one?
  301. -- and leave others the same or set them untrusted
  302. TrustPackage str ->
  303. case selectPackages (matchingStr str) pkgs unusable of
  304. Left ps -> packageFlagErr dflags flag ps
  305. Right (ps,qs) -> return (map trust ps ++ qs)
  306. where trust p = p {trusted=True}
  307. DistrustPackage str ->
  308. case selectPackages (matchingStr str) pkgs unusable of
  309. Left ps -> packageFlagErr dflags flag ps
  310. Right (ps,qs) -> return (map distrust ps ++ qs)
  311. where distrust p = p {trusted=False}
  312. _ -> panic "applyPackageFlag"
  313. where
  314. -- When a package is requested to be exposed, we hide all other
  315. -- packages with the same name.
  316. hideAll name ps = map maybe_hide ps
  317. where maybe_hide p
  318. | pkgName (sourcePackageId p) == name = p {exposed=False}
  319. | otherwise = p
  320. selectPackages :: (PackageConfig -> Bool) -> [PackageConfig]
  321. -> UnusablePackages
  322. -> Either [(PackageConfig, UnusablePackageReason)]
  323. ([PackageConfig], [PackageConfig])
  324. selectPackages matches pkgs unusable
  325. = let
  326. (ps,rest) = partition matches pkgs
  327. reasons = [ (p, Map.lookup (installedPackageId p) unusable)
  328. | p <- ps ]
  329. in
  330. if all (isJust.snd) reasons
  331. then Left [ (p, reason) | (p,Just reason) <- reasons ]
  332. else Right (sortByVersion [ p | (p,Nothing) <- reasons ], rest)
  333. -- A package named on the command line can either include the
  334. -- version, or just the name if it is unambiguous.
  335. matchingStr :: String -> PackageConfig -> Bool
  336. matchingStr str p
  337. = str == display (sourcePackageId p)
  338. || str == display (pkgName (sourcePackageId p))
  339. matchingId :: String -> PackageConfig -> Bool
  340. matchingId str p = InstalledPackageId str == installedPackageId p
  341. sortByVersion :: [InstalledPackageInfo_ m] -> [InstalledPackageInfo_ m]
  342. sortByVersion = sortBy (flip (comparing (pkgVersion.sourcePackageId)))
  343. comparing :: Ord a => (t -> a) -> t -> t -> Ordering
  344. comparing f a b = f a `compare` f b
  345. packageFlagErr :: DynFlags
  346. -> PackageFlag
  347. -> [(PackageConfig, UnusablePackageReason)]
  348. -> IO a
  349. -- for missing DPH package we emit a more helpful error message, because
  350. -- this may be the result of using -fdph-par or -fdph-seq.
  351. packageFlagErr dflags (ExposePackage pkg) [] | is_dph_package pkg
  352. = throwGhcExceptionIO (CmdLineError (showSDoc dflags $ dph_err))
  353. where dph_err = text "the " <> text pkg <> text " package is not installed."
  354. $$ text "To install it: \"cabal install dph\"."
  355. is_dph_package pkg = "dph" `isPrefixOf` pkg
  356. packageFlagErr dflags flag reasons
  357. = throwGhcExceptionIO (CmdLineError (showSDoc dflags $ err))
  358. where err = text "cannot satisfy " <> ppr_flag <>
  359. (if null reasons then empty else text ": ") $$
  360. nest 4 (ppr_reasons $$
  361. text "(use -v for more information)")
  362. ppr_flag = case flag of
  363. IgnorePackage p -> text "-ignore-package " <> text p
  364. HidePackage p -> text "-hide-package " <> text p
  365. ExposePackage p -> text "-package " <> text p
  366. ExposePackageId p -> text "-package-id " <> text p
  367. TrustPackage p -> text "-trust " <> text p
  368. DistrustPackage p -> text "-distrust " <> text p
  369. ppr_reasons = vcat (map ppr_reason reasons)
  370. ppr_reason (p, reason) = pprReason (pprIPkg p <+> text "is") reason
  371. -- -----------------------------------------------------------------------------
  372. -- Hide old versions of packages
  373. --
  374. -- hide all packages for which there is also a later version
  375. -- that is already exposed. This just makes it non-fatal to have two
  376. -- versions of a package exposed, which can happen if you install a
  377. -- later version of a package in the user database, for example.
  378. --
  379. hideOldPackages :: DynFlags -> [PackageConfig] -> IO [PackageConfig]
  380. hideOldPackages dflags pkgs = mapM maybe_hide pkgs
  381. where maybe_hide p
  382. | not (exposed p) = return p
  383. | (p' : _) <- later_versions = do
  384. debugTraceMsg dflags 2 $
  385. (ptext (sLit "hiding package") <+> pprSPkg p <+>
  386. ptext (sLit "to avoid conflict with later version") <+>
  387. pprSPkg p')
  388. return (p {exposed=False})
  389. | otherwise = return p
  390. where myname = pkgName (sourcePackageId p)
  391. myversion = pkgVersion (sourcePackageId p)
  392. later_versions = [ p | p <- pkgs, exposed p,
  393. let pkg = sourcePackageId p,
  394. pkgName pkg == myname,
  395. pkgVersion pkg > myversion ]
  396. -- -----------------------------------------------------------------------------
  397. -- Wired-in packages
  398. findWiredInPackages
  399. :: DynFlags
  400. -> [PackageConfig] -- database
  401. -> IO [PackageConfig]
  402. findWiredInPackages dflags pkgs = do
  403. --
  404. -- Now we must find our wired-in packages, and rename them to
  405. -- their canonical names (eg. base-1.0 ==> base).
  406. --
  407. let
  408. wired_in_pkgids :: [String]
  409. wired_in_pkgids = map packageIdString
  410. [ primPackageId,
  411. integerPackageId,
  412. basePackageId,
  413. rtsPackageId,
  414. thPackageId,
  415. dphSeqPackageId,
  416. dphParPackageId ]
  417. matches :: PackageConfig -> String -> Bool
  418. pc `matches` pid = display (pkgName (sourcePackageId pc)) == pid
  419. -- find which package corresponds to each wired-in package
  420. -- delete any other packages with the same name
  421. -- update the package and any dependencies to point to the new
  422. -- one.
  423. --
  424. -- When choosing which package to map to a wired-in package
  425. -- name, we prefer exposed packages, and pick the latest
  426. -- version. To override the default choice, -hide-package
  427. -- could be used to hide newer versions.
  428. --
  429. findWiredInPackage :: [PackageConfig] -> String
  430. -> IO (Maybe InstalledPackageId)
  431. findWiredInPackage pkgs wired_pkg =
  432. let all_ps = [ p | p <- pkgs, p `matches` wired_pkg ] in
  433. case all_ps of
  434. [] -> notfound
  435. many -> pick (head (sortByVersion many))
  436. where
  437. notfound = do
  438. debugTraceMsg dflags 2 $
  439. ptext (sLit "wired-in package ")
  440. <> text wired_pkg
  441. <> ptext (sLit " not found.")
  442. return Nothing
  443. pick :: InstalledPackageInfo_ ModuleName
  444. -> IO (Maybe InstalledPackageId)
  445. pick pkg = do
  446. debugTraceMsg dflags 2 $
  447. ptext (sLit "wired-in package ")
  448. <> text wired_pkg
  449. <> ptext (sLit " mapped to ")
  450. <> pprIPkg pkg
  451. return (Just (installedPackageId pkg))
  452. mb_wired_in_ids <- mapM (findWiredInPackage pkgs) wired_in_pkgids
  453. let
  454. wired_in_ids = catMaybes mb_wired_in_ids
  455. -- this is old: we used to assume that if there were
  456. -- multiple versions of wired-in packages installed that
  457. -- they were mutually exclusive. Now we're assuming that
  458. -- you have one "main" version of each wired-in package
  459. -- (the latest version), and the others are backward-compat
  460. -- wrappers that depend on this one. e.g. base-4.0 is the
  461. -- latest, base-3.0 is a compat wrapper depending on base-4.0.
  462. {-
  463. deleteOtherWiredInPackages pkgs = filterOut bad pkgs
  464. where bad p = any (p `matches`) wired_in_pkgids
  465. && package p `notElem` map fst wired_in_ids
  466. -}
  467. updateWiredInDependencies pkgs = map upd_pkg pkgs
  468. where upd_pkg p
  469. | installedPackageId p `elem` wired_in_ids
  470. = p { sourcePackageId = (sourcePackageId p){ pkgVersion = Version [] [] } }
  471. | otherwise
  472. = p
  473. return $ updateWiredInDependencies pkgs
  474. -- ----------------------------------------------------------------------------
  475. data UnusablePackageReason
  476. = IgnoredWithFlag
  477. | MissingDependencies [InstalledPackageId]
  478. | ShadowedBy InstalledPackageId
  479. type UnusablePackages = Map InstalledPackageId UnusablePackageReason
  480. pprReason :: SDoc -> UnusablePackageReason -> SDoc
  481. pprReason pref reason = case reason of
  482. IgnoredWithFlag ->
  483. pref <+> ptext (sLit "ignored due to an -ignore-package flag")
  484. MissingDependencies deps ->
  485. pref <+>
  486. ptext (sLit "unusable due to missing or recursive dependencies:") $$
  487. nest 2 (hsep (map (text.display) deps))
  488. ShadowedBy ipid ->
  489. pref <+> ptext (sLit "shadowed by package ") <> text (display ipid)
  490. reportUnusable :: DynFlags -> UnusablePackages -> IO ()
  491. reportUnusable dflags pkgs = mapM_ report (Map.toList pkgs)
  492. where
  493. report (ipid, reason) =
  494. debugTraceMsg dflags 2 $
  495. pprReason
  496. (ptext (sLit "package") <+>
  497. text (display ipid) <+> text "is") reason
  498. -- ----------------------------------------------------------------------------
  499. --
  500. -- Detect any packages that have missing dependencies, and also any
  501. -- mutually-recursive groups of packages (loops in the package graph
  502. -- are not allowed). We do this by taking the least fixpoint of the
  503. -- dependency graph, repeatedly adding packages whose dependencies are
  504. -- satisfied until no more can be added.
  505. --
  506. findBroken :: [PackageConfig] -> UnusablePackages
  507. findBroken pkgs = go [] Map.empty pkgs
  508. where
  509. go avail ipids not_avail =
  510. case partitionWith (depsAvailable ipids) not_avail of
  511. ([], not_avail) ->
  512. Map.fromList [ (installedPackageId p, MissingDependencies deps)
  513. | (p,deps) <- not_avail ]
  514. (new_avail, not_avail) ->
  515. go (new_avail ++ avail) new_ipids (map fst not_avail)
  516. where new_ipids = Map.insertList
  517. [ (installedPackageId p, p) | p <- new_avail ]
  518. ipids
  519. depsAvailable :: InstalledPackageIndex
  520. -> PackageConfig
  521. -> Either PackageConfig (PackageConfig, [InstalledPackageId])
  522. depsAvailable ipids pkg
  523. | null dangling = Left pkg
  524. | otherwise = Right (pkg, dangling)
  525. where dangling = filter (not . (`Map.member` ipids)) (depends pkg)
  526. -- -----------------------------------------------------------------------------
  527. -- Eliminate shadowed packages, giving the user some feedback
  528. -- later packages in the list should shadow earlier ones with the same
  529. -- package name/version. Additionally, a package may be preferred if
  530. -- it is in the transitive closure of packages selected using -package-id
  531. -- flags.
  532. shadowPackages :: [PackageConfig] -> [InstalledPackageId] -> UnusablePackages
  533. shadowPackages pkgs preferred
  534. = let (shadowed,_) = foldl check ([],emptyUFM) pkgs
  535. in Map.fromList shadowed
  536. where
  537. check (shadowed,pkgmap) pkg
  538. | Just oldpkg <- lookupUFM pkgmap (packageConfigId pkg)
  539. , let
  540. ipid_new = installedPackageId pkg
  541. ipid_old = installedPackageId oldpkg
  542. --
  543. , ipid_old /= ipid_new
  544. = if ipid_old `elem` preferred
  545. then ( (ipid_new, ShadowedBy ipid_old) : shadowed, pkgmap )
  546. else ( (ipid_old, ShadowedBy ipid_new) : shadowed, pkgmap' )
  547. | otherwise
  548. = (shadowed, pkgmap')
  549. where
  550. pkgmap' = addToUFM pkgmap (packageConfigId pkg) pkg
  551. -- -----------------------------------------------------------------------------
  552. ignorePackages :: [PackageFlag] -> [PackageConfig] -> UnusablePackages
  553. ignorePackages flags pkgs = Map.fromList (concatMap doit flags)
  554. where
  555. doit (IgnorePackage str) =
  556. case partition (matchingStr str) pkgs of
  557. (ps, _) -> [ (installedPackageId p, IgnoredWithFlag)
  558. | p <- ps ]
  559. -- missing package is not an error for -ignore-package,
  560. -- because a common usage is to -ignore-package P as
  561. -- a preventative measure just in case P exists.
  562. doit _ = panic "ignorePackages"
  563. -- -----------------------------------------------------------------------------
  564. depClosure :: InstalledPackageIndex
  565. -> [InstalledPackageId]
  566. -> [InstalledPackageId]
  567. depClosure index ipids = closure Map.empty ipids
  568. where
  569. closure set [] = Map.keys set
  570. closure set (ipid : ipids)
  571. | ipid `Map.member` set = closure set ipids
  572. | Just p <- Map.lookup ipid index = closure (Map.insert ipid p set)
  573. (depends p ++ ipids)
  574. | otherwise = closure set ipids
  575. -- -----------------------------------------------------------------------------
  576. -- When all the command-line options are in, we can process our package
  577. -- settings and populate the package state.
  578. mkPackageState
  579. :: DynFlags
  580. -> [PackageConfig] -- initial database
  581. -> [PackageId] -- preloaded packages
  582. -> PackageId -- this package
  583. -> IO (PackageState,
  584. [PackageId], -- new packages to preload
  585. PackageId) -- this package, might be modified if the current
  586. -- package is a wired-in package.
  587. mkPackageState dflags pkgs0 preload0 this_package = do
  588. {-
  589. Plan.
  590. 1. P = transitive closure of packages selected by -package-id
  591. 2. Apply shadowing. When there are multiple packages with the same
  592. sourcePackageId,
  593. * if one is in P, use that one
  594. * otherwise, use the one highest in the package stack
  595. [
  596. rationale: we cannot use two packages with the same sourcePackageId
  597. in the same program, because sourcePackageId is the symbol prefix.
  598. Hence we must select a consistent set of packages to use. We have
  599. a default algorithm for doing this: packages higher in the stack
  600. shadow those lower down. This default algorithm can be overriden
  601. by giving explicit -package-id flags; then we have to take these
  602. preferences into account when selecting which other packages are
  603. made available.
  604. Our simple algorithm throws away some solutions: there may be other
  605. consistent sets that would satisfy the -package flags, but it's
  606. not GHC's job to be doing constraint solving.
  607. ]
  608. 3. remove packages selected by -ignore-package
  609. 4. remove any packages with missing dependencies, or mutually recursive
  610. dependencies.
  611. 5. report (with -v) any packages that were removed by steps 2-4
  612. 6. apply flags to set exposed/hidden on the resulting packages
  613. - if any flag refers to a package which was removed by 2-4, then
  614. we can give an error message explaining why
  615. 7. hide any packages which are superseded by later exposed packages
  616. -}
  617. let
  618. flags = reverse (packageFlags dflags)
  619. -- pkgs0 with duplicate packages filtered out. This is
  620. -- important: it is possible for a package in the global package
  621. -- DB to have the same IPID as a package in the user DB, and
  622. -- we want the latter to take precedence. This is not the same
  623. -- as shadowing (below), since in this case the two packages
  624. -- have the same ABI and are interchangeable.
  625. --
  626. -- #4072: note that we must retain the ordering of the list here
  627. -- so that shadowing behaves as expected when we apply it later.
  628. pkgs0_unique = snd $ foldr del (Set.empty,[]) pkgs0
  629. where del p (s,ps)
  630. | pid `Set.member` s = (s,ps)
  631. | otherwise = (Set.insert pid s, p:ps)
  632. where pid = installedPackageId p
  633. -- XXX this is just a variant of nub
  634. ipid_map = Map.fromList [ (installedPackageId p, p) | p <- pkgs0 ]
  635. ipid_selected = depClosure ipid_map [ InstalledPackageId i
  636. | ExposePackageId i <- flags ]
  637. (ignore_flags, other_flags) = partition is_ignore flags
  638. is_ignore IgnorePackage{} = True
  639. is_ignore _ = False
  640. shadowed = shadowPackages pkgs0_unique ipid_selected
  641. ignored = ignorePackages ignore_flags pkgs0_unique
  642. pkgs0' = filter (not . (`Map.member` (Map.union shadowed ignored)) . installedPackageId) pkgs0_unique
  643. broken = findBroken pkgs0'
  644. unusable = shadowed `Map.union` ignored `Map.union` broken
  645. reportUnusable dflags unusable
  646. --
  647. -- Modify the package database according to the command-line flags
  648. -- (-package, -hide-package, -ignore-package, -hide-all-packages).
  649. --
  650. pkgs1 <- foldM (applyPackageFlag dflags unusable) pkgs0_unique other_flags
  651. let pkgs2 = filter (not . (`Map.member` unusable) . installedPackageId) pkgs1
  652. -- Here we build up a set of the packages mentioned in -package
  653. -- flags on the command line; these are called the "preload"
  654. -- packages. we link these packages in eagerly. The preload set
  655. -- should contain at least rts & base, which is why we pretend that
  656. -- the command line contains -package rts & -package base.
  657. --
  658. let preload1 = [ installedPackageId p | f <- flags, p <- get_exposed f ]
  659. get_exposed (ExposePackage s)
  660. = take 1 $ sortByVersion (filter (matchingStr s) pkgs2)
  661. -- -package P means "the latest version of P" (#7030)
  662. get_exposed (ExposePackageId s) = filter (matchingId s) pkgs2
  663. get_exposed _ = []
  664. -- hide packages that are subsumed by later versions
  665. pkgs3 <- hideOldPackages dflags pkgs2
  666. -- sort out which packages are wired in
  667. pkgs4 <- findWiredInPackages dflags pkgs3
  668. let pkg_db = extendPackageConfigMap emptyPackageConfigMap pkgs4
  669. ipid_map = Map.fromList [ (installedPackageId p, packageConfigId p)
  670. | p <- pkgs4 ]
  671. lookupIPID ipid@(InstalledPackageId str)
  672. | Just pid <- Map.lookup ipid ipid_map = return pid
  673. | otherwise = missingPackageErr dflags str
  674. preload2 <- mapM lookupIPID preload1
  675. let
  676. -- add base & rts to the preload packages
  677. basicLinkedPackages
  678. | gopt Opt_AutoLinkPackages dflags
  679. = filter (flip elemUFM pkg_db) [basePackageId, rtsPackageId]
  680. | otherwise = []
  681. -- but in any case remove the current package from the set of
  682. -- preloaded packages so that base/rts does not end up in the
  683. -- set up preloaded package when we are just building it
  684. preload3 = nub $ filter (/= this_package)
  685. $ (basicLinkedPackages ++ preload2)
  686. -- Close the preload packages with their dependencies
  687. dep_preload <- closeDeps dflags pkg_db ipid_map (zip preload3 (repeat Nothing))
  688. let new_dep_preload = filter (`notElem` preload0) dep_preload
  689. let pstate = PackageState{ preloadPackages = dep_preload,
  690. pkgIdMap = pkg_db,
  691. moduleToPkgConfAll = mkModuleMap pkg_db,
  692. installedPackageIdMap = ipid_map
  693. }
  694. return (pstate, new_dep_preload, this_package)
  695. -- -----------------------------------------------------------------------------
  696. -- Make the mapping from module to package info
  697. mkModuleMap
  698. :: PackageConfigMap
  699. -> UniqFM [(PackageConfig, Bool)]
  700. mkModuleMap pkg_db = foldr extend_modmap emptyUFM pkgids
  701. where
  702. pkgids = map packageConfigId (eltsUFM pkg_db)
  703. extend_modmap pkgid modmap =
  704. addListToUFM_C (++) modmap
  705. ([(m, [(pkg, True)]) | m <- exposed_mods] ++
  706. [(m, [(pkg, False)]) | m <- hidden_mods])
  707. where
  708. pkg = expectJust "mkModuleMap" (lookupPackage pkg_db pkgid)
  709. exposed_mods = exposedModules pkg
  710. hidden_mods = hiddenModules pkg
  711. pprSPkg :: PackageConfig -> SDoc
  712. pprSPkg p = text (display (sourcePackageId p))
  713. pprIPkg :: PackageConfig -> SDoc
  714. pprIPkg p = text (display (installedPackageId p))
  715. -- -----------------------------------------------------------------------------
  716. -- Extracting information from the packages in scope
  717. -- Many of these functions take a list of packages: in those cases,
  718. -- the list is expected to contain the "dependent packages",
  719. -- i.e. those packages that were found to be depended on by the
  720. -- current module/program. These can be auto or non-auto packages, it
  721. -- doesn't really matter. The list is always combined with the list
  722. -- of preload (command-line) packages to determine which packages to
  723. -- use.
  724. -- | Find all the include directories in these and the preload packages
  725. getPackageIncludePath :: DynFlags -> [PackageId] -> IO [String]
  726. getPackageIncludePath dflags pkgs =
  727. collectIncludeDirs `fmap` getPreloadPackagesAnd dflags pkgs
  728. collectIncludeDirs :: [PackageConfig] -> [FilePath]
  729. collectIncludeDirs ps = nub (filter notNull (concatMap includeDirs ps))
  730. -- | Find all the library paths in these and the preload packages
  731. getPackageLibraryPath :: DynFlags -> [PackageId] -> IO [String]
  732. getPackageLibraryPath dflags pkgs =
  733. collectLibraryPaths `fmap` getPreloadPackagesAnd dflags pkgs
  734. collectLibraryPaths :: [PackageConfig] -> [FilePath]
  735. collectLibraryPaths ps = nub (filter notNull (concatMap libraryDirs ps))
  736. -- | Find all the link options in these and the preload packages,
  737. -- returning (package hs lib options, extra library options, other flags)
  738. getPackageLinkOpts :: DynFlags -> [PackageId] -> IO ([String], [String], [String])
  739. getPackageLinkOpts dflags pkgs =
  740. collectLinkOpts dflags `fmap` getPreloadPackagesAnd dflags pkgs
  741. collectLinkOpts :: DynFlags -> [PackageConfig] -> ([String], [String], [String])
  742. collectLinkOpts dflags ps =
  743. (
  744. concatMap (map ("-l" ++) . packageHsLibs dflags) ps,
  745. concatMap (map ("-l" ++) . extraLibraries) ps,
  746. concatMap ldOptions ps
  747. )
  748. packageHsLibs :: DynFlags -> PackageConfig -> [String]
  749. packageHsLibs dflags p = map (mkDynName . addSuffix) (hsLibraries p)
  750. where
  751. ways0 = ways dflags
  752. ways1 = filter (/= WayDyn) ways0
  753. -- the name of a shared library is libHSfoo-ghc<version>.so
  754. -- we leave out the _dyn, because it is superfluous
  755. -- debug RTS includes support for -eventlog
  756. ways2 | WayDebug `elem` ways1
  757. = filter (/= WayEventLog) ways1
  758. | otherwise
  759. = ways1
  760. tag = mkBuildTag (filter (not . wayRTSOnly) ways2)
  761. rts_tag = mkBuildTag ways2
  762. mkDynName x
  763. | gopt Opt_Static dflags = x
  764. | "HS" `isPrefixOf` x = x ++ "-ghc" ++ cProjectVersion
  765. -- For non-Haskell libraries, we use the name "Cfoo". The .a
  766. -- file is libCfoo.a, and the .so is libfoo.so. That way the
  767. -- linker knows what we mean for the vanilla (-lCfoo) and dyn
  768. -- (-lfoo) ways. We therefore need to strip the 'C' off here.
  769. | Just x' <- stripPrefix "C" x = x'
  770. | otherwise
  771. = panic ("Don't understand library name " ++ x)
  772. addSuffix rts@"HSrts" = rts ++ (expandTag rts_tag)
  773. addSuffix other_lib = other_lib ++ (expandTag tag)
  774. expandTag t | null t = ""
  775. | otherwise = '_':t
  776. -- | Find all the C-compiler options in these and the preload packages
  777. getPackageExtraCcOpts :: DynFlags -> [PackageId] -> IO [String]
  778. getPackageExtraCcOpts dflags pkgs = do
  779. ps <- getPreloadPackagesAnd dflags pkgs
  780. return (concatMap ccOptions ps)
  781. -- | Find all the package framework paths in these and the preload packages
  782. getPackageFrameworkPath :: DynFlags -> [PackageId] -> IO [String]
  783. getPackageFrameworkPath dflags pkgs = do
  784. ps <- getPreloadPackagesAnd dflags pkgs
  785. return (nub (filter notNull (concatMap frameworkDirs ps)))
  786. -- | Find all the package frameworks in these and the preload packages
  787. getPackageFrameworks :: DynFlags -> [PackageId] -> IO [String]
  788. getPackageFrameworks dflags pkgs = do
  789. ps <- getPreloadPackagesAnd dflags pkgs
  790. return (concatMap frameworks ps)
  791. -- -----------------------------------------------------------------------------
  792. -- Package Utils
  793. -- | Takes a 'Module', and if the module is in a package returns
  794. -- @(pkgconf, exposed)@ where pkgconf is the PackageConfig for that package,
  795. -- and exposed is @True@ if the package exposes the module.
  796. lookupModuleInAllPackages :: DynFlags -> ModuleName -> [(PackageConfig,Bool)]
  797. lookupModuleInAllPackages dflags m
  798. = case lookupModuleWithSuggestions dflags m of
  799. Right pbs -> pbs
  800. Left _ -> []
  801. lookupModuleWithSuggestions
  802. :: DynFlags -> ModuleName
  803. -> Either [Module] [(PackageConfig,Bool)]
  804. -- Lookup module in all packages
  805. -- Right pbs => found in pbs
  806. -- Left ms => not found; but here are sugestions
  807. lookupModuleWithSuggestions dflags m
  808. = case lookupUFM (moduleToPkgConfAll pkg_state) m of
  809. Nothing -> Left suggestions
  810. Just ps -> Right ps
  811. where
  812. pkg_state = pkgState dflags
  813. suggestions
  814. | gopt Opt_HelpfulErrors dflags = fuzzyLookup (moduleNameString m) all_mods
  815. | otherwise = []
  816. all_mods :: [(String, Module)] -- All modules
  817. all_mods = [ (moduleNameString mod_nm, mkModule pkg_id mod_nm)
  818. | pkg_config <- eltsUFM (pkgIdMap pkg_state)
  819. , let pkg_id = packageConfigId pkg_config
  820. , mod_nm <- exposedModules pkg_config ]
  821. -- | Find all the 'PackageConfig' in both the preload packages from 'DynFlags' and corresponding to the list of
  822. -- 'PackageConfig's
  823. getPreloadPackagesAnd :: DynFlags -> [PackageId] -> IO [PackageConfig]
  824. getPreloadPackagesAnd dflags pkgids =
  825. let
  826. state = pkgState dflags
  827. pkg_map = pkgIdMap state
  828. ipid_map = installedPackageIdMap state
  829. preload = preloadPackages state
  830. pairs = zip pkgids (repeat Nothing)
  831. in do
  832. all_pkgs <- throwErr dflags (foldM (add_package pkg_map ipid_map) preload pairs)
  833. return (map (getPackageDetails state) all_pkgs)
  834. -- Takes a list of packages, and returns the list with dependencies included,
  835. -- in reverse dependency order (a package appears before those it depends on).
  836. closeDeps :: DynFlags
  837. -> PackageConfigMap
  838. -> Map InstalledPackageId PackageId
  839. -> [(PackageId, Maybe PackageId)]
  840. -> IO [PackageId]
  841. closeDeps dflags pkg_map ipid_map ps
  842. = throwErr dflags (closeDepsErr pkg_map ipid_map ps)
  843. throwErr :: DynFlags -> MaybeErr MsgDoc a -> IO a
  844. throwErr dflags m
  845. = case m of
  846. Failed e -> throwGhcExceptionIO (CmdLineError (showSDoc dflags e))
  847. Succeeded r -> return r
  848. closeDepsErr :: PackageConfigMap
  849. -> Map InstalledPackageId PackageId
  850. -> [(PackageId,Maybe PackageId)]
  851. -> MaybeErr MsgDoc [PackageId]
  852. closeDepsErr pkg_map ipid_map ps = foldM (add_package pkg_map ipid_map) [] ps
  853. -- internal helper
  854. add_package :: PackageConfigMap
  855. -> Map InstalledPackageId PackageId
  856. -> [PackageId]
  857. -> (PackageId,Maybe PackageId)
  858. -> MaybeErr MsgDoc [PackageId]
  859. add_package pkg_db ipid_map ps (p, mb_parent)
  860. | p `elem` ps = return ps -- Check if we've already added this package
  861. | otherwise =
  862. case lookupPackage pkg_db p of
  863. Nothing -> Failed (missingPackageMsg (packageIdString p) <>
  864. missingDependencyMsg mb_parent)
  865. Just pkg -> do
  866. -- Add the package's dependents also
  867. ps' <- foldM add_package_ipid ps (depends pkg)
  868. return (p : ps')
  869. where
  870. add_package_ipid ps ipid@(InstalledPackageId str)
  871. | Just pid <- Map.lookup ipid ipid_map
  872. = add_package pkg_db ipid_map ps (pid, Just p)
  873. | otherwise
  874. = Failed (missingPackageMsg str <> missingDependencyMsg mb_parent)
  875. missingPackageErr :: DynFlags -> String -> IO a
  876. missingPackageErr dflags p
  877. = throwGhcExceptionIO (CmdLineError (showSDoc dflags (missingPackageMsg p)))
  878. missingPackageMsg :: String -> SDoc
  879. missingPackageMsg p = ptext (sLit "unknown package:") <+> text p
  880. missingDependencyMsg :: Maybe PackageId -> SDoc
  881. missingDependencyMsg Nothing = empty
  882. missingDependencyMsg (Just parent)
  883. = space <> parens (ptext (sLit "dependency of") <+> ftext (packageIdFS parent))
  884. -- -----------------------------------------------------------------------------
  885. -- | Will the 'Name' come from a dynamically linked library?
  886. isDllName :: DynFlags -> PackageId -> Module -> Name -> Bool
  887. -- Despite the "dll", I think this function just means that
  888. -- the synbol comes from another dynamically-linked package,
  889. -- and applies on all platforms, not just Windows
  890. isDllName dflags this_pkg this_mod name
  891. | gopt Opt_Static dflags = False
  892. | Just mod <- nameModule_maybe name
  893. = if modulePackageId mod /= this_pkg
  894. then True
  895. else case dllSplit dflags of
  896. Nothing -> False
  897. Just ss ->
  898. let findMod m = let modStr = moduleNameString (moduleName m)
  899. in case find (modStr `Set.member`) ss of
  900. Just i -> i
  901. Nothing -> panic ("Can't find " ++ modStr ++ "in DLL split")
  902. in findMod mod /= findMod this_mod
  903. | otherwise = False -- no, it is not even an external name
  904. -- -----------------------------------------------------------------------------
  905. -- Displaying packages
  906. -- | Show package info on console, if verbosity is >= 3
  907. dumpPackages :: DynFlags -> IO ()
  908. dumpPackages dflags
  909. = do let pkg_map = pkgIdMap (pkgState dflags)
  910. putMsg dflags $
  911. vcat (map (text . showInstalledPackageInfo
  912. . packageConfigToInstalledPackageInfo)
  913. (eltsUFM pkg_map))
  914. \end{code}