summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2020-07-21 19:15:59 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-07-25 00:45:08 -0400
commit7721b923d53fb9eb93f80bb93b4c3bd976c05b4c (patch)
treeedc61b1ed9885e442c7327460052f10d1ca589fa
parent73145d57f961c73b5853da7881d6a21e48e05909 (diff)
downloadhaskell-7721b923d53fb9eb93f80bb93b4c3bd976c05b4c.tar.gz
Move GHC.Platform into the compiler
Previously it was in ghc-boot so that ghc-pkg could use it. However it wasn't necessary because ghc-pkg only uses a subset of it: reading target arch and OS from the settings file. This is now done via GHC.Platform.ArchOS (was called PlatformMini before).
-rw-r--r--compiler/GHC.hs6
-rw-r--r--compiler/GHC/Driver/Pipeline.hs1
-rw-r--r--compiler/GHC/Driver/Session.hs16
-rw-r--r--compiler/GHC/Parser/Header.hs4
-rw-r--r--compiler/GHC/Platform.hs (renamed from libraries/ghc-boot/GHC/Platform.hs)212
-rw-r--r--compiler/GHC/Settings.hs1
-rw-r--r--compiler/GHC/Settings/IO.hs41
-rw-r--r--compiler/GHC/Unit/State.hs6
-rw-r--r--compiler/ghc.cabal.in9
-rw-r--r--ghc/Main.hs8
-rw-r--r--hadrian/src/Rules/Generate.hs17
-rw-r--r--libraries/ghc-boot/GHC/Platform/ArchOS.hs152
-rw-r--r--libraries/ghc-boot/GHC/Settings/Platform.hs103
-rw-r--r--libraries/ghc-boot/GHC/Settings/Utils.hs57
-rw-r--r--libraries/ghc-boot/GHC/UniqueSubdir.hs14
-rw-r--r--libraries/ghc-boot/ghc-boot.cabal.in3
-rw-r--r--libraries/ghc-boot/ghc.mk15
-rw-r--r--utils/ghc-pkg/Main.hs21
18 files changed, 337 insertions, 349 deletions
diff --git a/compiler/GHC.hs b/compiler/GHC.hs
index c7fac76828..22ce5fac18 100644
--- a/compiler/GHC.hs
+++ b/compiler/GHC.hs
@@ -1683,11 +1683,11 @@ interpretPackageEnv dflags = do
where
-- Loading environments (by name or by location)
- platformArchOs = platformMini (targetPlatform dflags)
+ archOS = platformArchOS (targetPlatform dflags)
namedEnvPath :: String -> MaybeT IO FilePath
namedEnvPath name = do
- appdir <- versionedAppDir (programName dflags) platformArchOs
+ appdir <- versionedAppDir (programName dflags) archOS
return $ appdir </> "environments" </> name
probeEnvName :: String -> MaybeT IO FilePath
@@ -1724,7 +1724,7 @@ interpretPackageEnv dflags = do
-- e.g. .ghc.environment.x86_64-linux-7.6.3
localEnvFileName :: FilePath
- localEnvFileName = ".ghc.environment" <.> versionedFilePath platformArchOs
+ localEnvFileName = ".ghc.environment" <.> versionedFilePath archOS
-- Search for an env file, starting in the current dir and looking upwards.
-- Fail if we get to the users home dir or the filesystem root. That is,
diff --git a/compiler/GHC/Driver/Pipeline.hs b/compiler/GHC/Driver/Pipeline.hs
index 1603c38e71..36010a76af 100644
--- a/compiler/GHC/Driver/Pipeline.hs
+++ b/compiler/GHC/Driver/Pipeline.hs
@@ -42,6 +42,7 @@ import GHC.Prelude
import GHC.Driver.Pipeline.Monad
import GHC.Unit.State
import GHC.Platform.Ways
+import GHC.Platform.ArchOS
import GHC.Parser.Header
import GHC.Driver.Phases
import GHC.SysTools
diff --git a/compiler/GHC/Driver/Session.hs b/compiler/GHC/Driver/Session.hs
index 2c2c3db7c2..01555dff8f 100644
--- a/compiler/GHC/Driver/Session.hs
+++ b/compiler/GHC/Driver/Session.hs
@@ -1000,13 +1000,13 @@ opt_i dflags= toolSettings_opt_i $ toolSettings dflags
-- | The directory for this version of ghc in the user's app directory
-- (typically something like @~/.ghc/x86_64-linux-7.6.3@)
--
-versionedAppDir :: String -> PlatformMini -> MaybeT IO FilePath
+versionedAppDir :: String -> ArchOS -> MaybeT IO FilePath
versionedAppDir appname platform = do
-- Make sure we handle the case the HOME isn't set (see #11678)
appdir <- tryMaybeT $ getAppUserDataDirectory appname
return $ appdir </> versionedFilePath platform
-versionedFilePath :: PlatformMini -> FilePath
+versionedFilePath :: ArchOS -> FilePath
versionedFilePath platform = uniqueSubdir platform
-- | The 'GhcMode' tells us whether we're doing multi-module
@@ -3633,8 +3633,8 @@ supportedLanguages = map (flagSpecName . snd) languageFlagsDeps
supportedLanguageOverlays :: [String]
supportedLanguageOverlays = map (flagSpecName . snd) safeHaskellFlagsDeps
-supportedExtensions :: PlatformMini -> [String]
-supportedExtensions targetPlatformMini = concatMap toFlagSpecNamePair xFlags
+supportedExtensions :: ArchOS -> [String]
+supportedExtensions (ArchOS _ os) = concatMap toFlagSpecNamePair xFlags
where
toFlagSpecNamePair flg
-- IMPORTANT! Make sure that `ghc --supported-extensions` omits
@@ -3645,13 +3645,13 @@ supportedExtensions targetPlatformMini = concatMap toFlagSpecNamePair xFlags
| isAIX, flagSpecFlag flg == LangExt.QuasiQuotes = [noName]
| otherwise = [name, noName]
where
- isAIX = platformMini_os targetPlatformMini == OSAIX
+ isAIX = os == OSAIX
noName = "No" ++ name
name = flagSpecName flg
-supportedLanguagesAndExtensions :: PlatformMini -> [String]
-supportedLanguagesAndExtensions targetPlatformMini =
- supportedLanguages ++ supportedLanguageOverlays ++ supportedExtensions targetPlatformMini
+supportedLanguagesAndExtensions :: ArchOS -> [String]
+supportedLanguagesAndExtensions arch_os =
+ supportedLanguages ++ supportedLanguageOverlays ++ supportedExtensions arch_os
-- | These -X<blah> flags cannot be reversed with -XNo<blah>
languageFlagsDeps :: [(Deprecation, FlagSpec Language)]
diff --git a/compiler/GHC/Parser/Header.hs b/compiler/GHC/Parser/Header.hs
index bfdeb71631..dfc7aec2ad 100644
--- a/compiler/GHC/Parser/Header.hs
+++ b/compiler/GHC/Parser/Header.hs
@@ -316,7 +316,7 @@ checkExtension dflags (L l ext)
else unsupportedExtnError dflags l ext'
where
ext' = unpackFS ext
- supported = supportedLanguagesAndExtensions $ platformMini $ targetPlatform dflags
+ supported = supportedLanguagesAndExtensions $ platformArchOS $ targetPlatform dflags
languagePragParseError :: DynFlags -> SrcSpan -> a
languagePragParseError dflags loc =
@@ -332,7 +332,7 @@ unsupportedExtnError dflags loc unsup =
text "Unsupported extension: " <> text unsup $$
if null suggestions then Outputable.empty else text "Perhaps you meant" <+> quotedListWithOr (map text suggestions)
where
- supported = supportedLanguagesAndExtensions $ platformMini $ targetPlatform dflags
+ supported = supportedLanguagesAndExtensions $ platformArchOS $ targetPlatform dflags
suggestions = fuzzyMatch unsup supported
diff --git a/libraries/ghc-boot/GHC/Platform.hs b/compiler/GHC/Platform.hs
index 9191dda44f..56a18e9c88 100644
--- a/libraries/ghc-boot/GHC/Platform.hs
+++ b/compiler/GHC/Platform.hs
@@ -1,14 +1,13 @@
-{-# LANGUAGE LambdaCase, ScopedTypeVariables #-}
+{-# LANGUAGE ScopedTypeVariables #-}
--- | A description of the platform we're compiling for.
---
+-- | Platform description
module GHC.Platform
- ( PlatformMini(..)
+ ( Platform (..)
, PlatformWordSize(..)
, PlatformConstants(..)
- , Platform(..)
, platformArch
, platformOS
+ , ArchOS(..)
, Arch(..)
, OS(..)
, ArmISA(..)
@@ -30,34 +29,26 @@ module GHC.Platform
, platformInIntRange
, platformInWordRange
, PlatformMisc(..)
- , stringEncodeArch
- , stringEncodeOS
, SseVersion (..)
, BmiVersion (..)
)
where
import Prelude -- See Note [Why do we import Prelude here?]
-import GHC.Read
-import GHC.ByteOrder (ByteOrder(..))
-import GHC.Platform.Constants
+
import Data.Word
import Data.Int
--- | Contains the bare-bones arch and os information. This isn't enough for
--- code gen, but useful for tasks where we can fall back upon the host
--- platform, as this is all we know about the host platform.
-data PlatformMini
- = PlatformMini
- { platformMini_arch :: Arch
- , platformMini_os :: OS
- }
- deriving (Read, Show, Eq)
+import GHC.Read
+import GHC.ByteOrder (ByteOrder(..))
+import GHC.Platform.Constants
+import GHC.Platform.ArchOS
--- | Contains enough information for the native code generator to emit
--- code for this platform.
+-- | Platform description
+--
+-- This is used to describe platforms so that we can generate code for them.
data Platform = Platform
- { platformMini :: !PlatformMini
+ { platformArchOS :: !ArchOS -- ^ Architecture and OS
, platformWordSize :: !PlatformWordSize -- ^ Word size
, platformByteOrder :: !ByteOrder -- ^ Byte order (endianness)
, platformUnregisterised :: !Bool
@@ -101,152 +92,21 @@ platformWordSizeInBytes p =
platformWordSizeInBits :: Platform -> Int
platformWordSizeInBits p = platformWordSizeInBytes p * 8
--- | Legacy accessor
+-- | Platform architecture
platformArch :: Platform -> Arch
-platformArch = platformMini_arch . platformMini
+platformArch platform = case platformArchOS platform of
+ ArchOS arch _ -> arch
--- | Legacy accessor
+-- | Platform OS
platformOS :: Platform -> OS
-platformOS = platformMini_os . platformMini
-
--- | Architectures that the native code generator knows about.
--- TODO: It might be nice to extend these constructors with information
--- about what instruction set extensions an architecture might support.
---
-data Arch
- = ArchUnknown
- | ArchX86
- | ArchX86_64
- | ArchPPC
- | ArchPPC_64
- { ppc_64ABI :: PPC_64ABI
- }
- | ArchS390X
- | ArchSPARC
- | ArchSPARC64
- | ArchARM
- { armISA :: ArmISA
- , armISAExt :: [ArmISAExt]
- , armABI :: ArmABI
- }
- | ArchARM64
- | ArchAlpha
- | ArchMipseb
- | ArchMipsel
- | ArchJavaScript
- deriving (Read, Show, Eq)
-
--- Note [Platform Syntax]
--- ~~~~~~~~~~~~~~~~~~~~~~
--- There is a very loose encoding of platforms shared by many tools we are
--- encoding to here. GNU Config (http://git.savannah.gnu.org/cgit/config.git),
--- and LLVM's http://llvm.org/doxygen/classllvm_1_1Triple.html are perhaps the
--- most definitional parsers. The basic syntax is a list of '-'-separated
--- components. The Unix 'uname' command syntax is related but briefer.
---
--- Those two parsers are quite forgiving, and even the 'config.sub'
--- normalization is forgiving too. The "best" way to encode a platform is
--- therefore somewhat a matter of taste.
---
--- The 'stringEncode*' functions here convert each part of GHC's structured
--- notion of a platform into one dash-separated component.
-
--- | See Note [Platform Syntax].
-stringEncodeArch :: Arch -> String
-stringEncodeArch = \case
- ArchUnknown -> "unknown"
- ArchX86 -> "i386"
- ArchX86_64 -> "x86_64"
- ArchPPC -> "powerpc"
- ArchPPC_64 { ppc_64ABI = abi } -> case abi of
- ELF_V1 -> "powerpc64"
- ELF_V2 -> "powerpc64le"
- ArchS390X -> "s390x"
- ArchSPARC -> "sparc"
- ArchSPARC64 -> "sparc64"
- ArchARM { armISA = isa, armISAExt = _, armABI = _ } -> "arm" ++ vsuf
- where
- vsuf = case isa of
- ARMv5 -> "v5"
- ARMv6 -> "v6"
- ARMv7 -> "v7"
- ArchARM64 -> "aarch64"
- ArchAlpha -> "alpha"
- ArchMipseb -> "mipseb"
- ArchMipsel -> "mipsel"
- ArchJavaScript -> "js"
+platformOS platform = case platformArchOS platform of
+ ArchOS _ os -> os
isARM :: Arch -> Bool
isARM (ArchARM {}) = True
isARM ArchARM64 = True
isARM _ = False
--- | Operating systems that the native code generator knows about.
--- Having OSUnknown should produce a sensible default, but no promises.
-data OS
- = OSUnknown
- | OSLinux
- | OSDarwin
- | OSSolaris2
- | OSMinGW32
- | OSFreeBSD
- | OSDragonFly
- | OSOpenBSD
- | OSNetBSD
- | OSKFreeBSD
- | OSHaiku
- | OSQNXNTO
- | OSAIX
- | OSHurd
- deriving (Read, Show, Eq)
-
--- | See Note [Platform Syntax].
-stringEncodeOS :: OS -> String
-stringEncodeOS = \case
- OSUnknown -> "unknown"
- OSLinux -> "linux"
- OSDarwin -> "darwin"
- OSSolaris2 -> "solaris2"
- OSMinGW32 -> "mingw32"
- OSFreeBSD -> "freebsd"
- OSDragonFly -> "dragonfly"
- OSOpenBSD -> "openbsd"
- OSNetBSD -> "netbsd"
- OSKFreeBSD -> "kfreebsdgnu"
- OSHaiku -> "haiku"
- OSQNXNTO -> "nto-qnx"
- OSAIX -> "aix"
- OSHurd -> "hurd"
-
--- | ARM Instruction Set Architecture, Extensions and ABI
---
-data ArmISA
- = ARMv5
- | ARMv6
- | ARMv7
- deriving (Read, Show, Eq)
-
-data ArmISAExt
- = VFPv2
- | VFPv3
- | VFPv3D16
- | NEON
- | IWMMX2
- deriving (Read, Show, Eq)
-
-data ArmABI
- = SOFT
- | SOFTFP
- | HARD
- deriving (Read, Show, Eq)
-
--- | PowerPC 64-bit ABI
---
-data PPC_64ABI
- = ELF_V1
- | ELF_V2
- deriving (Read, Show, Eq)
-
-- | This predicate tells us whether the platform is 32-bit.
target32Bit :: Platform -> Bool
target32Bit p =
@@ -291,23 +151,6 @@ osSubsectionsViaSymbols :: OS -> Bool
osSubsectionsViaSymbols OSDarwin = True
osSubsectionsViaSymbols _ = False
--- | Platform-specific settings formerly hard-coded in Config.hs.
---
--- These should probably be all be triaged whether they can be computed from
--- other settings or belong in another another place (like 'Platform' above).
-data PlatformMisc = PlatformMisc
- { -- TODO Recalculate string from richer info?
- platformMisc_targetPlatformString :: String
- , platformMisc_ghcWithInterpreter :: Bool
- , platformMisc_ghcWithSMP :: Bool
- , platformMisc_ghcRTSWays :: String
- , platformMisc_libFFI :: Bool
- , platformMisc_ghcThreaded :: Bool
- , platformMisc_ghcDebugged :: Bool
- , platformMisc_ghcRtsWithLibdw :: Bool
- , platformMisc_llvmTarget :: String
- }
-
-- | Minimum representable Int value for the given platform
platformMinInt :: Platform -> Integer
platformMinInt p = case platformWordSize p of
@@ -354,3 +197,20 @@ data BmiVersion
| BMI2
deriving (Eq, Ord)
+
+-- | Platform-specific settings formerly hard-coded in Config.hs.
+--
+-- These should probably be all be triaged whether they can be computed from
+-- other settings or belong in another another place (like 'Platform' above).
+data PlatformMisc = PlatformMisc
+ { -- TODO Recalculate string from richer info?
+ platformMisc_targetPlatformString :: String
+ , platformMisc_ghcWithInterpreter :: Bool
+ , platformMisc_ghcWithSMP :: Bool
+ , platformMisc_ghcRTSWays :: String
+ , platformMisc_libFFI :: Bool
+ , platformMisc_ghcThreaded :: Bool
+ , platformMisc_ghcDebugged :: Bool
+ , platformMisc_ghcRtsWithLibdw :: Bool
+ , platformMisc_llvmTarget :: String
+ }
diff --git a/compiler/GHC/Settings.hs b/compiler/GHC/Settings.hs
index 12ad3ce94b..49a2018252 100644
--- a/compiler/GHC/Settings.hs
+++ b/compiler/GHC/Settings.hs
@@ -8,7 +8,6 @@ module GHC.Settings
, GhcNameVersion (..)
, Platform (..)
, PlatformMisc (..)
- , PlatformMini (..)
-- * Accessors
, sProgramName
, sProjectVersion
diff --git a/compiler/GHC/Settings/IO.hs b/compiler/GHC/Settings/IO.hs
index c4e47618d2..d1ec388195 100644
--- a/compiler/GHC/Settings/IO.hs
+++ b/compiler/GHC/Settings/IO.hs
@@ -11,7 +11,6 @@ module GHC.Settings.IO
import GHC.Prelude
-import GHC.Settings.Platform
import GHC.Settings.Utils
import GHC.Settings.Config
@@ -71,12 +70,12 @@ initSettings top_dir = do
-- just partially applying those functions and throwing 'Left's; they're
-- written in a very portable style to keep ghc-boot light.
let getSetting key = either pgmError pure $
- getFilePathSetting0 top_dir settingsFile mySettings key
+ getRawFilePathSetting top_dir settingsFile mySettings key
getToolSetting :: String -> ExceptT SettingsError m String
getToolSetting key = expandToolDir mtool_dir <$> getSetting key
getBooleanSetting :: String -> ExceptT SettingsError m Bool
getBooleanSetting key = either pgmError pure $
- getBooleanSetting0 settingsFile mySettings key
+ getRawBooleanSetting settingsFile mySettings key
targetPlatformString <- getSetting "target platform string"
myExtraGccViaCFlags <- getSetting "GCC extra via C opts"
-- On Windows, mingw is distributed with GHC,
@@ -228,3 +227,39 @@ initSettings top_dir = do
, sRawSettings = settingsList
}
+
+getTargetPlatform
+ :: FilePath -- ^ Settings filepath (for error messages)
+ -> RawSettings -- ^ Raw settings file contents
+ -> PlatformConstants -- ^ Platform constants
+ -> Either String Platform
+getTargetPlatform settingsFile settings constants = do
+ let
+ getBooleanSetting = getRawBooleanSetting settingsFile settings
+ readSetting :: (Show a, Read a) => String -> Either String a
+ readSetting = readRawSetting settingsFile settings
+
+ targetArchOS <- getTargetArchOS settingsFile settings
+ targetWordSize <- readSetting "target word size"
+ targetWordBigEndian <- getBooleanSetting "target word big endian"
+ targetLeadingUnderscore <- getBooleanSetting "Leading underscore"
+ targetUnregisterised <- getBooleanSetting "Unregisterised"
+ targetHasGnuNonexecStack <- getBooleanSetting "target has GNU nonexec stack"
+ targetHasIdentDirective <- getBooleanSetting "target has .ident directive"
+ targetHasSubsectionsViaSymbols <- getBooleanSetting "target has subsections via symbols"
+ crossCompiling <- getBooleanSetting "cross compiling"
+ tablesNextToCode <- getBooleanSetting "Tables next to code"
+
+ pure $ Platform
+ { platformArchOS = targetArchOS
+ , platformWordSize = targetWordSize
+ , platformByteOrder = if targetWordBigEndian then BigEndian else LittleEndian
+ , platformUnregisterised = targetUnregisterised
+ , platformHasGnuNonexecStack = targetHasGnuNonexecStack
+ , platformHasIdentDirective = targetHasIdentDirective
+ , platformHasSubsectionsViaSymbols = targetHasSubsectionsViaSymbols
+ , platformIsCrossCompiling = crossCompiling
+ , platformLeadingUnderscore = targetLeadingUnderscore
+ , platformTablesNextToCode = tablesNextToCode
+ , platformConstants = constants
+ }
diff --git a/compiler/GHC/Unit/State.hs b/compiler/GHC/Unit/State.hs
index fb50966195..93c0b86dc8 100644
--- a/compiler/GHC/Unit/State.hs
+++ b/compiler/GHC/Unit/State.hs
@@ -314,7 +314,7 @@ instance Monoid UnitVisibility where
-- | Unit configuration
data UnitConfig = UnitConfig
- { unitConfigPlatformArchOs :: !PlatformMini -- ^ Platform
+ { unitConfigPlatformArchOS :: !ArchOS -- ^ Platform arch and OS
, unitConfigWays :: !(Set Way) -- ^ Ways to use
, unitConfigProgramName :: !String
-- ^ Name of the compiler (e.g. "GHC", "GHCJS"). Used to fetch environment
@@ -356,7 +356,7 @@ initUnitConfig dflags =
| otherwise = filter (/= homeUnitId dflags) [baseUnitId, rtsUnitId]
in UnitConfig
- { unitConfigPlatformArchOs = platformMini (targetPlatform dflags)
+ { unitConfigPlatformArchOS = platformArchOS (targetPlatform dflags)
, unitConfigProgramName = programName dflags
, unitConfigWays = ways dflags
@@ -646,7 +646,7 @@ getUnitDbRefs cfg = do
resolveUnitDatabase :: UnitConfig -> PkgDbRef -> IO (Maybe FilePath)
resolveUnitDatabase cfg GlobalPkgDb = return $ Just (unitConfigGlobalDB cfg)
resolveUnitDatabase cfg UserPkgDb = runMaybeT $ do
- dir <- versionedAppDir (unitConfigProgramName cfg) (unitConfigPlatformArchOs cfg)
+ dir <- versionedAppDir (unitConfigProgramName cfg) (unitConfigPlatformArchOS cfg)
let pkgconf = dir </> unitConfigDBName cfg
exist <- tryMaybeT $ doesDirectoryExist pkgconf
if exist then return pkgconf else mzero
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
index 5c153817e7..efa45c89e4 100644
--- a/compiler/ghc.cabal.in
+++ b/compiler/ghc.cabal.in
@@ -181,8 +181,6 @@ Library
GHC.Driver.Monad
GHC.Driver.Hooks
GHC.Driver.Flags
- GHC.Platform.Ways
- GHC.Platform.Profile
GHC.Types.Id
GHC.Types.Id.Info
GHC.Core.Predicate
@@ -258,6 +256,9 @@ Library
GHC.Cmm.Ppr.Decl
GHC.Cmm.Ppr.Expr
GHC.Data.Bitmap
+ GHC.Platform
+ GHC.Platform.Ways
+ GHC.Platform.Profile
GHC.Platform.Regs
GHC.Platform.ARM
GHC.Platform.ARM64
@@ -566,6 +567,10 @@ Library
GHC.Cmm.Dataflow.Graph
GHC.Cmm.Dataflow.Label
+ reexported-modules:
+ GHC.Platform.ArchOS
+ GHC.Platform.Host
+
Exposed-Modules:
GHC.CmmToAsm
GHC.CmmToAsm.Reg.Target
diff --git a/ghc/Main.hs b/ghc/Main.hs
index 41435af878..fa6608761d 100644
--- a/ghc/Main.hs
+++ b/ghc/Main.hs
@@ -792,16 +792,16 @@ showSupportedExtensions m_top_dir = do
Nothing -> throwE $ SettingsError_MissingData "Could not find the top directory, missing -B flag"
Just dir -> pure dir
initSettings top_dir
- targetPlatformMini <- case res of
- Right s -> pure $ platformMini $ sTargetPlatform s
+ arch_os <- case res of
+ Right s -> pure $ platformArchOS $ sTargetPlatform s
Left (SettingsError_MissingData msg) -> do
hPutStrLn stderr $ "WARNING: " ++ show msg
hPutStrLn stderr $ "cannot know target platform so guessing target == host (native compiler)."
- pure cHostPlatformMini
+ pure hostPlatformArchOS
Left (SettingsError_BadData msg) -> do
hPutStrLn stderr msg
exitWith $ ExitFailure 1
- mapM_ putStrLn $ supportedLanguagesAndExtensions targetPlatformMini
+ mapM_ putStrLn $ supportedLanguagesAndExtensions arch_os
showVersion :: IO ()
showVersion = putStrLn (cProjectName ++ ", version " ++ cProjectVersion)
diff --git a/hadrian/src/Rules/Generate.hs b/hadrian/src/Rules/Generate.hs
index 98ea2bd353..7a51814b07 100644
--- a/hadrian/src/Rules/Generate.hs
+++ b/hadrian/src/Rules/Generate.hs
@@ -474,17 +474,14 @@ generatePlatformHostHs = do
return $ unlines
[ "module GHC.Platform.Host where"
, ""
- , "import GHC.Platform"
+ , "import GHC.Platform.ArchOS"
, ""
- , "cHostPlatformArch :: Arch"
- , "cHostPlatformArch = " ++ cHostPlatformArch
+ , "hostPlatformArch :: Arch"
+ , "hostPlatformArch = " ++ cHostPlatformArch
, ""
- , "cHostPlatformOS :: OS"
- , "cHostPlatformOS = " ++ cHostPlatformOS
+ , "hostPlatformOS :: OS"
+ , "hostPlatformOS = " ++ cHostPlatformOS
, ""
- , "cHostPlatformMini :: PlatformMini"
- , "cHostPlatformMini = PlatformMini"
- , " { platformMini_arch = cHostPlatformArch"
- , " , platformMini_os = cHostPlatformOS"
- , " }"
+ , "hostPlatformArchOS :: ArchOS"
+ , "hostPlatformArchOS = ArchOS hostPlatformArch hostPlatformOS"
]
diff --git a/libraries/ghc-boot/GHC/Platform/ArchOS.hs b/libraries/ghc-boot/GHC/Platform/ArchOS.hs
new file mode 100644
index 0000000000..bd3ef5f4cc
--- /dev/null
+++ b/libraries/ghc-boot/GHC/Platform/ArchOS.hs
@@ -0,0 +1,152 @@
+{-# LANGUAGE LambdaCase, ScopedTypeVariables #-}
+
+-- | Platform architecture and OS
+--
+-- We need it in ghc-boot because ghc-pkg needs it.
+module GHC.Platform.ArchOS
+ ( ArchOS(..)
+ , Arch(..)
+ , OS(..)
+ , ArmISA(..)
+ , ArmISAExt(..)
+ , ArmABI(..)
+ , PPC_64ABI(..)
+ , stringEncodeArch
+ , stringEncodeOS
+ )
+where
+
+import Prelude -- See Note [Why do we import Prelude here?]
+
+-- | Platform architecture and OS.
+data ArchOS
+ = ArchOS Arch OS
+ deriving (Read, Show, Eq)
+
+-- | Architectures
+--
+-- TODO: It might be nice to extend these constructors with information about
+-- what instruction set extensions an architecture might support.
+--
+data Arch
+ = ArchUnknown
+ | ArchX86
+ | ArchX86_64
+ | ArchPPC
+ | ArchPPC_64 PPC_64ABI
+ | ArchS390X
+ | ArchSPARC
+ | ArchSPARC64
+ | ArchARM ArmISA [ArmISAExt] ArmABI
+ | ArchARM64
+ | ArchAlpha
+ | ArchMipseb
+ | ArchMipsel
+ | ArchJavaScript
+ deriving (Read, Show, Eq)
+
+-- | ARM Instruction Set Architecture
+data ArmISA
+ = ARMv5
+ | ARMv6
+ | ARMv7
+ deriving (Read, Show, Eq)
+
+-- | ARM extensions
+data ArmISAExt
+ = VFPv2
+ | VFPv3
+ | VFPv3D16
+ | NEON
+ | IWMMX2
+ deriving (Read, Show, Eq)
+
+-- | ARM ABI
+data ArmABI
+ = SOFT
+ | SOFTFP
+ | HARD
+ deriving (Read, Show, Eq)
+
+-- | PowerPC 64-bit ABI
+data PPC_64ABI
+ = ELF_V1
+ | ELF_V2
+ deriving (Read, Show, Eq)
+
+-- | Operating systems.
+--
+-- Using OSUnknown to generate code should produce a sensible default, but no
+-- promises.
+data OS
+ = OSUnknown
+ | OSLinux
+ | OSDarwin
+ | OSSolaris2
+ | OSMinGW32
+ | OSFreeBSD
+ | OSDragonFly
+ | OSOpenBSD
+ | OSNetBSD
+ | OSKFreeBSD
+ | OSHaiku
+ | OSQNXNTO
+ | OSAIX
+ | OSHurd
+ deriving (Read, Show, Eq)
+
+
+-- Note [Platform Syntax]
+-- ~~~~~~~~~~~~~~~~~~~~~~
+--
+-- There is a very loose encoding of platforms shared by many tools we are
+-- encoding to here. GNU Config (http://git.savannah.gnu.org/cgit/config.git),
+-- and LLVM's http://llvm.org/doxygen/classllvm_1_1Triple.html are perhaps the
+-- most definitional parsers. The basic syntax is a list of '-'-separated
+-- components. The Unix 'uname' command syntax is related but briefer.
+--
+-- Those two parsers are quite forgiving, and even the 'config.sub'
+-- normalization is forgiving too. The "best" way to encode a platform is
+-- therefore somewhat a matter of taste.
+--
+-- The 'stringEncode*' functions here convert each part of GHC's structured
+-- notion of a platform into one dash-separated component.
+
+-- | See Note [Platform Syntax].
+stringEncodeArch :: Arch -> String
+stringEncodeArch = \case
+ ArchUnknown -> "unknown"
+ ArchX86 -> "i386"
+ ArchX86_64 -> "x86_64"
+ ArchPPC -> "powerpc"
+ ArchPPC_64 ELF_V1 -> "powerpc64"
+ ArchPPC_64 ELF_V2 -> "powerpc64le"
+ ArchS390X -> "s390x"
+ ArchSPARC -> "sparc"
+ ArchSPARC64 -> "sparc64"
+ ArchARM ARMv5 _ _ -> "armv5"
+ ArchARM ARMv6 _ _ -> "armv6"
+ ArchARM ARMv7 _ _ -> "armv7"
+ ArchARM64 -> "aarch64"
+ ArchAlpha -> "alpha"
+ ArchMipseb -> "mipseb"
+ ArchMipsel -> "mipsel"
+ ArchJavaScript -> "js"
+
+-- | See Note [Platform Syntax].
+stringEncodeOS :: OS -> String
+stringEncodeOS = \case
+ OSUnknown -> "unknown"
+ OSLinux -> "linux"
+ OSDarwin -> "darwin"
+ OSSolaris2 -> "solaris2"
+ OSMinGW32 -> "mingw32"
+ OSFreeBSD -> "freebsd"
+ OSDragonFly -> "dragonfly"
+ OSOpenBSD -> "openbsd"
+ OSNetBSD -> "netbsd"
+ OSKFreeBSD -> "kfreebsdgnu"
+ OSHaiku -> "haiku"
+ OSQNXNTO -> "nto-qnx"
+ OSAIX -> "aix"
+ OSHurd -> "hurd"
diff --git a/libraries/ghc-boot/GHC/Settings/Platform.hs b/libraries/ghc-boot/GHC/Settings/Platform.hs
deleted file mode 100644
index 95278da76e..0000000000
--- a/libraries/ghc-boot/GHC/Settings/Platform.hs
+++ /dev/null
@@ -1,103 +0,0 @@
--- Note [Settings file]
--- ~~~~~~~~~~~~~~~~~~~~
---
--- GHC has a file, `${top_dir}/settings`, which is the main source of run-time
--- configuration. ghc-pkg needs just a little bit of it: the target platform CPU
--- arch and OS. It uses that to figure out what subdirectory of `~/.ghc` is
--- associated with the current version/target.
---
--- This module has just enough code to read key value pairs from the settings
--- file, and read the target platform from those pairs.
---
--- The "0" suffix is because the caller will partially apply it, and that will
--- in turn be used a few more times.
-module GHC.Settings.Platform where
-
-import Prelude -- See Note [Why do we import Prelude here?]
-
-import GHC.BaseDir
-import GHC.Platform
-import GHC.Settings.Utils
-
-import Data.Map (Map)
-import qualified Data.Map as Map
-
------------------------------------------------------------------------------
--- parts of settings file
-
-getTargetPlatform
- :: FilePath -- ^ Settings filepath (for error messages)
- -> RawSettings -- ^ Raw settings file contents
- -> PlatformConstants -- ^ Platform constants
- -> Either String Platform
-getTargetPlatform settingsFile mySettings constants = do
- let
- getBooleanSetting = getBooleanSetting0 settingsFile mySettings
- readSetting :: (Show a, Read a) => String -> Either String a
- readSetting = readSetting0 settingsFile mySettings
-
- targetArch <- readSetting "target arch"
- targetOS <- readSetting "target os"
- targetWordSize <- readSetting "target word size"
- targetWordBigEndian <- getBooleanSetting "target word big endian"
- targetLeadingUnderscore <- getBooleanSetting "Leading underscore"
- targetUnregisterised <- getBooleanSetting "Unregisterised"
- targetHasGnuNonexecStack <- getBooleanSetting "target has GNU nonexec stack"
- targetHasIdentDirective <- getBooleanSetting "target has .ident directive"
- targetHasSubsectionsViaSymbols <- getBooleanSetting "target has subsections via symbols"
- crossCompiling <- getBooleanSetting "cross compiling"
- tablesNextToCode <- getBooleanSetting "Tables next to code"
-
- pure $ Platform
- { platformMini = PlatformMini
- { platformMini_arch = targetArch
- , platformMini_os = targetOS
- }
- , platformWordSize = targetWordSize
- , platformByteOrder = if targetWordBigEndian then BigEndian else LittleEndian
- , platformUnregisterised = targetUnregisterised
- , platformHasGnuNonexecStack = targetHasGnuNonexecStack
- , platformHasIdentDirective = targetHasIdentDirective
- , platformHasSubsectionsViaSymbols = targetHasSubsectionsViaSymbols
- , platformIsCrossCompiling = crossCompiling
- , platformLeadingUnderscore = targetLeadingUnderscore
- , platformTablesNextToCode = tablesNextToCode
- , platformConstants = constants
- }
-
------------------------------------------------------------------------------
--- settings file helpers
-
-type RawSettings = Map String String
-
--- | See Note [Settings file] for "0" suffix
-getSetting0
- :: FilePath -> RawSettings -> String -> Either String String
-getSetting0 settingsFile mySettings key = case Map.lookup key mySettings of
- Just xs -> Right xs
- Nothing -> Left $ "No entry for " ++ show key ++ " in " ++ show settingsFile
-
--- | See Note [Settings file] for "0" suffix
-getFilePathSetting0
- :: FilePath -> FilePath -> RawSettings -> String -> Either String String
-getFilePathSetting0 top_dir settingsFile mySettings key =
- expandTopDir top_dir <$> getSetting0 settingsFile mySettings key
-
--- | See Note [Settings file] for "0" suffix
-getBooleanSetting0
- :: FilePath -> RawSettings -> String -> Either String Bool
-getBooleanSetting0 settingsFile mySettings key = do
- rawValue <- getSetting0 settingsFile mySettings key
- case rawValue of
- "YES" -> Right True
- "NO" -> Right False
- xs -> Left $ "Bad value for " ++ show key ++ ": " ++ show xs
-
--- | See Note [Settings file] for "0" suffix
-readSetting0
- :: (Show a, Read a) => FilePath -> RawSettings -> String -> Either String a
-readSetting0 settingsFile mySettings key = case Map.lookup key mySettings of
- Just xs -> case maybeRead xs of
- Just v -> Right v
- Nothing -> Left $ "Failed to read " ++ show key ++ " value " ++ show xs
- Nothing -> Left $ "No entry for " ++ show key ++ " in " ++ show settingsFile
diff --git a/libraries/ghc-boot/GHC/Settings/Utils.hs b/libraries/ghc-boot/GHC/Settings/Utils.hs
index 1f1cd67030..4ccbbf23b6 100644
--- a/libraries/ghc-boot/GHC/Settings/Utils.hs
+++ b/libraries/ghc-boot/GHC/Settings/Utils.hs
@@ -3,6 +3,11 @@ module GHC.Settings.Utils where
import Prelude -- See Note [Why do we import Prelude here?]
import Data.Char (isSpace)
+import Data.Map (Map)
+import qualified Data.Map as Map
+
+import GHC.BaseDir
+import GHC.Platform.ArchOS
maybeRead :: Read a => String -> Maybe a
maybeRead str = case reads str of
@@ -13,3 +18,55 @@ maybeReadFuzzy :: Read a => String -> Maybe a
maybeReadFuzzy str = case reads str of
[(x, s)] | all isSpace s -> Just x
_ -> Nothing
+
+
+-- Note [Settings file]
+-- ~~~~~~~~~~~~~~~~~~~~
+--
+-- GHC has a file, `${top_dir}/settings`, which is the main source of run-time
+-- configuration. ghc-pkg needs just a little bit of it: the target platform CPU
+-- arch and OS. It uses that to figure out what subdirectory of `~/.ghc` is
+-- associated with the current version/target platform.
+--
+-- This module has just enough code to read key value pairs from the settings
+-- file, and read the target platform from those pairs.
+
+type RawSettings = Map String String
+
+-- | Read target Arch/OS from the settings
+getTargetArchOS
+ :: FilePath -- ^ Settings filepath (for error messages)
+ -> RawSettings -- ^ Raw settings file contents
+ -> Either String ArchOS
+getTargetArchOS settingsFile settings =
+ ArchOS <$> readRawSetting settingsFile settings "target arch"
+ <*> readRawSetting settingsFile settings "target os"
+
+
+getRawSetting
+ :: FilePath -> RawSettings -> String -> Either String String
+getRawSetting settingsFile settings key = case Map.lookup key settings of
+ Just xs -> Right xs
+ Nothing -> Left $ "No entry for " ++ show key ++ " in " ++ show settingsFile
+
+getRawFilePathSetting
+ :: FilePath -> FilePath -> RawSettings -> String -> Either String String
+getRawFilePathSetting top_dir settingsFile settings key =
+ expandTopDir top_dir <$> getRawSetting settingsFile settings key
+
+getRawBooleanSetting
+ :: FilePath -> RawSettings -> String -> Either String Bool
+getRawBooleanSetting settingsFile settings key = do
+ rawValue <- getRawSetting settingsFile settings key
+ case rawValue of
+ "YES" -> Right True
+ "NO" -> Right False
+ xs -> Left $ "Bad value for " ++ show key ++ ": " ++ show xs
+
+readRawSetting
+ :: (Show a, Read a) => FilePath -> RawSettings -> String -> Either String a
+readRawSetting settingsFile settings key = case Map.lookup key settings of
+ Just xs -> case maybeRead xs of
+ Just v -> Right v
+ Nothing -> Left $ "Failed to read " ++ show key ++ " value " ++ show xs
+ Nothing -> Left $ "No entry for " ++ show key ++ " in " ++ show settingsFile
diff --git a/libraries/ghc-boot/GHC/UniqueSubdir.hs b/libraries/ghc-boot/GHC/UniqueSubdir.hs
index b59fdc43ce..5ffaafefd8 100644
--- a/libraries/ghc-boot/GHC/UniqueSubdir.hs
+++ b/libraries/ghc-boot/GHC/UniqueSubdir.hs
@@ -6,19 +6,15 @@ import Prelude -- See Note [Why do we import Prelude here?]
import Data.List (intercalate)
-import GHC.Platform
+import GHC.Platform.ArchOS
import GHC.Version (cProjectVersion)
-- | A filepath like @x86_64-linux-7.6.3@ with the platform string to use when
-- constructing platform-version-dependent files that need to co-exist.
---
--- 'ghc-pkg' falls back on the host platform if the settings file is missing,
--- and so needs this since we don't have information about the host platform in
--- as much detail as 'Platform', so we use 'PlatformMini' instead.
-uniqueSubdir :: PlatformMini -> FilePath
-uniqueSubdir archOs = intercalate "-"
- [ stringEncodeArch $ platformMini_arch archOs
- , stringEncodeOS $ platformMini_os archOs
+uniqueSubdir :: ArchOS -> FilePath
+uniqueSubdir (ArchOS arch os) = intercalate "-"
+ [ stringEncodeArch arch
+ , stringEncodeOS os
, cProjectVersion
]
-- NB: This functionality is reimplemented in Cabal, so if you
diff --git a/libraries/ghc-boot/ghc-boot.cabal.in b/libraries/ghc-boot/ghc-boot.cabal.in
index aed65d8f0a..e320a5725f 100644
--- a/libraries/ghc-boot/ghc-boot.cabal.in
+++ b/libraries/ghc-boot/ghc-boot.cabal.in
@@ -43,10 +43,9 @@ Library
GHC.Serialized
GHC.ForeignSrcLang
GHC.HandleEncoding
- GHC.Platform
+ GHC.Platform.ArchOS
GHC.Platform.Host
GHC.Platform.Constants
- GHC.Settings.Platform
GHC.Settings.Utils
GHC.UniqueSubdir
GHC.Version
diff --git a/libraries/ghc-boot/ghc.mk b/libraries/ghc-boot/ghc.mk
index 9c5d695d8c..d183ccc501 100644
--- a/libraries/ghc-boot/ghc.mk
+++ b/libraries/ghc-boot/ghc.mk
@@ -42,17 +42,14 @@ libraries/ghc-boot/dist-install/build/GHC/Platform/Host.hs: mk/project.mk | $$(d
@echo >> $@
@echo 'import GHC.Platform' >> $@
@echo >> $@
- @echo 'cHostPlatformArch :: Arch' >> $@
- @echo 'cHostPlatformArch = $(HaskellHostArch)' >> $@
+ @echo 'hostPlatformArch :: Arch' >> $@
+ @echo 'hostPlatformArch = $(HaskellHostArch)' >> $@
@echo >> $@
- @echo 'cHostPlatformOS :: OS' >> $@
- @echo 'cHostPlatformOS = $(HaskellHostOs)' >> $@
+ @echo 'hostPlatformOS :: OS' >> $@
+ @echo 'hostPlatformOS = $(HaskellHostOs)' >> $@
@echo >> $@
- @echo 'cHostPlatformMini :: PlatformMini' >> $@
- @echo 'cHostPlatformMini = PlatformMini' >> $@
- @echo ' { platformMini_arch = cHostPlatformArch' >> $@
- @echo ' , platformMini_os = cHostPlatformOS' >> $@
- @echo ' }' >> $@
+ @echo 'hostPlatformArchOS :: ArchOS' >> $@
+ @echo 'hostPlatformArchOS = ArchOS hostPlatformArch hostPlatformOS' >> $@
@echo done.
libraries/ghc-boot/dist-boot/package-data.mk: \
diff --git a/utils/ghc-pkg/Main.hs b/utils/ghc-pkg/Main.hs
index 91637f5fab..3c7a65ddf6 100644
--- a/utils/ghc-pkg/Main.hs
+++ b/utils/ghc-pkg/Main.hs
@@ -34,10 +34,8 @@ import qualified GHC.Unit.Database as GhcPkg
import GHC.Unit.Database
import GHC.HandleEncoding
import GHC.BaseDir (getBaseDir)
-import GHC.Settings.Platform (getTargetPlatform)
-import GHC.Settings.Utils (maybeReadFuzzy)
-import GHC.Platform (platformMini)
-import GHC.Platform.Host (cHostPlatformMini)
+import GHC.Settings.Utils (getTargetArchOS, maybeReadFuzzy)
+import GHC.Platform.Host (hostPlatformArchOS)
import GHC.UniqueSubdir (uniqueSubdir)
import GHC.Version ( cProjectVersion )
import qualified Distribution.Simple.PackageIndex as PackageIndex
@@ -643,13 +641,12 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
Right appdir -> do
-- See Note [Settings File] about this file, and why we need GHC to share it with us.
let settingsFile = top_dir </> "settings"
- let constantsFile = top_dir </> "platformConstants"
exists_settings_file <- doesFileExist settingsFile
- targetPlatformMini <- case exists_settings_file of
+ targetArchOS <- case exists_settings_file of
False -> do
warn $ "WARNING: settings file doesn't exist " ++ show settingsFile
warn "cannot know target platform so guessing target == host (native compiler)."
- pure cHostPlatformMini
+ pure hostPlatformArchOS
True -> do
settingsStr <- readFile settingsFile
mySettings <- case maybeReadFuzzy settingsStr of
@@ -657,14 +654,10 @@ getPkgDatabases verbosity mode use_user use_cache expand_vars my_flags = do
-- It's excusable to not have a settings file (for now at
-- least) but completely inexcusable to have a malformed one.
Nothing -> die $ "Can't parse settings file " ++ show settingsFile
- constantsStr <- readFile constantsFile
- constants <- case maybeReadFuzzy constantsStr of
- Just s -> pure s
- Nothing -> die $ "Can't parse platform constants file " ++ show constantsFile
- case getTargetPlatform settingsFile mySettings constants of
- Right platform -> pure $ platformMini platform
+ case getTargetArchOS settingsFile mySettings of
+ Right archOS -> pure archOS
Left e -> die e
- let subdir = uniqueSubdir targetPlatformMini
+ let subdir = uniqueSubdir targetArchOS
dir = appdir </> subdir
r <- lookForPackageDBIn dir
case r of