summaryrefslogtreecommitdiff
path: root/hadrian/src/Oracles
diff options
context:
space:
mode:
Diffstat (limited to 'hadrian/src/Oracles')
-rw-r--r--hadrian/src/Oracles/Flag.hs74
-rw-r--r--hadrian/src/Oracles/ModuleFiles.hs160
-rw-r--r--hadrian/src/Oracles/PackageData.hs66
-rw-r--r--hadrian/src/Oracles/Setting.hs236
4 files changed, 0 insertions, 536 deletions
diff --git a/hadrian/src/Oracles/Flag.hs b/hadrian/src/Oracles/Flag.hs
deleted file mode 100644
index 1bd4dfeefd..0000000000
--- a/hadrian/src/Oracles/Flag.hs
+++ /dev/null
@@ -1,74 +0,0 @@
-module Oracles.Flag (
- Flag (..), flag, crossCompiling, platformSupportsSharedLibs,
- ghcWithSMP, ghcWithNativeCodeGen, supportsSplitObjects
- ) where
-
-import Hadrian.Oracles.TextFile
-
-import Base
-import Oracles.Setting
-
-data Flag = ArSupportsAtFile
- | CrossCompiling
- | GccIsClang
- | GhcUnregisterised
- | LeadingUnderscore
- | SolarisBrokenShld
- | SplitObjectsBroken
- | WithLibdw
- | HaveLibMingwEx
- | UseSystemFfi
-
--- Note, if a flag is set to empty string we treat it as set to NO. This seems
--- fragile, but some flags do behave like this, e.g. GccIsClang.
-flag :: Flag -> Action Bool
-flag f = do
- let key = case f of
- ArSupportsAtFile -> "ar-supports-at-file"
- CrossCompiling -> "cross-compiling"
- GccIsClang -> "gcc-is-clang"
- GhcUnregisterised -> "ghc-unregisterised"
- LeadingUnderscore -> "leading-underscore"
- SolarisBrokenShld -> "solaris-broken-shld"
- SplitObjectsBroken -> "split-objects-broken"
- WithLibdw -> "with-libdw"
- HaveLibMingwEx -> "have-lib-mingw-ex"
- UseSystemFfi -> "use-system-ffi"
- value <- lookupValueOrError configFile key
- when (value `notElem` ["YES", "NO", ""]) . error $ "Configuration flag "
- ++ quote (key ++ " = " ++ value) ++ " cannot be parsed."
- return $ value == "YES"
-
-crossCompiling :: Action Bool
-crossCompiling = flag CrossCompiling
-
-platformSupportsSharedLibs :: Action Bool
-platformSupportsSharedLibs = do
- badPlatform <- anyTargetPlatform [ "powerpc-unknown-linux"
- , "x86_64-unknown-mingw32"
- , "i386-unknown-mingw32" ]
- solaris <- anyTargetPlatform [ "i386-unknown-solaris2" ]
- solarisBroken <- flag SolarisBrokenShld
- return $ not (badPlatform || solaris && solarisBroken)
-
-ghcWithSMP :: Action Bool
-ghcWithSMP = do
- goodArch <- anyTargetArch ["i386", "x86_64", "sparc", "powerpc", "arm"]
- ghcUnreg <- flag GhcUnregisterised
- return $ goodArch && not ghcUnreg
-
-ghcWithNativeCodeGen :: Action Bool
-ghcWithNativeCodeGen = do
- goodArch <- anyTargetArch ["i386", "x86_64", "sparc", "powerpc"]
- badOs <- anyTargetOs ["ios", "aix"]
- ghcUnreg <- flag GhcUnregisterised
- return $ goodArch && not badOs && not ghcUnreg
-
-supportsSplitObjects :: Action Bool
-supportsSplitObjects = do
- broken <- flag SplitObjectsBroken
- ghcUnreg <- flag GhcUnregisterised
- goodArch <- anyTargetArch [ "i386", "x86_64", "powerpc", "sparc" ]
- goodOs <- anyTargetOs [ "mingw32", "cygwin32", "linux", "darwin", "solaris2"
- , "freebsd", "dragonfly", "netbsd", "openbsd" ]
- return $ not broken && not ghcUnreg && goodArch && goodOs
diff --git a/hadrian/src/Oracles/ModuleFiles.hs b/hadrian/src/Oracles/ModuleFiles.hs
deleted file mode 100644
index c7175dbc1c..0000000000
--- a/hadrian/src/Oracles/ModuleFiles.hs
+++ /dev/null
@@ -1,160 +0,0 @@
-{-# LANGUAGE TypeFamilies #-}
-module Oracles.ModuleFiles (
- decodeModule, encodeModule, findGenerator, hsSources, hsObjects, moduleFilesOracle
- ) where
-
-import qualified Data.HashMap.Strict as Map
-
-import Base
-import Builder
-import Context
-import GHC
-import Oracles.PackageData
-
-newtype ModuleFiles = ModuleFiles (Stage, Package)
- deriving (Binary, Eq, Hashable, NFData, Show, Typeable)
-type instance RuleResult ModuleFiles = [Maybe FilePath]
-
-newtype Generator = Generator (Stage, Package, FilePath)
- deriving (Binary, Eq, Hashable, NFData, Show, Typeable)
-type instance RuleResult Generator = Maybe FilePath
-
--- | We scan for the following Haskell source extensions when looking for module
--- files. Note, we do not list "*.(l)hs-boot" files here, as they can never
--- appear by themselves and always have accompanying "*.(l)hs" master files.
-haskellExtensions :: [String]
-haskellExtensions = [".hs", ".lhs"]
-
--- | Non-Haskell source extensions and corresponding builders.
-otherExtensions :: [(String, Builder)]
-otherExtensions = [ (".x" , Alex )
- , (".y" , Happy )
- , (".ly" , Happy )
- , (".hsc", Hsc2Hs) ]
-
--- | We match the following file patterns when looking for module files.
-moduleFilePatterns :: [FilePattern]
-moduleFilePatterns = map ("*" ++) $ haskellExtensions ++ map fst otherExtensions
-
--- | Given a FilePath determine the corresponding builder.
-determineBuilder :: FilePath -> Maybe Builder
-determineBuilder file = lookup (takeExtension file) otherExtensions
-
--- | Given a module name extract the directory and file name, e.g.:
---
--- > decodeModule "Data.Functor.Identity" == ("Data/Functor", "Identity")
--- > decodeModule "Prelude" == ("", "Prelude")
-decodeModule :: String -> (FilePath, String)
-decodeModule modName = (intercalate "/" (init xs), last xs)
- where
- xs = words $ replaceEq '.' ' ' modName
-
--- | Given the directory and file name find the corresponding module name, e.g.:
---
--- > encodeModule "Data/Functor" "Identity.hs" == "Data.Functor.Identity"
--- > encodeModule "" "Prelude" == "Prelude"
--- > uncurry encodeModule (decodeModule name) == name
-encodeModule :: FilePath -> String -> String
-encodeModule dir file
- | dir == "" = takeBaseName file
- | otherwise = replaceEq '/' '.' dir ++ '.' : takeBaseName file
-
--- | Find the generator for a given 'Context' and a source file. For example:
--- findGenerator (Context Stage1 compiler vanilla)
--- "_build/stage1/compiler/build/Lexer.hs"
--- == Just ("compiler/parser/Lexer.x", Alex)
--- findGenerator (Context Stage1 base vanilla)
--- "_build/stage1/base/build/Prelude.hs"
--- == Nothing
-findGenerator :: Context -> FilePath -> Action (Maybe (FilePath, Builder))
-findGenerator Context {..} file = do
- maybeSource <- askOracle $ Generator (stage, package, file)
- return $ do
- source <- maybeSource
- builder <- determineBuilder source
- return (source, builder)
-
--- | Find all Haskell source files for a given 'Context'.
-hsSources :: Context -> Action [FilePath]
-hsSources context = do
- let modFile (m, Nothing ) = generatedFile context m
- modFile (m, Just file )
- | takeExtension file `elem` haskellExtensions = return file
- | otherwise = generatedFile context m
- mapM modFile =<< contextFiles context
-
--- | Find all Haskell object files for a given 'Context'. Note: this is a much
--- simpler function compared to 'hsSources', because all object files live in
--- the build directory regardless of whether they are generated or not.
-hsObjects :: Context -> Action [FilePath]
-hsObjects context = do
- path <- buildPath context
- modules <- pkgDataList (Modules path)
- -- GHC.Prim module is only for documentation, we do not actually build it.
- mapM (objectPath context . moduleSource) (filter (/= "GHC.Prim") modules)
-
--- | Generated module files live in the 'Context' specific build directory.
-generatedFile :: Context -> String -> Action FilePath
-generatedFile context moduleName = do
- path <- buildPath context
- return $ path -/- moduleSource moduleName
-
-moduleSource :: String -> FilePath
-moduleSource moduleName = replaceEq '.' '/' moduleName <.> "hs"
-
--- | Module files for a given 'Context'.
-contextFiles :: Context -> Action [(String, Maybe FilePath)]
-contextFiles context@Context {..} = do
- path <- buildPath context
- modules <- fmap sort . pkgDataList $ Modules path
- zip modules <$> askOracle (ModuleFiles (stage, package))
-
--- | This is an important oracle whose role is to find and cache module source
--- files. It takes a 'Stage' and a 'Package', looks up corresponding source
--- directories @dirs@ and a sorted list of module names @modules@, and for each
--- module, e.g. @A.B.C@, returns a 'FilePath' of the form @dir/A/B/C.extension@,
--- such that @dir@ belongs to @dirs@, and file @dir/A/B/C.extension@ exists, or
--- 'Nothing' if there is no such file. If more than one matching file is found
--- an error is raised. For example, for 'Stage1' and 'compiler', @dirs@ will
--- contain ["compiler/codeGen", "compiler/parser"], and @modules@ will contain
--- ["CodeGen.Platform.ARM", "Config", "Lexer"]; the oracle will produce a list
--- containing [Just "compiler/codeGen/CodeGen/Platform/ARM.hs", Nothing,
--- Just "compiler/parser/Lexer.x"]. The oracle ignores @.(l)hs-boot@ files.
-moduleFilesOracle :: Rules ()
-moduleFilesOracle = void $ do
- void . addOracle $ \(ModuleFiles (stage, package)) -> do
- let context = vanillaContext stage package
- path <- buildPath context
- srcDirs <- pkgDataList $ SrcDirs path
- modules <- fmap sort . pkgDataList $ Modules path
- autogen <- autogenPath context
- let dirs = autogen : map (pkgPath package -/-) srcDirs
- modDirFiles = groupSort $ map decodeModule modules
- result <- concatForM dirs $ \dir -> do
- todo <- filterM (doesDirectoryExist . (dir -/-) . fst) modDirFiles
- forM todo $ \(mDir, mFiles) -> do
- let fullDir = unifyPath $ dir -/- mDir
- files <- getDirectoryFiles fullDir moduleFilePatterns
- let cmp f = compare (dropExtension f)
- found = intersectOrd cmp files mFiles
- return (map (fullDir -/-) found, mDir)
- let pairs = sort [ (encodeModule d f, f) | (fs, d) <- result, f <- fs ]
- multi = [ (m, f1, f2) | (m, f1):(n, f2):_ <- tails pairs, m == n ]
- unless (null multi) $ do
- let (m, f1, f2) = head multi
- error $ "Module " ++ m ++ " has more than one source file: "
- ++ f1 ++ " and " ++ f2 ++ "."
- return $ lookupAll modules pairs
-
- -- Optimisation: we discard Haskell files here, because they are never used
- -- as generators, and hence would be discarded in 'findGenerator' anyway.
- generators <- newCache $ \(stage, package) -> do
- let context = vanillaContext stage package
- files <- contextFiles context
- list <- sequence [ (,src) <$> generatedFile context modName
- | (modName, Just src) <- files
- , takeExtension src `notElem` haskellExtensions ]
- return $ Map.fromList list
-
- addOracle $ \(Generator (stage, package, file)) ->
- Map.lookup file <$> generators (stage, package)
diff --git a/hadrian/src/Oracles/PackageData.hs b/hadrian/src/Oracles/PackageData.hs
deleted file mode 100644
index cdfe9bfb48..0000000000
--- a/hadrian/src/Oracles/PackageData.hs
+++ /dev/null
@@ -1,66 +0,0 @@
-module Oracles.PackageData (
- PackageData (..), PackageDataList (..), pkgData, pkgDataList
- ) where
-
-import Hadrian.Oracles.TextFile
-
-import Base
-
-newtype PackageData = BuildGhciLib FilePath
-
-data PackageDataList = AsmSrcs FilePath
- | CcArgs FilePath
- | CSrcs FilePath
- | CmmSrcs FilePath
- | CppArgs FilePath
- | DepCcArgs FilePath
- | DepExtraLibs FilePath
- | DepIds FilePath
- | DepIncludeDirs FilePath
- | DepLdArgs FilePath
- | DepLibDirs FilePath
- | DepNames FilePath
- | Deps FilePath
- | HiddenModules FilePath
- | HsArgs FilePath
- | IncludeDirs FilePath
- | LdArgs FilePath
- | Modules FilePath
- | SrcDirs FilePath
-
-askPackageData :: FilePath -> String -> Action String
-askPackageData path = lookupValueOrEmpty (path -/- "package-data.mk")
-
--- | For each @PackageData path@ the file 'path/package-data.mk' contains a line
--- of the form 'path_VERSION = 1.2.3.4'. @pkgData (PackageData path)@ is an
--- Action that consults the file and returns "1.2.3.4".
-pkgData :: PackageData -> Action String
-pkgData packageData = case packageData of
- BuildGhciLib path -> askPackageData path "BUILD_GHCI_LIB"
-
--- | @PackageDataList path@ is used for multiple string options separated by
--- spaces, such as @path_MODULES = Data.Array Data.Array.Base ...@.
--- @pkgListData Modules@ therefore returns ["Data.Array", "Data.Array.Base", ...]
-pkgDataList :: PackageDataList -> Action [String]
-pkgDataList packageData = fmap (map unquote . words) $ case packageData of
- AsmSrcs path -> askPackageData path "S_SRCS"
- CcArgs path -> askPackageData path "CC_OPTS"
- CSrcs path -> askPackageData path "C_SRCS"
- CmmSrcs path -> askPackageData path "CMM_SRCS"
- CppArgs path -> askPackageData path "CPP_OPTS"
- DepCcArgs path -> askPackageData path "DEP_CC_OPTS"
- DepExtraLibs path -> askPackageData path "DEP_EXTRA_LIBS"
- DepIds path -> askPackageData path "DEP_IPIDS"
- DepIncludeDirs path -> askPackageData path "DEP_INCLUDE_DIRS_SINGLE_QUOTED"
- DepLibDirs path -> askPackageData path "DEP_LIB_DIRS_SINGLE_QUOTED"
- DepLdArgs path -> askPackageData path "DEP_LD_OPTS"
- DepNames path -> askPackageData path "DEP_NAMES"
- Deps path -> askPackageData path "DEPS"
- HiddenModules path -> askPackageData path "HIDDEN_MODULES"
- HsArgs path -> askPackageData path "HC_OPTS"
- IncludeDirs path -> askPackageData path "INCLUDE_DIRS"
- LdArgs path -> askPackageData path "LD_OPTS"
- Modules path -> askPackageData path "MODULES"
- SrcDirs path -> askPackageData path "HS_SRC_DIRS"
- where
- unquote = dropWhile (== '\'') . dropWhileEnd (== '\'')
diff --git a/hadrian/src/Oracles/Setting.hs b/hadrian/src/Oracles/Setting.hs
deleted file mode 100644
index aa49011e1e..0000000000
--- a/hadrian/src/Oracles/Setting.hs
+++ /dev/null
@@ -1,236 +0,0 @@
-module Oracles.Setting (
- configFile, Setting (..), SettingList (..), setting, settingList, getSetting,
- getSettingList, anyTargetPlatform, anyTargetOs, anyTargetArch, anyHostOs,
- ghcWithInterpreter, ghcEnableTablesNextToCode, useLibFFIForAdjustors,
- ghcCanonVersion, cmdLineLengthLimit, iosHost, osxHost, windowsHost,
- topDirectory, relocatableBuild, installDocDir, installGhcLibDir, libsuf
- ) where
-
-import Hadrian.Expression
-import Hadrian.Oracles.TextFile
-import Hadrian.Oracles.Path
-
-import Base
-
--- TODO: Reduce the variety of similar flags (e.g. CPP and non-CPP versions).
--- | Each 'Setting' comes from @system.config@ file, e.g. 'target-os = mingw32'.
--- @setting TargetOs@ looks up the config file and returns "mingw32".
--- 'SettingList' is used for multiple string values separated by spaces, such
--- as @gmp-include-dirs = a b@.
--- @settingList GmpIncludeDirs@ therefore returns a list of strings ["a", "b"].
-data Setting = BuildArch
- | BuildOs
- | BuildPlatform
- | BuildVendor
- | CcClangBackend
- | CcLlvmBackend
- | DynamicExtension
- | GhcMajorVersion
- | GhcMinorVersion
- | GhcPatchLevel
- | GhcVersion
- | GhcSourcePath
- | HostArch
- | HostOs
- | HostPlatform
- | HostVendor
- | ProjectGitCommitId
- | ProjectName
- | ProjectVersion
- | ProjectVersionInt
- | ProjectPatchLevel
- | ProjectPatchLevel1
- | ProjectPatchLevel2
- | TargetArch
- | TargetOs
- | TargetPlatform
- | TargetPlatformFull
- | TargetVendor
- | LlvmTarget
- | FfiIncludeDir
- | FfiLibDir
- | GmpIncludeDir
- | GmpLibDir
- | IconvIncludeDir
- | IconvLibDir
- | CursesLibDir
- -- Paths to where GHC is installed (ref: mk/install.mk)
- | InstallPrefix
- | InstallBinDir
- | InstallLibDir
- | InstallDataRootDir
- -- Command lines for invoking the @install@ utility
- | Install
- | InstallData
- | InstallProgram
- | InstallScript
- | InstallDir
- -- Command line for creating a symbolic link
- | LnS
-
-data SettingList = ConfCcArgs Stage
- | ConfCppArgs Stage
- | ConfGccLinkerArgs Stage
- | ConfLdLinkerArgs Stage
- | HsCppArgs
-
--- | Maps 'Setting's to names in @cfg/system.config.in@.
-setting :: Setting -> Action String
-setting key = lookupValueOrError configFile $ case key of
- BuildArch -> "build-arch"
- BuildOs -> "build-os"
- BuildPlatform -> "build-platform"
- BuildVendor -> "build-vendor"
- CcClangBackend -> "cc-clang-backend"
- CcLlvmBackend -> "cc-llvm-backend"
- DynamicExtension -> "dynamic-extension"
- GhcMajorVersion -> "ghc-major-version"
- GhcMinorVersion -> "ghc-minor-version"
- GhcPatchLevel -> "ghc-patch-level"
- GhcVersion -> "ghc-version"
- GhcSourcePath -> "ghc-source-path"
- HostArch -> "host-arch"
- HostOs -> "host-os"
- HostPlatform -> "host-platform"
- HostVendor -> "host-vendor"
- ProjectGitCommitId -> "project-git-commit-id"
- ProjectName -> "project-name"
- ProjectVersion -> "project-version"
- ProjectVersionInt -> "project-version-int"
- ProjectPatchLevel -> "project-patch-level"
- ProjectPatchLevel1 -> "project-patch-level1"
- ProjectPatchLevel2 -> "project-patch-level2"
- TargetArch -> "target-arch"
- TargetOs -> "target-os"
- TargetPlatform -> "target-platform"
- TargetPlatformFull -> "target-platform-full"
- TargetVendor -> "target-vendor"
- LlvmTarget -> "llvm-target"
- FfiIncludeDir -> "ffi-include-dir"
- FfiLibDir -> "ffi-lib-dir"
- GmpIncludeDir -> "gmp-include-dir"
- GmpLibDir -> "gmp-lib-dir"
- IconvIncludeDir -> "iconv-include-dir"
- IconvLibDir -> "iconv-lib-dir"
- CursesLibDir -> "curses-lib-dir"
- InstallPrefix -> "install-prefix"
- InstallBinDir -> "install-bindir"
- InstallLibDir -> "install-libdir"
- InstallDataRootDir -> "install-datarootdir"
- Install -> "install"
- InstallDir -> "install-dir"
- InstallProgram -> "install-program"
- InstallScript -> "install-script"
- InstallData -> "install-data"
- LnS -> "ln-s"
-
-settingList :: SettingList -> Action [String]
-settingList key = fmap words $ lookupValueOrError configFile $ case key of
- ConfCcArgs stage -> "conf-cc-args-" ++ stageString stage
- ConfCppArgs stage -> "conf-cpp-args-" ++ stageString stage
- ConfGccLinkerArgs stage -> "conf-gcc-linker-args-" ++ stageString stage
- ConfLdLinkerArgs stage -> "conf-ld-linker-args-" ++ stageString stage
- HsCppArgs -> "hs-cpp-args"
-
--- | Get a configuration setting.
-getSetting :: Setting -> Expr c b String
-getSetting = expr . setting
-
--- | Get a list of configuration settings.
-getSettingList :: SettingList -> Args c b
-getSettingList = expr . settingList
-
-matchSetting :: Setting -> [String] -> Action Bool
-matchSetting key values = (`elem` values) <$> setting key
-
-anyTargetPlatform :: [String] -> Action Bool
-anyTargetPlatform = matchSetting TargetPlatformFull
-
-anyTargetOs :: [String] -> Action Bool
-anyTargetOs = matchSetting TargetOs
-
-anyTargetArch :: [String] -> Action Bool
-anyTargetArch = matchSetting TargetArch
-
-anyHostOs :: [String] -> Action Bool
-anyHostOs = matchSetting HostOs
-
-iosHost :: Action Bool
-iosHost = anyHostOs ["ios"]
-
-osxHost :: Action Bool
-osxHost = anyHostOs ["darwin"]
-
-windowsHost :: Action Bool
-windowsHost = anyHostOs ["mingw32", "cygwin32"]
-
-ghcWithInterpreter :: Action Bool
-ghcWithInterpreter = do
- goodOs <- anyTargetOs [ "mingw32", "cygwin32", "linux", "solaris2"
- , "freebsd", "dragonfly", "netbsd", "openbsd"
- , "darwin", "kfreebsdgnu" ]
- goodArch <- anyTargetArch [ "i386", "x86_64", "powerpc", "sparc"
- , "sparc64", "arm" ]
- return $ goodOs && goodArch
-
-ghcEnableTablesNextToCode :: Action Bool
-ghcEnableTablesNextToCode = notM $ anyTargetArch ["ia64", "powerpc64", "powerpc64le"]
-
-useLibFFIForAdjustors :: Action Bool
-useLibFFIForAdjustors = notM $ anyTargetArch ["i386", "x86_64"]
-
--- | Canonicalised GHC version number, used for integer version comparisons. We
--- expand GhcMinorVersion to two digits by adding a leading zero if necessary.
-ghcCanonVersion :: Action String
-ghcCanonVersion = do
- ghcMajorVersion <- setting GhcMajorVersion
- ghcMinorVersion <- setting GhcMinorVersion
- let leadingZero = [ '0' | length ghcMinorVersion == 1 ]
- return $ ghcMajorVersion ++ leadingZero ++ ghcMinorVersion
-
--- ref: https://ghc.haskell.org/trac/ghc/wiki/Building/Installing#HowGHCfindsitsfiles
--- | On Windows we normally build a relocatable installation, which assumes that
--- the library directory @libdir@ is in a fixed location relative to the GHC
--- binary, namely @../lib@.
-relocatableBuild :: Action Bool
-relocatableBuild = windowsHost
-
-installDocDir :: Action String
-installDocDir = do
- version <- setting ProjectVersion
- dataDir <- setting InstallDataRootDir
- return $ dataDir -/- ("doc/ghc-" ++ version)
-
--- | Path to the GHC source tree.
-topDirectory :: Action FilePath
-topDirectory = fixAbsolutePathOnWindows =<< setting GhcSourcePath
-
--- ref: mk/install.mk:101
--- TODO: CroosCompilePrefix
--- | Unix: override @libdir@ and @datadir@ to put GHC-specific files in a
--- subdirectory with the version number included.
-installGhcLibDir :: Action String
-installGhcLibDir = do
- rBuild <- relocatableBuild
- libdir <- setting InstallLibDir
- if rBuild then return libdir
- else do
- version <- setting ProjectVersion
- return $ libdir -/- ("ghc-" ++ version)
-
--- TODO: find out why we need version number in the dynamic suffix
--- The current theory: dynamic libraries are eventually placed in a single
--- giant directory in the load path of the dynamic linker, and hence we must
--- distinguish different versions of GHC. In contrast static libraries live
--- in their own per-package directory and hence do not need a unique filename.
--- We also need to respect the system's dynamic extension, e.g. .dll or .so.
-libsuf :: Way -> Action String
-libsuf way =
- if not (wayUnit Dynamic way)
- then return $ waySuffix way ++ ".a" -- e.g., _p.a
- else do
- extension <- setting DynamicExtension -- e.g., .dll or .so
- version <- setting ProjectVersion -- e.g., 7.11.20141222
- let prefix = wayPrefix $ removeWayUnit Dynamic way
- -- e.g., p_ghc7.11.20141222.dll (the result)
- return $ prefix ++ "-ghc" ++ version ++ extension