2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE MultiWayIf #-}
4 {-# LANGUAGE NamedFieldPuns #-}
5 {-# LANGUAGE RankNTypes #-}
6 {-# LANGUAGE TupleSections #-}
8 -----------------------------------------------------------------------------
11 -- Module : Distribution.Simple.GHC
12 -- Copyright : Isaac Jones 2003-2007
15 -- Maintainer : cabal-devel@haskell.org
16 -- Portability : portable
18 -- This is a fairly large module. It contains most of the GHC-specific code for
19 -- configuring, building and installing packages. It also exports a function
20 -- for finding out what packages are already installed. Configuring involves
21 -- finding the @ghc@ and @ghc-pkg@ programs, finding what language extensions
22 -- this version of ghc supports and returning a 'Compiler' value.
24 -- 'getInstalledPackages' involves calling the @ghc-pkg@ program to find out
25 -- what packages are installed.
27 -- Building is somewhat complex as there is quite a bit of information to take
28 -- into account. We have to build libs and programs, possibly for profiling and
29 -- shared libs. We have to support building libraries that will be usable by
30 -- GHCi and also ghc's @-split-objs@ feature. We have to compile any C files
31 -- using ghc. Linking, especially for @split-objs@ is remarkably complex,
32 -- partly because there tend to be 1,000's of @.o@ files and this can often be
33 -- more than we can pass to the @ld@ or @ar@ programs in one go.
35 -- Installing for libs and exes involves finding the right files and copying
36 -- them to the right places. One of the more tricky things about this module is
37 -- remembering the layout of files in the build directory (which is not
38 -- explicitly documented) and thus what search dirs are used for various kinds
40 module Distribution
.Simple
.GHC
43 , getInstalledPackages
44 , getInstalledPackagesMonitorFiles
45 , getPackageDBContents
59 , Internal
.componentGhcOptions
60 , Internal
.componentCcGhcOptions
67 -- * Constructing and deconstructing GHC environment files
68 , Internal
.GhcEnvironmentFileEntry
(..)
69 , Internal
.simpleGhcEnvironmentFile
70 , Internal
.renderGhcEnvironmentFile
71 , Internal
.writeGhcEnvironmentFile
72 , Internal
.ghcPlatformAndVersionString
73 , readGhcEnvironmentFile
74 , parseGhcEnvironmentFile
77 -- * Version-specific implementation quirks
82 import Distribution
.Compat
.Prelude
85 import Control
.Monad
(forM_
)
86 import Data
.List
(stripPrefix
)
87 import qualified Data
.Map
as Map
88 import Distribution
.CabalSpecVersion
89 import Distribution
.InstalledPackageInfo
(InstalledPackageInfo
)
90 import qualified Distribution
.InstalledPackageInfo
as InstalledPackageInfo
91 import Distribution
.Package
92 import Distribution
.PackageDescription
as PD
93 import Distribution
.Pretty
94 import Distribution
.Simple
.Build
.Inputs
(PreBuildComponentInputs
(..))
95 import Distribution
.Simple
.BuildPaths
96 import Distribution
.Simple
.Compiler
97 import Distribution
.Simple
.Errors
98 import Distribution
.Simple
.Flag
(Flag
(..), toFlag
)
99 import qualified Distribution
.Simple
.GHC
.Build
as GHC
100 import Distribution
.Simple
.GHC
.Build
.Utils
101 import Distribution
.Simple
.GHC
.EnvironmentParser
102 import Distribution
.Simple
.GHC
.ImplInfo
103 import qualified Distribution
.Simple
.GHC
.Internal
as Internal
104 import Distribution
.Simple
.LocalBuildInfo
105 import Distribution
.Simple
.PackageIndex
(InstalledPackageIndex
)
106 import qualified Distribution
.Simple
.PackageIndex
as PackageIndex
107 import Distribution
.Simple
.PreProcess
.Types
108 import Distribution
.Simple
.Program
109 import Distribution
.Simple
.Program
.Builtin
(runghcProgram
)
110 import Distribution
.Simple
.Program
.GHC
111 import qualified Distribution
.Simple
.Program
.HcPkg
as HcPkg
112 import qualified Distribution
.Simple
.Program
.Strip
as Strip
113 import Distribution
.Simple
.Setup
.Common
(extraCompilationArtifacts
)
114 import Distribution
.Simple
.Setup
.Repl
115 import Distribution
.Simple
.Utils
116 import Distribution
.System
117 import Distribution
.Types
.ComponentLocalBuildInfo
118 import Distribution
.Types
.ParStrat
119 import Distribution
.Types
.TargetInfo
120 import Distribution
.Utils
.NubList
121 import Distribution
.Verbosity
122 import Distribution
.Version
123 import Language
.Haskell
.Extension
124 import System
.Directory
126 , createDirectoryIfMissing
129 , getAppUserDataDirectory
130 , getDirectoryContents
132 import System
.FilePath
137 import qualified System
.Info
138 #ifndef mingw32_HOST_OS
139 import System
.Directory
(renameFile)
140 import System
.Posix
(createSymbolicLink
)
141 #endif
/* mingw32_HOST_OS
*/
143 import Distribution
.Simple
.Setup
(BuildingWhat
(..))
144 import Distribution
.Simple
.Setup
.Build
146 -- -----------------------------------------------------------------------------
154 -> IO (Compiler
, Maybe Platform
, ProgramDb
)
155 configure verbosity hcPath hcPkgPath conf0
= do
156 (ghcProg
, ghcVersion
, progdb1
) <-
157 requireProgramVersion
160 (orLaterVersion
(mkVersion
[7, 0, 1]))
161 (userMaybeSpecifyPath
"ghc" hcPath conf0
)
162 let implInfo
= ghcVersionImplInfo ghcVersion
164 -- Cabal currently supports ghc >= 7.0.1 && < 9.12
165 -- ... and the following odd development version
166 unless (ghcVersion
< mkVersion
[9, 12]) $
168 "Unknown/unsupported 'ghc' version detected "
170 ++ prettyShow cabalVersion
171 ++ " supports 'ghc' version < 9.12): "
172 ++ programPath ghcProg
174 ++ prettyShow ghcVersion
176 -- This is slightly tricky, we have to configure ghc first, then we use the
177 -- location of ghc to help find ghc-pkg in the case that the user did not
178 -- specify the location of ghc-pkg directly:
179 (ghcPkgProg
, ghcPkgVersion
, progdb2
) <-
180 requireProgramVersion
183 { programFindLocation
= guessGhcPkgFromGhcPath ghcProg
186 (userMaybeSpecifyPath
"ghc-pkg" hcPkgPath progdb1
)
188 when (ghcVersion
/= ghcPkgVersion
) $
189 dieWithException verbosity
$
190 VersionMismatchGHC
(programPath ghcProg
) ghcVersion
(programPath ghcPkgProg
) ghcPkgVersion
191 -- Likewise we try to find the matching hsc2hs and haddock programs.
194 { programFindLocation
= guessHsc2hsFromGhcPath ghcProg
198 { programFindLocation
= guessHaddockFromGhcPath ghcProg
202 { programFindLocation
= guessHpcFromGhcPath ghcProg
206 { programFindLocation
= guessRunghcFromGhcPath ghcProg
209 addKnownProgram haddockProgram
' $
210 addKnownProgram hsc2hsProgram
' $
211 addKnownProgram hpcProgram
' $
212 addKnownProgram runghcProgram
' progdb2
214 languages
<- Internal
.getLanguages verbosity implInfo ghcProg
215 extensions0
<- Internal
.getExtensions verbosity implInfo ghcProg
217 ghcInfo
<- Internal
.getGhcInfo verbosity implInfo ghcProg
218 let ghcInfoMap
= Map
.fromList ghcInfo
219 filterJS
= if ghcVersion
< mkVersion
[9, 8] then filterExt JavaScriptFFI
else id
221 -- workaround https://gitlab.haskell.org/ghc/ghc/-/issues/11214
223 -- see 'filterExtTH' comment below
227 -- starting with GHC 8.0, `TemplateHaskell` will be omitted from
228 -- `--supported-extensions` when it's not available.
229 -- for older GHCs we can use the "Have interpreter" property to
230 -- filter out `TemplateHaskell`
232 | ghcVersion
< mkVersion
[8]
233 , Just
"NO" <- Map
.lookup "Have interpreter" ghcInfoMap
=
234 filterExt TemplateHaskell
237 filterExt ext
= filter ((/= EnableExtension ext
) . fst)
239 compilerId
:: CompilerId
240 compilerId
= CompilerId GHC ghcVersion
242 compilerAbiTag
:: AbiTag
243 compilerAbiTag
= maybe NoAbiTag AbiTag
(Map
.lookup "Project Unit Id" ghcInfoMap
>>= stripPrefix
(prettyShow compilerId
<> "-"))
249 , compilerCompat
= []
250 , compilerLanguages
= languages
251 , compilerExtensions
= extensions
252 , compilerProperties
= ghcInfoMap
254 compPlatform
= Internal
.targetPlatform ghcInfo
255 -- configure gcc and ld
256 progdb4
= Internal
.configureToolchain implInfo ghcProg ghcInfoMap progdb3
257 return (comp
, compPlatform
, progdb4
)
259 -- | Given something like /usr/local/bin/ghc-6.6.1(.exe) we try and find
260 -- the corresponding tool; e.g. if the tool is ghc-pkg, we try looking
261 -- for a versioned or unversioned ghc-pkg in the same dir, that is:
263 -- > /usr/local/bin/ghc-pkg-ghc-6.6.1(.exe)
264 -- > /usr/local/bin/ghc-pkg-6.6.1(.exe)
265 -- > /usr/local/bin/ghc-pkg(.exe)
271 -> IO (Maybe (FilePath, [FilePath]))
272 guessToolFromGhcPath tool ghcProg verbosity searchpath
=
274 let toolname
= programName tool
275 given_path
= programPath ghcProg
276 given_dir
= takeDirectory given_path
277 real_path
<- canonicalizePath given_path
278 let real_dir
= takeDirectory real_path
279 versionSuffix path
= takeVersionSuffix
(dropExeExtension path
)
280 given_suf
= versionSuffix given_path
281 real_suf
= versionSuffix real_path
282 guessNormal dir
= dir
</> toolname
<.> exeExtension buildPlatform
283 guessGhcVersioned dir suf
=
285 </> (toolname
++ "-ghc" ++ suf
)
286 <.> exeExtension buildPlatform
287 guessVersioned dir suf
=
289 </> (toolname
++ suf
)
290 <.> exeExtension buildPlatform
292 |
null suf
= [guessNormal dir
]
294 [ guessGhcVersioned dir suf
295 , guessVersioned dir suf
298 -- order matters here, see https://github.com/haskell/cabal/issues/7390
300 ( if real_path
== given_path
302 else mkGuesses real_dir real_suf
304 ++ mkGuesses given_dir given_suf
308 ++ " near compiler in "
310 debug verbosity
$ "candidate locations: " ++ show guesses
311 exists
<- traverse
doesFileExist guesses
312 case [file |
(file
, True) <- zip guesses exists
] of
313 -- If we can't find it near ghc, fall back to the usual
315 [] -> programFindLocation tool verbosity searchpath
317 info verbosity
$ "found " ++ toolname
++ " in " ++ fp
320 . takeWhile (\(_file
, exist
) -> not exist
)
322 return (Just
(fp
, lookedAt
))
324 takeVersionSuffix
:: FilePath -> String
325 takeVersionSuffix
= takeWhileEndLE isSuffixChar
327 isSuffixChar
:: Char -> Bool
328 isSuffixChar c
= isDigit c || c
== '.' || c
== '-'
330 -- | Given something like /usr/local/bin/ghc-6.6.1(.exe) we try and find a
331 -- corresponding ghc-pkg, we try looking for both a versioned and unversioned
332 -- ghc-pkg in the same dir, that is:
334 -- > /usr/local/bin/ghc-pkg-ghc-6.6.1(.exe)
335 -- > /usr/local/bin/ghc-pkg-6.6.1(.exe)
336 -- > /usr/local/bin/ghc-pkg(.exe)
337 guessGhcPkgFromGhcPath
341 -> IO (Maybe (FilePath, [FilePath]))
342 guessGhcPkgFromGhcPath
= guessToolFromGhcPath ghcPkgProgram
344 -- | Given something like /usr/local/bin/ghc-6.6.1(.exe) we try and find a
345 -- corresponding hsc2hs, we try looking for both a versioned and unversioned
346 -- hsc2hs in the same dir, that is:
348 -- > /usr/local/bin/hsc2hs-ghc-6.6.1(.exe)
349 -- > /usr/local/bin/hsc2hs-6.6.1(.exe)
350 -- > /usr/local/bin/hsc2hs(.exe)
351 guessHsc2hsFromGhcPath
355 -> IO (Maybe (FilePath, [FilePath]))
356 guessHsc2hsFromGhcPath
= guessToolFromGhcPath hsc2hsProgram
358 -- | Given something like /usr/local/bin/ghc-6.6.1(.exe) we try and find a
359 -- corresponding haddock, we try looking for both a versioned and unversioned
360 -- haddock in the same dir, that is:
362 -- > /usr/local/bin/haddock-ghc-6.6.1(.exe)
363 -- > /usr/local/bin/haddock-6.6.1(.exe)
364 -- > /usr/local/bin/haddock(.exe)
365 guessHaddockFromGhcPath
369 -> IO (Maybe (FilePath, [FilePath]))
370 guessHaddockFromGhcPath
= guessToolFromGhcPath haddockProgram
376 -> IO (Maybe (FilePath, [FilePath]))
377 guessHpcFromGhcPath
= guessToolFromGhcPath hpcProgram
379 guessRunghcFromGhcPath
383 -> IO (Maybe (FilePath, [FilePath]))
384 guessRunghcFromGhcPath
= guessToolFromGhcPath runghcProgram
386 getGhcInfo
:: Verbosity
-> ConfiguredProgram
-> IO [(String, String)]
387 getGhcInfo verbosity ghcProg
= Internal
.getGhcInfo verbosity implInfo ghcProg
389 version
= fromMaybe (error "GHC.getGhcInfo: no ghc version") $ programVersion ghcProg
390 implInfo
= ghcVersionImplInfo version
392 -- | Given a single package DB, return all installed packages.
397 -> IO InstalledPackageIndex
398 getPackageDBContents verbosity packagedb progdb
= do
399 pkgss
<- getInstalledPackages
' verbosity
[packagedb
] progdb
400 toPackageIndex verbosity pkgss progdb
402 -- | Given a package DB stack, return all installed packages.
408 -> IO InstalledPackageIndex
409 getInstalledPackages verbosity comp packagedbs progdb
= do
410 checkPackageDbEnvVar verbosity
411 checkPackageDbStack verbosity comp packagedbs
412 pkgss
<- getInstalledPackages
' verbosity packagedbs progdb
413 index <- toPackageIndex verbosity pkgss progdb
414 return $! hackRtsPackage
index
416 hackRtsPackage
index =
417 case PackageIndex
.lookupPackageName
index (mkPackageName
"rts") of
419 PackageIndex
.insert (removeMingwIncludeDir rts
) index
420 _
-> index -- No (or multiple) ghc rts package is registered!!
421 -- Feh, whatever, the ghc test suite does some crazy stuff.
423 -- | Given a list of @(PackageDB, InstalledPackageInfo)@ pairs, produce a
424 -- @PackageIndex@. Helper function used by 'getPackageDBContents' and
425 -- 'getInstalledPackages'.
428 -> [(PackageDB
, [InstalledPackageInfo
])]
430 -> IO InstalledPackageIndex
431 toPackageIndex verbosity pkgss progdb
= do
432 -- On Windows, various fields have $topdir/foo rather than full
433 -- paths. We need to substitute the right value in so that when
434 -- we, for example, call gcc, we have proper paths to give it.
435 topDir
<- getLibDir
' verbosity ghcProg
437 [ PackageIndex
.fromList
(map (Internal
.substTopDir topDir
) pkgs
)
440 return $! mconcat
indices
442 ghcProg
= fromMaybe (error "GHC.toPackageIndex: no ghc program") $ lookupProgram ghcProgram progdb
444 -- | Return the 'FilePath' to the GHC application data directory.
447 getGhcAppDir
:: IO FilePath
448 getGhcAppDir
= getAppUserDataDirectory
"ghc"
450 getLibDir
:: Verbosity
-> LocalBuildInfo
-> IO FilePath
451 getLibDir verbosity lbi
=
452 dropWhileEndLE
isSpace
453 `
fmap` getDbProgramOutput
459 getLibDir
' :: Verbosity
-> ConfiguredProgram
-> IO FilePath
460 getLibDir
' verbosity ghcProg
=
461 dropWhileEndLE
isSpace
462 `
fmap` getProgramOutput verbosity ghcProg
["--print-libdir"]
464 -- | Return the 'FilePath' to the global GHC package database.
465 getGlobalPackageDB
:: Verbosity
-> ConfiguredProgram
-> IO FilePath
466 getGlobalPackageDB verbosity ghcProg
=
467 dropWhileEndLE
isSpace
468 `
fmap` getProgramOutput verbosity ghcProg
["--print-global-package-db"]
470 -- | Return the 'FilePath' to the per-user GHC package database.
472 :: Verbosity
-> ConfiguredProgram
-> Platform
-> IO FilePath
473 getUserPackageDB _verbosity ghcProg platform
= do
474 -- It's rather annoying that we have to reconstruct this, because ghc
475 -- hides this information from us otherwise. But for certain use cases
476 -- like change monitoring it really can't remain hidden.
477 appdir
<- getGhcAppDir
478 return (appdir
</> platformAndVersion
</> packageConfFileName
)
481 Internal
.ghcPlatformAndVersionString
484 packageConfFileName
= "package.conf.d"
485 ghcVersion
= fromMaybe (error "GHC.getUserPackageDB: no ghc version") $ programVersion ghcProg
487 checkPackageDbEnvVar
:: Verbosity
-> IO ()
488 checkPackageDbEnvVar verbosity
=
489 Internal
.checkPackageDbEnvVar verbosity
"GHC" "GHC_PACKAGE_PATH"
491 checkPackageDbStack
:: Verbosity
-> Compiler
-> PackageDBStack
-> IO ()
492 checkPackageDbStack verbosity comp
=
493 if flagPackageConf implInfo
494 then checkPackageDbStackPre76 verbosity
495 else checkPackageDbStackPost76 verbosity
497 implInfo
= ghcVersionImplInfo
(compilerVersion comp
)
499 checkPackageDbStackPost76
:: Verbosity
-> PackageDBStack
-> IO ()
500 checkPackageDbStackPost76 _
(GlobalPackageDB
: rest
)
501 | GlobalPackageDB `
notElem` rest
= return ()
502 checkPackageDbStackPost76 verbosity rest
503 | GlobalPackageDB `
elem` rest
=
504 dieWithException verbosity CheckPackageDbStackPost76
505 checkPackageDbStackPost76 _ _
= return ()
507 checkPackageDbStackPre76
:: Verbosity
-> PackageDBStack
-> IO ()
508 checkPackageDbStackPre76 _
(GlobalPackageDB
: rest
)
509 | GlobalPackageDB `
notElem` rest
= return ()
510 checkPackageDbStackPre76 verbosity rest
511 | GlobalPackageDB `
notElem` rest
=
512 dieWithException verbosity CheckPackageDbStackPre76
513 checkPackageDbStackPre76 verbosity _
=
514 dieWithException verbosity GlobalPackageDbSpecifiedFirst
516 -- GHC < 6.10 put "$topdir/include/mingw" in rts's installDirs. This
517 -- breaks when you want to use a different gcc, so we need to filter
519 removeMingwIncludeDir
:: InstalledPackageInfo
-> InstalledPackageInfo
520 removeMingwIncludeDir pkg
=
521 let ids
= InstalledPackageInfo
.includeDirs pkg
522 ids
' = filter (not . ("mingw" `
isSuffixOf`
)) ids
523 in pkg
{InstalledPackageInfo
.includeDirs
= ids
'}
525 -- | Get the packages from specific PackageDBs, not cumulative.
526 getInstalledPackages
'
530 -> IO [(PackageDB
, [InstalledPackageInfo
])]
531 getInstalledPackages
' verbosity packagedbs progdb
=
534 pkgs
<- HcPkg
.dump
(hcPkgInfo progdb
) verbosity packagedb
535 return (packagedb
, pkgs
)
536 | packagedb
<- packagedbs
539 getInstalledPackagesMonitorFiles
545 getInstalledPackagesMonitorFiles verbosity platform progdb
=
546 traverse getPackageDBPath
548 getPackageDBPath
:: PackageDB
-> IO FilePath
549 getPackageDBPath GlobalPackageDB
=
550 selectMonitorFile
=<< getGlobalPackageDB verbosity ghcProg
551 getPackageDBPath UserPackageDB
=
552 selectMonitorFile
=<< getUserPackageDB verbosity ghcProg platform
553 getPackageDBPath
(SpecificPackageDB path
) = selectMonitorFile path
555 -- GHC has old style file dbs, and new style directory dbs.
556 -- Note that for dir style dbs, we only need to monitor the cache file, not
557 -- the whole directory. The ghc program itself only reads the cache file
558 -- so it's safe to only monitor this one file.
559 selectMonitorFile path
= do
560 isFileStyle
<- doesFileExist path
563 else return (path
</> "package.cache")
565 ghcProg
= fromMaybe (error "GHC.toPackageIndex: no ghc program") $ lookupProgram ghcProgram progdb
567 -- -----------------------------------------------------------------------------
568 -- Building a library
573 -> PackageDescription
576 -> ComponentLocalBuildInfo
578 buildLib flags numJobs pkg lbi lib clbi
=
579 GHC
.build numJobs pkg
$
580 PreBuildComponentInputs
(BuildNormal flags
) lbi
(TargetInfo clbi
(CLib lib
))
585 -> PackageDescription
588 -> ComponentLocalBuildInfo
590 replLib flags numJobs pkg lbi lib clbi
=
591 GHC
.build numJobs pkg
$
592 PreBuildComponentInputs
(BuildRepl flags
) lbi
(TargetInfo clbi
(CLib lib
))
594 -- | Start a REPL without loading any source files.
602 startInterpreter verbosity progdb comp platform packageDBs
= do
605 { ghcOptMode
= toFlag GhcModeInteractive
606 , ghcOptPackageDBs
= packageDBs
608 checkPackageDbStack verbosity comp packageDBs
609 (ghcProg
, _
) <- requireProgram verbosity ghcProgram progdb
610 runGHC verbosity ghcProg comp platform replOpts
612 -- -----------------------------------------------------------------------------
613 -- Building an executable or foreign library
615 -- | Build a foreign library
619 -> PackageDescription
622 -> ComponentLocalBuildInfo
624 buildFLib v numJobs pkg lbi flib clbi
=
625 GHC
.build numJobs pkg
$
626 PreBuildComponentInputs
(BuildNormal mempty
{buildVerbosity
= toFlag v
}) lbi
(TargetInfo clbi
(CFLib flib
))
631 -> PackageDescription
634 -> ComponentLocalBuildInfo
636 replFLib replFlags njobs pkg lbi flib clbi
=
637 GHC
.build njobs pkg
$
638 PreBuildComponentInputs
(BuildRepl replFlags
) lbi
(TargetInfo clbi
(CFLib flib
))
640 -- | Build an executable with GHC.
644 -> PackageDescription
647 -> ComponentLocalBuildInfo
649 buildExe v njobs pkg lbi exe clbi
=
650 GHC
.build njobs pkg
$
651 PreBuildComponentInputs
(BuildNormal mempty
{buildVerbosity
= toFlag v
}) lbi
(TargetInfo clbi
(CExe exe
))
656 -> PackageDescription
659 -> ComponentLocalBuildInfo
661 replExe replFlags njobs pkg lbi exe clbi
=
662 GHC
.build njobs pkg
$
663 PreBuildComponentInputs
(BuildRepl replFlags
) lbi
(TargetInfo clbi
(CExe exe
))
665 -- | Extracts a String representing a hash of the ABI of a built
666 -- library. It can fail if the library has not yet been built.
669 -> PackageDescription
672 -> ComponentLocalBuildInfo
674 libAbiHash verbosity _pkg_descr lbi lib clbi
= do
676 libBi
= libBuildInfo lib
678 platform
= hostPlatform lbi
680 (Internal
.componentGhcOptions verbosity lbi libBi clbi
(componentBuildDir lbi clbi
))
682 { ghcOptMode
= toFlag GhcModeAbiHash
683 , ghcOptInputModules
= toNubListR
$ exposedModules lib
688 { ghcOptDynLinkMode
= toFlag GhcDynamicOnly
689 , ghcOptFPic
= toFlag
True
690 , ghcOptHiSuffix
= toFlag
"dyn_hi"
691 , ghcOptObjSuffix
= toFlag
"dyn_o"
692 , ghcOptExtra
= hcSharedOptions GHC libBi
697 { ghcOptProfilingMode
= toFlag
True
698 , ghcOptProfilingAuto
=
699 Internal
.profDetailLevelFlag
701 (withProfLibDetail lbi
)
702 , ghcOptHiSuffix
= toFlag
"p_hi"
703 , ghcOptObjSuffix
= toFlag
"p_o"
704 , ghcOptExtra
= hcProfOptions GHC libBi
707 | withVanillaLib lbi
= vanillaArgs
708 | withSharedLib lbi
= sharedArgs
709 | withProfLib lbi
= profArgs
710 |
otherwise = error "libAbiHash: Can't find an enabled library way"
712 (ghcProg
, _
) <- requireProgram verbosity ghcProgram
(withPrograms lbi
)
715 getProgramInvocationOutput
717 =<< ghcInvocation verbosity ghcProg comp platform ghcArgs
719 return (takeWhile (not . isSpace) hash
)
721 -- -----------------------------------------------------------------------------
724 -- | Install executables for GHC.
729 -- ^ Where to copy the files to
732 -> (FilePath, FilePath)
733 -- ^ Executable (prefix,suffix)
734 -> PackageDescription
742 (progprefix
, progsuffix
)
745 createDirectoryIfMissingVerbose verbosity
True binDir
746 let exeName
' = unUnqualComponentName
$ exeName exe
747 exeFileName
= exeTargetName
(hostPlatform lbi
) (exeName exe
)
748 fixedExeBaseName
= progprefix
++ exeName
' ++ progsuffix
749 installBinary dest
= do
750 installExecutableFile
752 (buildPref
</> exeName
' </> exeFileName
)
753 (dest
<.> exeExtension
(hostPlatform lbi
))
754 when (stripExes lbi
) $
759 (dest
<.> exeExtension
(hostPlatform lbi
))
760 installBinary
(binDir
</> fixedExeBaseName
)
762 -- | Install foreign library for GHC.
767 -- ^ install location
770 -> PackageDescription
773 installFLib verbosity lbi targetDir builtDir _pkg flib
=
775 (foreignLibIsShared flib
)
778 (flibTargetName lbi flib
)
780 install isShared srcDir dstDir name
= do
781 let src
= srcDir
</> name
782 dst
= dstDir
</> name
783 createDirectoryIfMissingVerbose verbosity
True targetDir
784 -- TODO: Should we strip? (stripLibs lbi)
786 then installExecutableFile verbosity src dst
787 else installOrdinaryFile verbosity src dst
788 -- Now install appropriate symlinks if library is versioned
789 let (Platform _ os
) = hostPlatform lbi
790 when (not (null (foreignLibVersion flib os
))) $ do
792 dieWithException verbosity
$
793 CantInstallForeignLib
794 #ifndef mingw32_HOST_OS
795 -- 'createSymbolicLink file1 file2' creates a symbolic link
796 -- named 'file2' which points to the file 'file1'.
797 -- Note that we do want a symlink to 'name' rather than
798 -- 'dst', because the symlink will be relative to the
799 -- directory it's created in.
800 -- Finally, we first create the symlinks in a temporary
801 -- directory and then rename to simulate 'ln --force'.
802 withTempDirectory verbosity dstDir nm
$ \tmpDir
-> do
803 let link1
= flibBuildName lbi flib
804 link2
= "lib" ++ nm
<.> "so"
805 createSymbolicLink name
(tmpDir
</> link1
)
806 renameFile (tmpDir
</> link1
) (dstDir
</> link1
)
807 createSymbolicLink name
(tmpDir
</> link2
)
808 renameFile (tmpDir
</> link2
) (dstDir
</> link2
)
811 nm
= unUnqualComponentName
$ foreignLibName flib
812 #endif
/* mingw32_HOST_OS
*/
814 -- | Install for ghc, .hi, .a and, if --with-ghci given, .o
819 -- ^ install location
821 -- ^ install location for dynamic libraries
824 -> PackageDescription
826 -> ComponentLocalBuildInfo
828 installLib verbosity lbi targetDir dynlibTargetDir _builtDir pkg lib clbi
= do
829 -- copy .hi files over:
830 whenVanilla
$ copyModuleFiles
$ Suffix
"hi"
831 whenProf
$ copyModuleFiles
$ Suffix
"p_hi"
832 whenShared
$ copyModuleFiles
$ Suffix
"dyn_hi"
834 -- copy extra compilation artifacts that ghc plugins may produce
835 copyDirectoryIfExists extraCompilationArtifacts
837 -- copy the built library files over:
844 (mkGenericStaticLibName
(l
++ f
))
847 (componentUnitId clbi
)
848 : (extraBundledLibs
(libBuildInfo lib
))
849 , f
<- "" : extraLibFlavours
(libBuildInfo lib
)
851 whenGHCi
$ installOrdinary builtDir targetDir ghciLibName
853 installOrdinary builtDir targetDir profileLibName
854 whenGHCi
$ installOrdinary builtDir targetDir ghciProfLibName
857 -- The behavior for "extra-bundled-libraries" changed in version 2.5.0.
858 -- See ghc issue #15837 and Cabal PR #5855.
859 | specVersion pkg
< CabalSpecV3_0
-> do
864 (mkGenericSharedLibName platform compiler_id
(l
++ f
))
865 | l
<- getHSLibraryName uid
: extraBundledLibs
(libBuildInfo lib
)
866 , f
<- "" : extraDynLibFlavours
(libBuildInfo lib
)
873 ( mkGenericSharedLibName
876 (getHSLibraryName uid
++ f
)
878 | f
<- "" : extraDynLibFlavours
(libBuildInfo lib
)
882 files
<- getDirectoryContents builtDir
884 mkGenericSharedBundledLibName
888 forM_ files
$ \file
->
889 when (l
' `
isPrefixOf` file
) $ do
890 isFile
<- doesFileExist (builtDir
</> file
)
896 | l
<- extraBundledLibs
(libBuildInfo lib
)
899 builtDir
= componentBuildDir lbi clbi
901 install isShared srcDir dstDir name
= do
902 let src
= srcDir
</> name
903 dst
= dstDir
</> name
905 createDirectoryIfMissingVerbose verbosity
True dstDir
908 then installExecutableFile verbosity src dst
909 else installOrdinaryFile verbosity src dst
911 when (stripLibs lbi
) $
918 installOrdinary
= install
False
919 installShared
= install
True
921 copyModuleFiles ext
=
922 findModuleFilesEx verbosity
[builtDir
] [ext
] (allLibModules lib clbi
)
923 >>= installOrdinaryFiles verbosity targetDir
925 copyDirectoryIfExists dirName
= do
926 let src
= builtDir
</> dirName
927 dst
= targetDir
</> dirName
928 dirExists
<- doesDirectoryExist src
929 when dirExists
$ copyDirectoryRecursive verbosity src dst
931 compiler_id
= compilerId
(compiler lbi
)
932 platform
= hostPlatform lbi
933 uid
= componentUnitId clbi
934 profileLibName
= mkProfLibName uid
935 ghciLibName
= Internal
.mkGHCiLibName uid
936 ghciProfLibName
= Internal
.mkGHCiProfLibName uid
940 null (allLibModules lib clbi
)
941 && null (cSources
(libBuildInfo lib
))
942 && null (cxxSources
(libBuildInfo lib
))
943 && null (cmmSources
(libBuildInfo lib
))
944 && null (asmSources
(libBuildInfo lib
))
945 && (null (jsSources
(libBuildInfo lib
)) ||
not hasJsSupport
)
946 hasJsSupport
= case hostPlatform lbi
of
947 Platform JavaScript _
-> True
949 has_code
= not (componentIsIndefinite clbi
)
950 whenHasCode
= when has_code
951 whenVanilla
= when (hasLib
&& withVanillaLib lbi
)
952 whenProf
= when (hasLib
&& withProfLib lbi
&& has_code
)
953 whenGHCi
= when (hasLib
&& withGHCiLib lbi
&& has_code
)
954 whenShared
= when (hasLib
&& withSharedLib lbi
&& has_code
)
956 -- -----------------------------------------------------------------------------
959 hcPkgInfo
:: ProgramDb
-> HcPkg
.HcPkgInfo
962 { HcPkg
.hcPkgProgram
= ghcPkgProg
963 , HcPkg
.noPkgDbStack
= v
< [6, 9]
964 , HcPkg
.noVerboseFlag
= v
< [6, 11]
965 , HcPkg
.flagPackageConf
= v
< [7, 5]
966 , HcPkg
.supportsDirDbs
= v
>= [6, 8]
967 , HcPkg
.requiresDirDbs
= v
>= [7, 10]
968 , HcPkg
.nativeMultiInstance
= v
>= [7, 10]
969 , HcPkg
.recacheMultiInstance
= v
>= [6, 12]
970 , HcPkg
.suppressFilesCheck
= v
>= [6, 6]
973 v
= versionNumbers ver
974 ghcPkgProg
= fromMaybe (error "GHC.hcPkgInfo: no ghc program") $ lookupProgram ghcPkgProgram progdb
975 ver
= fromMaybe (error "GHC.hcPkgInfo: no ghc version") $ programVersion ghcPkgProg
981 -> InstalledPackageInfo
982 -> HcPkg
.RegisterOptions
984 registerPackage verbosity progdb packageDbs installedPkgInfo registerOptions
=
992 pkgRoot
:: Verbosity
-> LocalBuildInfo
-> PackageDB
-> IO FilePath
993 pkgRoot verbosity lbi
= pkgRoot
'
995 pkgRoot
' GlobalPackageDB
=
996 let ghcProg
= fromMaybe (error "GHC.pkgRoot: no ghc program") $ lookupProgram ghcProgram
(withPrograms lbi
)
997 in fmap takeDirectory
(getGlobalPackageDB verbosity ghcProg
)
998 pkgRoot
' UserPackageDB
= do
999 appDir
<- getGhcAppDir
1000 let ver
= compilerVersion
(compiler lbi
)
1007 rootDir
= appDir
</> subdir
1008 -- We must create the root directory for the user package database if it
1009 -- does not yet exists. Otherwise '${pkgroot}' will resolve to a
1010 -- directory at the time of 'ghc-pkg register', and registration will
1012 createDirectoryIfMissing
True rootDir
1014 pkgRoot
' (SpecificPackageDB fp
) = return (takeDirectory fp
)