1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE RankNTypes #-}
4 -----------------------------------------------------------------------------
7 -- Module : Distribution.Simple.GHC.Internal
8 -- Copyright : Isaac Jones 2003-2007
10 -- Maintainer : cabal-devel@haskell.org
11 -- Portability : portable
13 -- This module contains functions shared by GHC (Distribution.Simple.GHC)
14 -- and GHC-derived compilers.
15 module Distribution
.Simple
.GHC
.Internal
21 , componentCcGhcOptions
22 , componentCmmGhcOptions
23 , componentCxxGhcOptions
24 , componentAsmGhcOptions
25 , componentJsGhcOptions
34 , checkPackageDbEnvVar
37 -- * GHC platform and version strings
40 , ghcPlatformAndVersionString
42 -- * Constructing GHC environment files
43 , GhcEnvironmentFileEntry
(..)
44 , writeGhcEnvironmentFile
45 , simpleGhcEnvironmentFile
46 , ghcEnvironmentFileName
47 , renderGhcEnvironmentFile
48 , renderGhcEnvironmentFileEntry
51 import Distribution
.Compat
.Prelude
54 import Data
.Bool (bool
)
55 import qualified Data
.ByteString
.Lazy
.Char8
as BS
56 import qualified Data
.Map
as Map
57 import qualified Data
.Set
as Set
58 import Distribution
.Backpack
59 import Distribution
.Compat
.Stack
60 import qualified Distribution
.InstalledPackageInfo
as IPI
61 import Distribution
.Lex
62 import qualified Distribution
.ModuleName
as ModuleName
63 import Distribution
.PackageDescription
64 import Distribution
.Parsec
(simpleParsec
)
65 import Distribution
.Pretty
(prettyShow
)
66 import Distribution
.Simple
.BuildPaths
67 import Distribution
.Simple
.Compiler
68 import Distribution
.Simple
.Errors
69 import Distribution
.Simple
.Flag
(Flag
(NoFlag
), maybeToFlag
, toFlag
)
70 import Distribution
.Simple
.GHC
.ImplInfo
71 import Distribution
.Simple
.LocalBuildInfo
72 import Distribution
.Simple
.Program
73 import Distribution
.Simple
.Program
.GHC
74 import Distribution
.Simple
.Setup
.Common
(extraCompilationArtifacts
)
75 import Distribution
.Simple
.Utils
76 import Distribution
.System
77 import Distribution
.Types
.ComponentId
(ComponentId
)
78 import Distribution
.Types
.ComponentLocalBuildInfo
79 import Distribution
.Types
.LocalBuildInfo
80 import Distribution
.Types
.TargetInfo
81 import Distribution
.Types
.UnitId
82 import Distribution
.Utils
.NubList
(toNubListR
)
83 import Distribution
.Utils
.Path
84 import Distribution
.Verbosity
85 import Distribution
.Version
(Version
)
86 import Language
.Haskell
.Extension
87 import System
.Directory
(getDirectoryContents, getTemporaryDirectory
)
88 import System
.Environment
(getEnv)
89 import System
.FilePath
96 import System
.IO (hClose, hPutStrLn)
98 targetPlatform
:: [(String, String)] -> Maybe Platform
99 targetPlatform ghcInfo
= platformFromTriple
=<< lookup "Target platform" ghcInfo
101 -- | Adjust the way we find and configure gcc and ld
108 configureToolchain _implInfo ghcProg ghcInfo
=
111 { programFindLocation
= findProg gccProgramName extraGccPath
112 , programPostConf
= configureGcc
116 { programFindLocation
= findProg ldProgramName extraLdPath
117 , programPostConf
= \v cp
->
118 -- Call any existing configuration first and then add any new configuration
119 configureLd v
=<< programPostConf ldProgram v cp
123 { programFindLocation
= findProg arProgramName extraArPath
127 { programFindLocation
= findProg stripProgramName extraStripPath
130 compilerDir
= takeDirectory
(programPath ghcProg
)
131 base_dir
= takeDirectory compilerDir
132 mingwBinDir
= base_dir
</> "mingw" </> "bin"
133 isWindows
= case buildOS
of Windows
-> True; _
-> False
136 maybeName
:: Program
-> Maybe FilePath -> String
137 maybeName prog
= maybe (programName prog
) (dropExeExtension
. takeFileName
)
139 gccProgramName
= maybeName gccProgram mbGccLocation
140 ldProgramName
= maybeName ldProgram mbLdLocation
141 arProgramName
= maybeName arProgram mbArLocation
142 stripProgramName
= maybeName stripProgram mbStripLocation
144 mkExtraPath
:: Maybe FilePath -> FilePath -> [FilePath]
145 mkExtraPath mbPath mingwPath
146 | isWindows
= mbDir
++ [mingwPath
]
149 mbDir
= maybeToList . fmap takeDirectory
$ mbPath
151 extraGccPath
= mkExtraPath mbGccLocation windowsExtraGccDir
152 extraLdPath
= mkExtraPath mbLdLocation windowsExtraLdDir
153 extraArPath
= mkExtraPath mbArLocation windowsExtraArDir
154 extraStripPath
= mkExtraPath mbStripLocation windowsExtraStripDir
156 -- on Windows finding and configuring ghc's gcc & binutils is a bit special
160 , windowsExtraStripDir
162 let b
= mingwBinDir
</> binPrefix
170 -> IO (Maybe (FilePath, [FilePath]))
171 findProg progName extraPath v searchpath
=
172 findProgramOnSearchPath v searchpath
' progName
174 searchpath
' = (map ProgramSearchPathDir extraPath
) ++ searchpath
176 -- Read tool locations from the 'ghc --info' output. Useful when
178 mbGccLocation
= Map
.lookup "C compiler command" ghcInfo
179 mbLdLocation
= Map
.lookup "ld command" ghcInfo
180 mbArLocation
= Map
.lookup "ar command" ghcInfo
181 mbStripLocation
= Map
.lookup "strip command" ghcInfo
183 ccFlags
= getFlags
"C compiler flags"
184 -- GHC 7.8 renamed "Gcc Linker flags" to "C compiler link flags"
185 -- and "Ld Linker flags" to "ld flags" (GHC #4862).
186 gccLinkerFlags
= getFlags
"Gcc Linker flags" ++ getFlags
"C compiler link flags"
187 ldLinkerFlags
= getFlags
"Ld Linker flags" ++ getFlags
"ld flags"
189 -- It appears that GHC 7.6 and earlier encode the tokenized flags as a
190 -- [String] in these settings whereas later versions just encode the flags as
193 -- We first try to parse as a [String] and if this fails then tokenize the
195 getFlags
:: String -> [String]
197 case Map
.lookup key ghcInfo
of
200 |
(flags
', "") : _
<- reads flags
-> flags
'
201 |
otherwise -> tokenizeQuotedWords flags
203 configureGcc
:: Verbosity
-> ConfiguredProgram
-> IO ConfiguredProgram
204 configureGcc _v gccProg
= do
207 { programDefaultArgs
=
208 programDefaultArgs gccProg
213 configureLd
:: Verbosity
-> ConfiguredProgram
-> IO ConfiguredProgram
214 configureLd v ldProg
= do
215 ldProg
' <- configureLd
' v ldProg
218 { programDefaultArgs
= programDefaultArgs ldProg
' ++ ldLinkerFlags
221 -- we need to find out if ld supports the -x flag
222 configureLd
' :: Verbosity
-> ConfiguredProgram
-> IO ConfiguredProgram
223 configureLd
' verbosity ldProg
= do
224 tempDir
<- getTemporaryDirectory
225 ldx
<- withTempFile tempDir
".c" $ \testcfile testchnd
->
226 withTempFile tempDir
".o" $ \testofile testohnd
-> do
227 hPutStrLn testchnd
"int foo() { return 0; }"
233 [ "-hide-all-packages"
239 withTempFile tempDir
".o" $ \testofile
' testohnd
' ->
246 ["-x", "-r", testofile
, "-o", testofile
']
248 `catchIO`
(\_
-> return False)
249 `catchExit`
(\_
-> return False)
251 then return ldProg
{programDefaultArgs
= ["-x"]}
258 -> IO [(Language
, String)]
259 getLanguages _ implInfo _
260 -- TODO: should be using --supported-languages rather than hard coding
261 | supportsGHC2024 implInfo
=
263 [ (GHC2024
, "-XGHC2024")
264 , (GHC2021
, "-XGHC2021")
265 , (Haskell2010
, "-XHaskell2010")
266 , (Haskell98
, "-XHaskell98")
268 | supportsGHC2021 implInfo
=
270 [ (GHC2021
, "-XGHC2021")
271 , (Haskell2010
, "-XHaskell2010")
272 , (Haskell98
, "-XHaskell98")
274 | supportsHaskell2010 implInfo
=
276 [ (Haskell98
, "-XHaskell98")
277 , (Haskell2010
, "-XHaskell2010")
279 |
otherwise = return [(Haskell98
, "")]
285 -> IO [(String, String)]
286 getGhcInfo verbosity _implInfo ghcProg
= do
290 (suppressOverrideArgs ghcProg
)
297 dieWithException verbosity CantParseGHCOutput
303 -> IO [(Extension
, Maybe String)]
304 getExtensions verbosity implInfo ghcProg
= do
308 (suppressOverrideArgs ghcProg
)
309 ["--supported-languages"]
311 if reportsNoExt implInfo
313 else -- Older GHCs only gave us either Foo or NoFoo,
314 -- so we have to work out the other one ourselves
317 | extStr
<- lines str
318 , let extStr
' = case extStr
of
321 , extStr
'' <- [extStr
, extStr
']
324 [ (ext
, Just
$ "-X" ++ prettyShow ext
)
325 | Just ext
<- map simpleParsec extStrs
328 if alwaysNondecIndent implInfo
329 then -- ghc-7.2 split NondecreasingIndentation off
330 -- into a proper extension. Before that it
332 -- Since it was not a proper extension, it could
333 -- not be turned off, hence we omit a
334 -- DisableExtension entry here.
336 (EnableExtension NondecreasingIndentation
, Nothing
)
341 componentCcGhcOptions
345 -> ComponentLocalBuildInfo
349 componentCcGhcOptions verbosity lbi bi clbi odir filename
=
351 { -- Respect -v0, but don't crank up verbosity on GHC if
352 -- Cabal verbosity is requested. For that, use --ghc-option=-v instead!
353 ghcOptVerbosity
= toFlag
(min verbosity normal
)
354 , ghcOptMode
= toFlag GhcModeCompile
355 , ghcOptInputFiles
= toNubListR
[filename
]
356 , ghcOptCppIncludePath
=
358 [ autogenComponentModulesDir lbi clbi
359 , autogenPackageModulesDir lbi
362 -- includes relative to the package
364 -- potential includes generated by `configure'
365 -- in the build directory
366 ++ [buildDir lbi
</> dir | dir
<- includeDirs bi
]
367 , ghcOptHideAllPackages
= toFlag
True
368 , ghcOptPackageDBs
= withPackageDB lbi
369 , ghcOptPackages
= toNubListR
$ mkGhcOptPackages
(promisedPkgs lbi
) clbi
371 ( case withOptimization lbi
of
375 ++ ( case withDebugInfo lbi
of
377 MinimalDebugInfo
-> ["-g1"]
378 NormalDebugInfo
-> ["-g"]
379 MaximalDebugInfo
-> ["-g3"]
385 <$> lookupProgram gccProgram
(withPrograms lbi
)
386 , ghcOptObjDir
= toFlag odir
387 , ghcOptExtra
= hcOptions GHC bi
390 componentCxxGhcOptions
394 -> ComponentLocalBuildInfo
398 componentCxxGhcOptions verbosity lbi bi clbi odir filename
=
400 { -- Respect -v0, but don't crank up verbosity on GHC if
401 -- Cabal verbosity is requested. For that, use --ghc-option=-v instead!
402 ghcOptVerbosity
= toFlag
(min verbosity normal
)
403 , ghcOptMode
= toFlag GhcModeCompile
404 , ghcOptInputFiles
= toNubListR
[filename
]
405 , ghcOptCppIncludePath
=
407 [ autogenComponentModulesDir lbi clbi
408 , autogenPackageModulesDir lbi
411 -- includes relative to the package
413 -- potential includes generated by `configure'
414 -- in the build directory
415 ++ [buildDir lbi
</> dir | dir
<- includeDirs bi
]
416 , ghcOptHideAllPackages
= toFlag
True
417 , ghcOptPackageDBs
= withPackageDB lbi
418 , ghcOptPackages
= toNubListR
$ mkGhcOptPackages
(promisedPkgs lbi
) clbi
420 ( case withOptimization lbi
of
424 ++ ( case withDebugInfo lbi
of
426 MinimalDebugInfo
-> ["-g1"]
427 NormalDebugInfo
-> ["-g"]
428 MaximalDebugInfo
-> ["-g3"]
434 <$> lookupProgram gccProgram
(withPrograms lbi
)
435 , ghcOptObjDir
= toFlag odir
436 , ghcOptExtra
= hcOptions GHC bi
439 componentAsmGhcOptions
443 -> ComponentLocalBuildInfo
447 componentAsmGhcOptions verbosity lbi bi clbi odir filename
=
449 { -- Respect -v0, but don't crank up verbosity on GHC if
450 -- Cabal verbosity is requested. For that, use --ghc-option=-v instead!
451 ghcOptVerbosity
= toFlag
(min verbosity normal
)
452 , ghcOptMode
= toFlag GhcModeCompile
453 , ghcOptInputFiles
= toNubListR
[filename
]
454 , ghcOptCppIncludePath
=
456 [ autogenComponentModulesDir lbi clbi
457 , autogenPackageModulesDir lbi
460 -- includes relative to the package
462 -- potential includes generated by `configure'
463 -- in the build directory
464 ++ [buildDir lbi
</> dir | dir
<- includeDirs bi
]
465 , ghcOptHideAllPackages
= toFlag
True
466 , ghcOptPackageDBs
= withPackageDB lbi
467 , ghcOptPackages
= toNubListR
$ mkGhcOptPackages
(promisedPkgs lbi
) clbi
469 ( case withOptimization lbi
of
473 ++ ( case withDebugInfo lbi
of
475 MinimalDebugInfo
-> ["-g1"]
476 NormalDebugInfo
-> ["-g"]
477 MaximalDebugInfo
-> ["-g3"]
480 , ghcOptObjDir
= toFlag odir
483 componentJsGhcOptions
487 -> ComponentLocalBuildInfo
491 componentJsGhcOptions verbosity lbi bi clbi odir filename
=
493 { -- Respect -v0, but don't crank up verbosity on GHC if
494 -- Cabal verbosity is requested. For that, use --ghc-option=-v instead!
495 ghcOptVerbosity
= toFlag
(min verbosity normal
)
496 , ghcOptMode
= toFlag GhcModeCompile
497 , ghcOptInputFiles
= toNubListR
[filename
]
498 , ghcOptCppIncludePath
=
500 [ autogenComponentModulesDir lbi clbi
501 , autogenPackageModulesDir lbi
504 -- includes relative to the package
506 -- potential includes generated by `configure'
507 -- in the build directory
508 ++ [buildDir lbi
</> dir | dir
<- includeDirs bi
]
509 , ghcOptHideAllPackages
= toFlag
True
510 , ghcOptPackageDBs
= withPackageDB lbi
511 , ghcOptPackages
= toNubListR
$ mkGhcOptPackages
(promisedPkgs lbi
) clbi
512 , ghcOptObjDir
= toFlag odir
519 -> ComponentLocalBuildInfo
522 componentGhcOptions verbosity lbi bi clbi odir
=
523 let implInfo
= getImplInfo
$ compiler lbi
525 { -- Respect -v0, but don't crank up verbosity on GHC if
526 -- Cabal verbosity is requested. For that, use --ghc-option=-v instead!
527 ghcOptVerbosity
= toFlag
(min verbosity normal
)
528 , ghcOptCabal
= toFlag
True
529 , ghcOptThisUnitId
= case clbi
of
530 LibComponentLocalBuildInfo
{componentCompatPackageKey
= pk
} ->
532 _ |
not (unitIdForExes implInfo
) -> mempty
533 ExeComponentLocalBuildInfo
{componentUnitId
= uid
} ->
534 toFlag
(unUnitId uid
)
535 TestComponentLocalBuildInfo
{componentUnitId
= uid
} ->
536 toFlag
(unUnitId uid
)
537 BenchComponentLocalBuildInfo
{componentUnitId
= uid
} ->
538 toFlag
(unUnitId uid
)
539 FLibComponentLocalBuildInfo
{componentUnitId
= uid
} ->
540 toFlag
(unUnitId uid
)
541 , ghcOptThisComponentId
= case clbi
of
542 LibComponentLocalBuildInfo
543 { componentComponentId
= cid
544 , componentInstantiatedWith
= insts
550 , ghcOptInstantiatedWith
= case clbi
of
551 LibComponentLocalBuildInfo
{componentInstantiatedWith
= insts
} ->
554 , ghcOptNoCode
= toFlag
$ componentIsIndefinite clbi
555 , ghcOptHideAllPackages
= toFlag
True
556 , ghcOptWarnMissingHomeModules
= toFlag
$ flagWarnMissingHomeModules implInfo
557 , ghcOptPackageDBs
= withPackageDB lbi
558 , ghcOptPackages
= toNubListR
$ mkGhcOptPackages mempty clbi
559 , ghcOptSplitSections
= toFlag
(splitSections lbi
)
560 , ghcOptSplitObjs
= toFlag
(splitObjs lbi
)
561 , ghcOptSourcePathClear
= toFlag
True
564 map getSymbolicPath
(hsSourceDirs bi
)
566 ++ [autogenComponentModulesDir lbi clbi
]
567 ++ [autogenPackageModulesDir lbi
]
568 , ghcOptCppIncludePath
=
570 [ autogenComponentModulesDir lbi clbi
571 , autogenPackageModulesDir lbi
574 -- includes relative to the package
576 -- potential includes generated by `configure'
577 -- in the build directory
578 ++ [buildDir lbi
</> dir | dir
<- includeDirs bi
]
579 , ghcOptCppOptions
= cppOptions bi
580 , ghcOptCppIncludes
=
582 [autogenComponentModulesDir lbi clbi
</> cppHeaderName
]
583 , ghcOptFfiIncludes
= toNubListR
$ includes bi
584 , ghcOptObjDir
= toFlag odir
585 , ghcOptHiDir
= toFlag odir
586 , ghcOptHieDir
= bool NoFlag
(toFlag
$ odir
</> extraCompilationArtifacts
</> "hie") $ flagHie implInfo
587 , ghcOptStubDir
= toFlag odir
588 , ghcOptOutputDir
= toFlag odir
589 , ghcOptOptimisation
= toGhcOptimisation
(withOptimization lbi
)
590 , ghcOptDebugInfo
= toFlag
(withDebugInfo lbi
)
591 , ghcOptExtra
= hcOptions GHC bi
592 , ghcOptExtraPath
= toNubListR
$ exe_paths
593 , ghcOptLanguage
= toFlag
(fromMaybe Haskell98
(defaultLanguage bi
))
594 , -- Unsupported extensions have already been checked by configure
595 ghcOptExtensions
= toNubListR
$ usedExtensions bi
596 , ghcOptExtensionMap
= Map
.fromList
. compilerExtensions
$ (compiler lbi
)
600 [ componentBuildDir lbi
(targetCLBI exe_tgt
)
601 | uid
<- componentExeDeps clbi
602 , -- TODO: Ugh, localPkgDescr
603 Just exe_tgt
<- [unitIdTarget
' (localPkgDescr lbi
) lbi uid
]
606 toGhcOptimisation
:: OptimisationLevel
-> Flag GhcOptimisation
607 toGhcOptimisation NoOptimisation
= mempty
-- TODO perhaps override?
608 toGhcOptimisation NormalOptimisation
= toFlag GhcNormalOptimisation
609 toGhcOptimisation MaximumOptimisation
= toFlag GhcMaximumOptimisation
611 componentCmmGhcOptions
615 -> ComponentLocalBuildInfo
619 componentCmmGhcOptions verbosity lbi bi clbi odir filename
=
621 { -- Respect -v0, but don't crank up verbosity on GHC if
622 -- Cabal verbosity is requested. For that, use --ghc-option=-v instead!
623 ghcOptVerbosity
= toFlag
(min verbosity normal
)
624 , ghcOptMode
= toFlag GhcModeCompile
625 , ghcOptInputFiles
= toNubListR
[filename
]
626 , ghcOptCppIncludePath
=
628 [ autogenComponentModulesDir lbi clbi
629 , autogenPackageModulesDir lbi
632 -- includes relative to the package
634 -- potential includes generated by `configure'
635 -- in the build directory
636 ++ [buildDir lbi
</> dir | dir
<- includeDirs bi
]
637 , ghcOptCppOptions
= cppOptions bi
638 , ghcOptCppIncludes
=
640 [autogenComponentModulesDir lbi clbi
</> cppHeaderName
]
641 , ghcOptHideAllPackages
= toFlag
True
642 , ghcOptPackageDBs
= withPackageDB lbi
643 , ghcOptPackages
= toNubListR
$ mkGhcOptPackages
(promisedPkgs lbi
) clbi
644 , ghcOptOptimisation
= toGhcOptimisation
(withOptimization lbi
)
645 , ghcOptDebugInfo
= toFlag
(withDebugInfo lbi
)
646 , ghcOptExtra
= cmmOptions bi
647 , ghcOptObjDir
= toFlag odir
650 -- | Strip out flags that are not supported in ghci
651 filterGhciFlags
:: [String] -> [String]
652 filterGhciFlags
= filter supported
654 supported
('-' : 'O
' : _
) = False
655 supported
"-debug" = False
656 supported
"-threaded" = False
657 supported
"-ticky" = False
658 supported
"-eventlog" = False
659 supported
"-prof" = False
660 supported
"-unreg" = False
663 mkGHCiLibName
:: UnitId
-> String
664 mkGHCiLibName lib
= getHSLibraryName lib
<.> "o"
666 mkGHCiProfLibName
:: UnitId
-> String
667 mkGHCiProfLibName lib
= getHSLibraryName lib
<.> "p_o"
669 ghcLookupProperty
:: String -> Compiler
-> Bool
670 ghcLookupProperty prop comp
=
671 case Map
.lookup prop
(compilerProperties comp
) of
675 -- when using -split-objs, we need to search for object files in the
676 -- Module_split directory for each module.
681 -> ComponentLocalBuildInfo
686 getHaskellObjects _implInfo lib lbi clbi pref wanted_obj_ext allow_split_objs
687 | splitObjs lbi
&& allow_split_objs
= do
688 let splitSuffix
= "_" ++ wanted_obj_ext
++ "_split"
690 [ pref
</> (ModuleName
.toFilePath x
++ splitSuffix
)
691 | x
<- allLibModules lib clbi
693 objss
<- traverse
getDirectoryContents dirs
696 |
(objs
', dir
) <- zip objss dirs
698 , let obj_ext
= takeExtension obj
699 , '.' : wanted_obj_ext
== obj_ext
704 [ pref
</> ModuleName
.toFilePath x
<.> wanted_obj_ext
705 | x
<- allLibModules lib clbi
708 -- | Create the required packaged arguments, but filtering out package arguments which
709 -- aren't yet built, but promised. This filtering is used when compiling C/Cxx/Asm files,
710 -- and is a hack to avoid passing bogus `-package` arguments to GHC. The assumption being that
711 -- in 99% of cases we will include the right `-package` so that the C file finds the right headers.
713 :: Map
(PackageName
, ComponentName
) ComponentId
714 -> ComponentLocalBuildInfo
715 -> [(OpenUnitId
, ModuleRenaming
)]
716 mkGhcOptPackages promisedPkgsMap clbi
=
717 [ i | i
@(uid
, _
) <- componentIncludes clbi
, abstractUnitId uid `Set
.notMember` promised_cids
720 -- Promised deps are going to be simple UnitIds
721 promised_cids
= Set
.fromList
(map newSimpleUnitId
(Map
.elems promisedPkgsMap
))
723 substTopDir
:: FilePath -> IPI
.InstalledPackageInfo
-> IPI
.InstalledPackageInfo
724 substTopDir topDir ipo
=
726 { IPI
.importDirs
= map f
(IPI
.importDirs ipo
)
727 , IPI
.libraryDirs
= map f
(IPI
.libraryDirs ipo
)
728 , IPI
.libraryDirsStatic
= map f
(IPI
.libraryDirsStatic ipo
)
729 , IPI
.includeDirs
= map f
(IPI
.includeDirs ipo
)
730 , IPI
.frameworkDirs
= map f
(IPI
.frameworkDirs ipo
)
731 , IPI
.haddockInterfaces
= map f
(IPI
.haddockInterfaces ipo
)
732 , IPI
.haddockHTMLs
= map f
(IPI
.haddockHTMLs ipo
)
735 f
('$' : 't
' : 'o
' : 'p
' : 'd
' : 'i
' : 'r
' : rest
) = topDir
++ rest
738 -- Cabal does not use the environment variable GHC{,JS}_PACKAGE_PATH; let
739 -- users know that this is the case. See ticket #335. Simply ignoring it is
740 -- not a good idea, since then ghc and cabal are looking at different sets
741 -- of package DBs and chaos is likely to ensue.
743 -- An exception to this is when running cabal from within a `cabal exec`
744 -- environment. In this case, `cabal exec` will set the
745 -- CABAL_SANDBOX_PACKAGE_PATH to the same value that it set
746 -- GHC{,JS}_PACKAGE_PATH to. If that is the case it is OK to allow
747 -- GHC{,JS}_PACKAGE_PATH.
748 checkPackageDbEnvVar
:: Verbosity
-> String -> String -> IO ()
749 checkPackageDbEnvVar verbosity compilerName packagePathEnvVar
= do
750 mPP
<- lookupEnv packagePathEnvVar
751 when (isJust mPP
) $ do
752 mcsPP
<- lookupEnv
"CABAL_SANDBOX_PACKAGE_PATH"
753 unless (mPP
== mcsPP
) abort
755 lookupEnv
:: String -> IO (Maybe String)
757 (Just `
fmap`
getEnv name
)
758 `catchIO`
const (return Nothing
)
760 dieWithException verbosity
$ IncompatibleWithCabal compilerName packagePathEnvVar
761 _
= callStack
-- TODO: output stack when erroring
763 profDetailLevelFlag
:: Bool -> ProfDetailLevel
-> Flag GhcProfAuto
764 profDetailLevelFlag forLib mpl
=
766 ProfDetailNone
-> mempty
768 | forLib
-> toFlag GhcProfAutoExported
769 |
otherwise -> toFlag GhcProfAutoToplevel
770 ProfDetailExportedFunctions
-> toFlag GhcProfAutoExported
771 ProfDetailToplevelFunctions
-> toFlag GhcProfAutoToplevel
772 ProfDetailAllFunctions
-> toFlag GhcProfAutoAll
773 ProfDetailTopLate
-> toFlag GhcProfLate
774 ProfDetailOther _
-> mempty
776 -- -----------------------------------------------------------------------------
777 -- GHC platform and version strings
779 -- | GHC's rendering of its host or target 'Arch' as used in its platform
780 -- strings and certain file locations (such as user package db location).
781 ghcArchString
:: Arch
-> String
782 ghcArchString PPC
= "powerpc"
783 ghcArchString PPC64
= "powerpc64"
784 ghcArchString PPC64LE
= "powerpc64le"
785 ghcArchString other
= prettyShow other
787 -- | GHC's rendering of its host or target 'OS' as used in its platform
788 -- strings and certain file locations (such as user package db location).
789 ghcOsString
:: OS
-> String
790 ghcOsString Windows
= "mingw32"
791 ghcOsString OSX
= "darwin"
792 ghcOsString Solaris
= "solaris2"
793 ghcOsString Hurd
= "gnu"
794 ghcOsString other
= prettyShow other
796 -- | GHC's rendering of its platform and compiler version string as used in
797 -- certain file locations (such as user package db location).
798 -- For example @x86_64-linux-7.10.4@
799 ghcPlatformAndVersionString
:: Platform
-> Version
-> String
800 ghcPlatformAndVersionString
(Platform arch os
) version
=
801 intercalate
"-" [ghcArchString arch
, ghcOsString os
, prettyShow version
]
803 -- -----------------------------------------------------------------------------
804 -- Constructing GHC environment files
806 -- | The kinds of entries we can stick in a @.ghc.environment@ file.
807 data GhcEnvironmentFileEntry
808 = -- | @-- a comment@
809 GhcEnvFileComment
String
810 |
-- | @package-id foo-1.0-4fe301a...@
811 GhcEnvFilePackageId UnitId
812 |
-- | @global-package-db@,
813 -- @user-package-db@ or
814 -- @package-db blah/package.conf.d/@
815 GhcEnvFilePackageDb PackageDB
816 |
-- | @clear-package-db@
817 GhcEnvFileClearPackageDbStack
818 deriving (Eq
, Ord
, Show)
820 -- | Make entries for a GHC environment file based on a 'PackageDBStack' and
821 -- a bunch of package (unit) ids.
823 -- If you need to do anything more complicated then either use this as a basis
824 -- and add more entries, or just make all the entries directly.
825 simpleGhcEnvironmentFile
828 -> [GhcEnvironmentFileEntry
]
829 simpleGhcEnvironmentFile packageDBs pkgids
=
830 GhcEnvFileClearPackageDbStack
831 : map GhcEnvFilePackageDb packageDBs
832 ++ map GhcEnvFilePackageId pkgids
834 -- | Write a @.ghc.environment-$arch-$os-$ver@ file in the given directory.
836 -- The 'Platform' and GHC 'Version' are needed as part of the file name.
838 -- Returns the name of the file written.
839 writeGhcEnvironmentFile
841 -- ^ directory in which to put it
843 -- ^ the GHC target platform
846 -> [GhcEnvironmentFileEntry
]
849 writeGhcEnvironmentFile directory platform ghcversion entries
= do
850 writeFileAtomic envfile
. BS
.pack
. renderGhcEnvironmentFile
$ entries
853 envfile
= directory
</> ghcEnvironmentFileName platform ghcversion
855 -- | The @.ghc.environment-$arch-$os-$ver@ file name
856 ghcEnvironmentFileName
:: Platform
-> Version
-> FilePath
857 ghcEnvironmentFileName platform ghcversion
=
858 ".ghc.environment." ++ ghcPlatformAndVersionString platform ghcversion
860 -- | Render a bunch of GHC environment file entries
861 renderGhcEnvironmentFile
:: [GhcEnvironmentFileEntry
] -> String
862 renderGhcEnvironmentFile
=
863 unlines . map renderGhcEnvironmentFileEntry
865 -- | Render an individual GHC environment file entry
866 renderGhcEnvironmentFileEntry
:: GhcEnvironmentFileEntry
-> String
867 renderGhcEnvironmentFileEntry entry
= case entry
of
868 GhcEnvFileComment comment
-> format comment
870 format
= intercalate
"\n" . map ("--" <++>) . lines
872 pref
<++> str
= pref
++ " " ++ str
873 GhcEnvFilePackageId pkgid
-> "package-id " ++ prettyShow pkgid
874 GhcEnvFilePackageDb pkgdb
->
876 GlobalPackageDB
-> "global-package-db"
877 UserPackageDB
-> "user-package-db"
878 SpecificPackageDB dbfile
-> "package-db " ++ dbfile
879 GhcEnvFileClearPackageDbStack
-> "clear-package-db"