{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE MultiWayIf #-}
module GHC.Toolchain.Target
  (
    -- * A Toolchain Target
    Target(..), targetPlatformTriple

  , WordSize(..), wordSize2Bytes

    -- ** Queries
  , tgtSupportsSMP, tgtRTSLinkerOnlySupportsSharedLibs

    -- ** Lenses
  , _tgtCC, _tgtCxx, _tgtCpp, _tgtHsCpp

    -- * Re-exports
  , ByteOrder(..)
  ) where

import GHC.ByteOrder
import GHC.Platform.ArchOS

import GHC.Toolchain.Prelude
import GHC.Toolchain.Program
import GHC.Toolchain.Library

import GHC.Toolchain.Tools.Cc
import GHC.Toolchain.Tools.Cxx
import GHC.Toolchain.Tools.Cpp
import GHC.Toolchain.Tools.Ar
import GHC.Toolchain.Tools.Ranlib
import GHC.Toolchain.Tools.Link
import GHC.Toolchain.Tools.Nm
import GHC.Toolchain.Tools.MergeObjs

data WordSize = WS4 | WS8
    deriving (Int -> WordSize -> ShowS
[WordSize] -> ShowS
WordSize -> [Char]
(Int -> WordSize -> ShowS)
-> (WordSize -> [Char]) -> ([WordSize] -> ShowS) -> Show WordSize
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> WordSize -> ShowS
showsPrec :: Int -> WordSize -> ShowS
$cshow :: WordSize -> [Char]
show :: WordSize -> [Char]
$cshowList :: [WordSize] -> ShowS
showList :: [WordSize] -> ShowS
Show, ReadPrec [WordSize]
ReadPrec WordSize
Int -> ReadS WordSize
ReadS [WordSize]
(Int -> ReadS WordSize)
-> ReadS [WordSize]
-> ReadPrec WordSize
-> ReadPrec [WordSize]
-> Read WordSize
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS WordSize
readsPrec :: Int -> ReadS WordSize
$creadList :: ReadS [WordSize]
readList :: ReadS [WordSize]
$creadPrec :: ReadPrec WordSize
readPrec :: ReadPrec WordSize
$creadListPrec :: ReadPrec [WordSize]
readListPrec :: ReadPrec [WordSize]
Read, WordSize -> WordSize -> Bool
(WordSize -> WordSize -> Bool)
-> (WordSize -> WordSize -> Bool) -> Eq WordSize
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WordSize -> WordSize -> Bool
== :: WordSize -> WordSize -> Bool
$c/= :: WordSize -> WordSize -> Bool
/= :: WordSize -> WordSize -> Bool
Eq, Eq WordSize
Eq WordSize =>
(WordSize -> WordSize -> Ordering)
-> (WordSize -> WordSize -> Bool)
-> (WordSize -> WordSize -> Bool)
-> (WordSize -> WordSize -> Bool)
-> (WordSize -> WordSize -> Bool)
-> (WordSize -> WordSize -> WordSize)
-> (WordSize -> WordSize -> WordSize)
-> Ord WordSize
WordSize -> WordSize -> Bool
WordSize -> WordSize -> Ordering
WordSize -> WordSize -> WordSize
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: WordSize -> WordSize -> Ordering
compare :: WordSize -> WordSize -> Ordering
$c< :: WordSize -> WordSize -> Bool
< :: WordSize -> WordSize -> Bool
$c<= :: WordSize -> WordSize -> Bool
<= :: WordSize -> WordSize -> Bool
$c> :: WordSize -> WordSize -> Bool
> :: WordSize -> WordSize -> Bool
$c>= :: WordSize -> WordSize -> Bool
>= :: WordSize -> WordSize -> Bool
$cmax :: WordSize -> WordSize -> WordSize
max :: WordSize -> WordSize -> WordSize
$cmin :: WordSize -> WordSize -> WordSize
min :: WordSize -> WordSize -> WordSize
Ord)

-- | A 'Target' consists of:
--
-- * a target architecture and operating system
-- * various bits of information about the platform
-- * various toolchain components targetting that platform
data Target = Target
    { -- Platform
      Target -> ArchOS
tgtArchOs :: ArchOS
    , Target -> Maybe [Char]
tgtVendor :: Maybe String -- ^ This is the vendor component of the triple, the other two components are found in @'tgtArchOs'@
    , Target -> Bool
tgtLocallyExecutable :: Bool
    , Target -> Bool
tgtSupportsGnuNonexecStack :: Bool
    , Target -> Bool
tgtSupportsSubsectionsViaSymbols :: Bool
    , Target -> Bool
tgtSupportsIdentDirective :: Bool
    , Target -> WordSize
tgtWordSize :: WordSize
    , Target -> ByteOrder
tgtEndianness :: ByteOrder
    , Target -> Bool
tgtSymbolsHaveLeadingUnderscore :: Bool
    , Target -> [Char]
tgtLlvmTarget :: String

      -- GHC capabilities
    , Target -> Bool
tgtUnregisterised :: Bool
    , Target -> Bool
tgtTablesNextToCode :: Bool
    -- , tgtHasThreadedRts :: Bool -- We likely just need this when bootstrapping
    , Target -> Bool
tgtUseLibffiForAdjustors :: Bool
    -- ^ We need to know whether or not to include libffi headers, and generate additional code for it
    , Target -> Bool
tgtHasLibm :: Bool
    -- ^ Does this target have a libm library that should always be linked against?

    -- RTS capabilities
    , Target -> Maybe Library
tgtRTSWithLibdw :: Maybe Library
    -- ^ Whether this target RTS is built with libdw support (for DWARF
    -- unwinding), and if yes, the 'Library' configuration.

      -- C toolchain
    , Target -> Cc
tgtCCompiler :: Cc
    , Target -> Cxx
tgtCxxCompiler :: Cxx
    , Target -> Cpp
tgtCPreprocessor :: Cpp
    , Target -> HsCpp
tgtHsCPreprocessor :: HsCpp
    , Target -> Maybe JsCpp
tgtJsCPreprocessor :: Maybe JsCpp
    , Target -> CmmCpp
tgtCmmCPreprocessor :: CmmCpp
    -- ^ We set it only in javascript target
    , Target -> CcLink
tgtCCompilerLink :: CcLink
    , Target -> Ar
tgtAr :: Ar
    , Target -> Maybe Ranlib
tgtRanlib :: Maybe Ranlib
    -- ^ N.B. Most @ar@ implementations will add an index by default without @ranlib@ so this is often optional
    , Target -> Nm
tgtNm :: Nm
    , Target -> Maybe MergeObjs
tgtMergeObjs :: Maybe MergeObjs
    -- ^ We don't need a merge objects tool if we @Ar@ supports @-L@

      -- LLVM backend toolchain
    , Target -> Maybe Program
tgtLlc :: Maybe Program
    , Target -> Maybe Program
tgtOpt :: Maybe Program
    , Target -> Maybe Program
tgtLlvmAs :: Maybe Program
    -- ^ assembler used to assemble LLVM backend output; typically @clang@

      -- Windows-specific tools
    , Target -> Maybe Program
tgtWindres :: Maybe Program

      -- Darwin-specific tools
    , Target -> Maybe Program
tgtOtool   :: Maybe Program
    , Target -> Maybe Program
tgtInstallNameTool :: Maybe Program
    }
    deriving (ReadPrec [Target]
ReadPrec Target
Int -> ReadS Target
ReadS [Target]
(Int -> ReadS Target)
-> ReadS [Target]
-> ReadPrec Target
-> ReadPrec [Target]
-> Read Target
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Target
readsPrec :: Int -> ReadS Target
$creadList :: ReadS [Target]
readList :: ReadS [Target]
$creadPrec :: ReadPrec Target
readPrec :: ReadPrec Target
$creadListPrec :: ReadPrec [Target]
readListPrec :: ReadPrec [Target]
Read, Target -> Target -> Bool
(Target -> Target -> Bool)
-> (Target -> Target -> Bool) -> Eq Target
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Target -> Target -> Bool
== :: Target -> Target -> Bool
$c/= :: Target -> Target -> Bool
/= :: Target -> Target -> Bool
Eq, Eq Target
Eq Target =>
(Target -> Target -> Ordering)
-> (Target -> Target -> Bool)
-> (Target -> Target -> Bool)
-> (Target -> Target -> Bool)
-> (Target -> Target -> Bool)
-> (Target -> Target -> Target)
-> (Target -> Target -> Target)
-> Ord Target
Target -> Target -> Bool
Target -> Target -> Ordering
Target -> Target -> Target
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Target -> Target -> Ordering
compare :: Target -> Target -> Ordering
$c< :: Target -> Target -> Bool
< :: Target -> Target -> Bool
$c<= :: Target -> Target -> Bool
<= :: Target -> Target -> Bool
$c> :: Target -> Target -> Bool
> :: Target -> Target -> Bool
$c>= :: Target -> Target -> Bool
>= :: Target -> Target -> Bool
$cmax :: Target -> Target -> Target
max :: Target -> Target -> Target
$cmin :: Target -> Target -> Target
min :: Target -> Target -> Target
Ord)

-- | The word size as an integer representing the number of bytes
wordSize2Bytes :: WordSize -> Int
wordSize2Bytes :: WordSize -> Int
wordSize2Bytes WordSize
WS4 = Int
4
wordSize2Bytes WordSize
WS8 = Int
8

-- | Reconstruct the platform triple from a toolchain target
-- (specifically from tgtArchOs and tgtVendor)
targetPlatformTriple :: Target -> String
targetPlatformTriple :: Target -> [Char]
targetPlatformTriple Target{ArchOS
tgtArchOs :: Target -> ArchOS
tgtArchOs :: ArchOS
tgtArchOs, Maybe [Char]
tgtVendor :: Target -> Maybe [Char]
tgtVendor :: Maybe [Char]
tgtVendor} =
  let archStr :: [Char]
archStr = Arch -> [Char]
stringEncodeArch (Arch -> [Char]) -> Arch -> [Char]
forall a b. (a -> b) -> a -> b
$ ArchOS -> Arch
archOS_arch ArchOS
tgtArchOs
      osStr :: [Char]
osStr   = OS -> [Char]
stringEncodeOS (OS -> [Char]) -> OS -> [Char]
forall a b. (a -> b) -> a -> b
$ ArchOS -> OS
archOS_OS ArchOS
tgtArchOs
   in case Maybe [Char]
tgtVendor of
        Maybe [Char]
Nothing -> [Char]
archStr [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
"-" [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
osStr
        Just [Char]
vendor -> [Char]
archStr [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
"-" [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
vendor [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
"-" [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
osStr

-- | Handwritten Show instance to have have better diffs against the toolchain
-- targets generated by configure
instance Show Target where
  show :: Target -> [Char]
show Target{Bool
[Char]
Maybe [Char]
Maybe Library
Maybe Program
Maybe Ranlib
Maybe MergeObjs
Maybe JsCpp
ByteOrder
ArchOS
Nm
Cxx
Cc
CcLink
CmmCpp
HsCpp
Cpp
Ar
WordSize
tgtArchOs :: Target -> ArchOS
tgtVendor :: Target -> Maybe [Char]
tgtLocallyExecutable :: Target -> Bool
tgtSupportsGnuNonexecStack :: Target -> Bool
tgtSupportsSubsectionsViaSymbols :: Target -> Bool
tgtSupportsIdentDirective :: Target -> Bool
tgtWordSize :: Target -> WordSize
tgtEndianness :: Target -> ByteOrder
tgtSymbolsHaveLeadingUnderscore :: Target -> Bool
tgtLlvmTarget :: Target -> [Char]
tgtUnregisterised :: Target -> Bool
tgtTablesNextToCode :: Target -> Bool
tgtUseLibffiForAdjustors :: Target -> Bool
tgtHasLibm :: Target -> Bool
tgtRTSWithLibdw :: Target -> Maybe Library
tgtCCompiler :: Target -> Cc
tgtCxxCompiler :: Target -> Cxx
tgtCPreprocessor :: Target -> Cpp
tgtHsCPreprocessor :: Target -> HsCpp
tgtJsCPreprocessor :: Target -> Maybe JsCpp
tgtCmmCPreprocessor :: Target -> CmmCpp
tgtCCompilerLink :: Target -> CcLink
tgtAr :: Target -> Ar
tgtRanlib :: Target -> Maybe Ranlib
tgtNm :: Target -> Nm
tgtMergeObjs :: Target -> Maybe MergeObjs
tgtLlc :: Target -> Maybe Program
tgtOpt :: Target -> Maybe Program
tgtLlvmAs :: Target -> Maybe Program
tgtWindres :: Target -> Maybe Program
tgtOtool :: Target -> Maybe Program
tgtInstallNameTool :: Target -> Maybe Program
tgtArchOs :: ArchOS
tgtVendor :: Maybe [Char]
tgtLocallyExecutable :: Bool
tgtSupportsGnuNonexecStack :: Bool
tgtSupportsSubsectionsViaSymbols :: Bool
tgtSupportsIdentDirective :: Bool
tgtWordSize :: WordSize
tgtEndianness :: ByteOrder
tgtSymbolsHaveLeadingUnderscore :: Bool
tgtLlvmTarget :: [Char]
tgtUnregisterised :: Bool
tgtTablesNextToCode :: Bool
tgtUseLibffiForAdjustors :: Bool
tgtHasLibm :: Bool
tgtRTSWithLibdw :: Maybe Library
tgtCCompiler :: Cc
tgtCxxCompiler :: Cxx
tgtCPreprocessor :: Cpp
tgtHsCPreprocessor :: HsCpp
tgtJsCPreprocessor :: Maybe JsCpp
tgtCmmCPreprocessor :: CmmCpp
tgtCCompilerLink :: CcLink
tgtAr :: Ar
tgtRanlib :: Maybe Ranlib
tgtNm :: Nm
tgtMergeObjs :: Maybe MergeObjs
tgtLlc :: Maybe Program
tgtOpt :: Maybe Program
tgtLlvmAs :: Maybe Program
tgtWindres :: Maybe Program
tgtOtool :: Maybe Program
tgtInstallNameTool :: Maybe Program
..} = [[Char]] -> [Char]
unlines
    [ [Char]
"Target"
    , [Char]
"{ tgtArchOs = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ArchOS -> [Char]
forall a. Show a => a -> [Char]
show ArchOS
tgtArchOs
    , [Char]
", tgtVendor = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe [Char] -> [Char]
forall a. Show a => a -> [Char]
show Maybe [Char]
tgtVendor
    , [Char]
", tgtLocallyExecutable = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtLocallyExecutable
    , [Char]
", tgtSupportsGnuNonexecStack = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtSupportsGnuNonexecStack
    , [Char]
", tgtSupportsSubsectionsViaSymbols = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtSupportsSubsectionsViaSymbols
    , [Char]
", tgtSupportsIdentDirective = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtSupportsIdentDirective
    , [Char]
", tgtWordSize = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ WordSize -> [Char]
forall a. Show a => a -> [Char]
show WordSize
tgtWordSize
    , [Char]
", tgtEndianness = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ByteOrder -> [Char]
forall a. Show a => a -> [Char]
show ByteOrder
tgtEndianness
    , [Char]
", tgtSymbolsHaveLeadingUnderscore = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtSymbolsHaveLeadingUnderscore
    , [Char]
", tgtLlvmTarget = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
forall a. Show a => a -> [Char]
show [Char]
tgtLlvmTarget
    , [Char]
", tgtUnregisterised = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtUnregisterised
    , [Char]
", tgtTablesNextToCode = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtTablesNextToCode
    , [Char]
", tgtUseLibffiForAdjustors = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtUseLibffiForAdjustors
    , [Char]
", tgtHasLibm = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Bool -> [Char]
forall a. Show a => a -> [Char]
show Bool
tgtHasLibm
    , [Char]
", tgtRTSWithLibdw = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe Library -> [Char]
forall a. Show a => a -> [Char]
show Maybe Library
tgtRTSWithLibdw
    , [Char]
", tgtCCompiler = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Cc -> [Char]
forall a. Show a => a -> [Char]
show Cc
tgtCCompiler
    , [Char]
", tgtCxxCompiler = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Cxx -> [Char]
forall a. Show a => a -> [Char]
show Cxx
tgtCxxCompiler
    , [Char]
", tgtCPreprocessor = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Cpp -> [Char]
forall a. Show a => a -> [Char]
show Cpp
tgtCPreprocessor
    , [Char]
", tgtHsCPreprocessor = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ HsCpp -> [Char]
forall a. Show a => a -> [Char]
show HsCpp
tgtHsCPreprocessor
    , [Char]
", tgtJsCPreprocessor = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe JsCpp -> [Char]
forall a. Show a => a -> [Char]
show Maybe JsCpp
tgtJsCPreprocessor
    , [Char]
", tgtCmmCPreprocessor = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ CmmCpp -> [Char]
forall a. Show a => a -> [Char]
show CmmCpp
tgtCmmCPreprocessor
    , [Char]
", tgtCCompilerLink = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ CcLink -> [Char]
forall a. Show a => a -> [Char]
show CcLink
tgtCCompilerLink
    , [Char]
", tgtAr = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Ar -> [Char]
forall a. Show a => a -> [Char]
show Ar
tgtAr
    , [Char]
", tgtRanlib = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe Ranlib -> [Char]
forall a. Show a => a -> [Char]
show Maybe Ranlib
tgtRanlib
    , [Char]
", tgtNm = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Nm -> [Char]
forall a. Show a => a -> [Char]
show Nm
tgtNm
    , [Char]
", tgtMergeObjs = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe MergeObjs -> [Char]
forall a. Show a => a -> [Char]
show Maybe MergeObjs
tgtMergeObjs
    , [Char]
", tgtLlc = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe Program -> [Char]
forall a. Show a => a -> [Char]
show Maybe Program
tgtLlc
    , [Char]
", tgtOpt = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe Program -> [Char]
forall a. Show a => a -> [Char]
show Maybe Program
tgtOpt
    , [Char]
", tgtLlvmAs = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe Program -> [Char]
forall a. Show a => a -> [Char]
show Maybe Program
tgtLlvmAs
    , [Char]
", tgtWindres = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe Program -> [Char]
forall a. Show a => a -> [Char]
show Maybe Program
tgtWindres
    , [Char]
", tgtOtool = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe Program -> [Char]
forall a. Show a => a -> [Char]
show Maybe Program
tgtOtool
    , [Char]
", tgtInstallNameTool = " [Char] -> ShowS
forall a. [a] -> [a] -> [a]
++ Maybe Program -> [Char]
forall a. Show a => a -> [Char]
show Maybe Program
tgtInstallNameTool
    , [Char]
"}"
    ]

--------------------------------------------------------------------------------
-- Queries
--------------------------------------------------------------------------------

tgtSupportsSMP :: Target -> Bool
tgtSupportsSMP :: Target -> Bool
tgtSupportsSMP Target{Bool
[Char]
Maybe [Char]
Maybe Library
Maybe Program
Maybe Ranlib
Maybe MergeObjs
Maybe JsCpp
ByteOrder
ArchOS
Nm
Cxx
Cc
CcLink
CmmCpp
HsCpp
Cpp
Ar
WordSize
tgtArchOs :: Target -> ArchOS
tgtVendor :: Target -> Maybe [Char]
tgtLocallyExecutable :: Target -> Bool
tgtSupportsGnuNonexecStack :: Target -> Bool
tgtSupportsSubsectionsViaSymbols :: Target -> Bool
tgtSupportsIdentDirective :: Target -> Bool
tgtWordSize :: Target -> WordSize
tgtEndianness :: Target -> ByteOrder
tgtSymbolsHaveLeadingUnderscore :: Target -> Bool
tgtLlvmTarget :: Target -> [Char]
tgtUnregisterised :: Target -> Bool
tgtTablesNextToCode :: Target -> Bool
tgtUseLibffiForAdjustors :: Target -> Bool
tgtHasLibm :: Target -> Bool
tgtRTSWithLibdw :: Target -> Maybe Library
tgtCCompiler :: Target -> Cc
tgtCxxCompiler :: Target -> Cxx
tgtCPreprocessor :: Target -> Cpp
tgtHsCPreprocessor :: Target -> HsCpp
tgtJsCPreprocessor :: Target -> Maybe JsCpp
tgtCmmCPreprocessor :: Target -> CmmCpp
tgtCCompilerLink :: Target -> CcLink
tgtAr :: Target -> Ar
tgtRanlib :: Target -> Maybe Ranlib
tgtNm :: Target -> Nm
tgtMergeObjs :: Target -> Maybe MergeObjs
tgtLlc :: Target -> Maybe Program
tgtOpt :: Target -> Maybe Program
tgtLlvmAs :: Target -> Maybe Program
tgtWindres :: Target -> Maybe Program
tgtOtool :: Target -> Maybe Program
tgtInstallNameTool :: Target -> Maybe Program
tgtArchOs :: ArchOS
tgtVendor :: Maybe [Char]
tgtLocallyExecutable :: Bool
tgtSupportsGnuNonexecStack :: Bool
tgtSupportsSubsectionsViaSymbols :: Bool
tgtSupportsIdentDirective :: Bool
tgtWordSize :: WordSize
tgtEndianness :: ByteOrder
tgtSymbolsHaveLeadingUnderscore :: Bool
tgtLlvmTarget :: [Char]
tgtUnregisterised :: Bool
tgtTablesNextToCode :: Bool
tgtUseLibffiForAdjustors :: Bool
tgtHasLibm :: Bool
tgtRTSWithLibdw :: Maybe Library
tgtCCompiler :: Cc
tgtCxxCompiler :: Cxx
tgtCPreprocessor :: Cpp
tgtHsCPreprocessor :: HsCpp
tgtJsCPreprocessor :: Maybe JsCpp
tgtCmmCPreprocessor :: CmmCpp
tgtCCompilerLink :: CcLink
tgtAr :: Ar
tgtRanlib :: Maybe Ranlib
tgtNm :: Nm
tgtMergeObjs :: Maybe MergeObjs
tgtLlc :: Maybe Program
tgtOpt :: Maybe Program
tgtLlvmAs :: Maybe Program
tgtWindres :: Maybe Program
tgtOtool :: Maybe Program
tgtInstallNameTool :: Maybe Program
..} = do
  let goodArch :: Bool
goodArch =
        Arch -> Bool
isARM (ArchOS -> Arch
archOS_arch ArchOS
tgtArchOs)
          Bool -> Bool -> Bool
|| ArchOS -> Arch
archOS_arch ArchOS
tgtArchOs Arch -> [Arch] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
              [ Arch
ArchX86
              , Arch
ArchX86_64
              , Arch
ArchPPC
              , PPC_64ABI -> Arch
ArchPPC_64 PPC_64ABI
ELF_V1
              , PPC_64ABI -> Arch
ArchPPC_64 PPC_64ABI
ELF_V2
              , Arch
ArchAArch64
              , Arch
ArchS390X
              , Arch
ArchRISCV64
              , Arch
ArchLoongArch64 ]

  if   -- The THREADED_RTS requires `BaseReg` to be in a register and the
       -- Unregisterised mode doesn't allow that.
     | Bool
tgtUnregisterised    -> Bool
False
       -- We don't support load/store barriers pre-ARMv7. See #10433.
     | ArchARM ArmISA
ver [ArmISAExt]
_ ArmABI
_ <- ArchOS -> Arch
archOS_arch ArchOS
tgtArchOs
     , ArmISA
ver ArmISA -> ArmISA -> Bool
forall a. Ord a => a -> a -> Bool
< ArmISA
ARMv7          -> Bool
False
     | Bool
goodArch             -> Bool
True
     | Bool
otherwise            -> Bool
False

-- | Does the target RTS linker only support loading shared libraries?
-- If true, this has several implications:
-- 1. The GHC driver must not do loadArchive/loadObj etc and must
--    always do loadDLL, regardless of whether host GHC is dynamic or
--    not.
-- 2. The GHC driver will always enable -dynamic-too when compiling
--    vanilla way with TH codegen requirement.
-- 3. ghci will always enforce dynamic ways even if -dynamic or
--    -dynamic-too is not explicitly passed.
-- 4. Cabal must not build ghci objects since it's not supported by
--    the target.
-- 5. The testsuite driver will use dyn way for TH/ghci tests even
--    when host GHC is static.
-- 6. TH/ghci doesn't work if stage1 is built without shared libraries
--    (e.g. quickest/fully_static).
tgtRTSLinkerOnlySupportsSharedLibs :: Target -> Bool
tgtRTSLinkerOnlySupportsSharedLibs :: Target -> Bool
tgtRTSLinkerOnlySupportsSharedLibs Target{ArchOS
tgtArchOs :: Target -> ArchOS
tgtArchOs :: ArchOS
tgtArchOs} =
  ArchOS -> Arch
archOS_arch ArchOS
tgtArchOs Arch -> [Arch] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem`
    [ Arch
ArchWasm32 ]

--------------------------------------------------------------------------------
-- Lenses
--------------------------------------------------------------------------------

_tgtCC :: Lens Target Cc
_tgtCC :: Lens Target Cc
_tgtCC = (Target -> Cc) -> (Cc -> Target -> Target) -> Lens Target Cc
forall a b. (a -> b) -> (b -> a -> a) -> Lens a b
Lens Target -> Cc
tgtCCompiler (\Cc
x Target
o -> Target
o {tgtCCompiler = x})

_tgtCxx :: Lens Target Cxx
_tgtCxx :: Lens Target Cxx
_tgtCxx = (Target -> Cxx) -> (Cxx -> Target -> Target) -> Lens Target Cxx
forall a b. (a -> b) -> (b -> a -> a) -> Lens a b
Lens Target -> Cxx
tgtCxxCompiler (\Cxx
x Target
o -> Target
o {tgtCxxCompiler = x})

_tgtCpp :: Lens Target Cpp
_tgtCpp :: Lens Target Cpp
_tgtCpp = (Target -> Cpp) -> (Cpp -> Target -> Target) -> Lens Target Cpp
forall a b. (a -> b) -> (b -> a -> a) -> Lens a b
Lens Target -> Cpp
tgtCPreprocessor (\Cpp
x Target
o -> Target
o {tgtCPreprocessor = x})

_tgtHsCpp :: Lens Target HsCpp
_tgtHsCpp :: Lens Target HsCpp
_tgtHsCpp = (Target -> HsCpp)
-> (HsCpp -> Target -> Target) -> Lens Target HsCpp
forall a b. (a -> b) -> (b -> a -> a) -> Lens a b
Lens Target -> HsCpp
tgtHsCPreprocessor (\HsCpp
x Target
o -> Target
o {tgtHsCPreprocessor = x})

_tgtJsCpp :: Lens Target (Maybe JsCpp)
_tgtJsCpp :: Lens Target (Maybe JsCpp)
_tgtJsCpp = (Target -> Maybe JsCpp)
-> (Maybe JsCpp -> Target -> Target) -> Lens Target (Maybe JsCpp)
forall a b. (a -> b) -> (b -> a -> a) -> Lens a b
Lens Target -> Maybe JsCpp
tgtJsCPreprocessor (\Maybe JsCpp
x Target
o -> Target
o {tgtJsCPreprocessor = x})

_tgtCmmCpp :: Lens Target CmmCpp
_tgtCmmCpp :: Lens Target CmmCpp
_tgtCmmCpp = (Target -> CmmCpp)
-> (CmmCpp -> Target -> Target) -> Lens Target CmmCpp
forall a b. (a -> b) -> (b -> a -> a) -> Lens a b
Lens Target -> CmmCpp
tgtCmmCPreprocessor (\CmmCpp
x Target
o -> Target
o {tgtCmmCPreprocessor = x})

_tgtMergeObjs :: Lens Target (Maybe MergeObjs)
_tgtMergeObjs :: Lens Target (Maybe MergeObjs)
_tgtMergeObjs = (Target -> Maybe MergeObjs)
-> (Maybe MergeObjs -> Target -> Target)
-> Lens Target (Maybe MergeObjs)
forall a b. (a -> b) -> (b -> a -> a) -> Lens a b
Lens Target -> Maybe MergeObjs
tgtMergeObjs (\Maybe MergeObjs
x Target
o -> Target
o {tgtMergeObjs = x})