module GHC.Linker.Unit
( collectLinkOpts
, collectArchives
, getUnitLinkOpts
, getLibs
)
where
import GHC.Prelude
import GHC.Platform
import GHC.Platform.Ways
import GHC.Unit.Types
import GHC.Unit.Info
import GHC.Unit.State
import GHC.Unit.Env
import GHC.Utils.Misc
import qualified GHC.Data.ShortText as ST
import GHC.Settings
import Control.Monad
import System.Directory
import System.FilePath
getUnitLinkOpts :: GhcNameVersion -> Ways -> UnitEnv -> [UnitId] -> IO ([String], [String], [String])
getUnitLinkOpts :: GhcNameVersion
-> Ways -> UnitEnv -> [UnitId] -> IO ([[Char]], [[Char]], [[Char]])
getUnitLinkOpts GhcNameVersion
namever Ways
ways UnitEnv
unit_env [UnitId]
pkgs = do
[UnitInfo]
ps <- MaybeErr UnitErr [UnitInfo] -> IO [UnitInfo]
forall a. MaybeErr UnitErr a -> IO a
mayThrowUnitErr (MaybeErr UnitErr [UnitInfo] -> IO [UnitInfo])
-> MaybeErr UnitErr [UnitInfo] -> IO [UnitInfo]
forall a b. (a -> b) -> a -> b
$ UnitEnv -> [UnitId] -> MaybeErr UnitErr [UnitInfo]
preloadUnitsInfo' UnitEnv
unit_env [UnitId]
pkgs
let hs_pkgs :: [UnitInfo]
hs_pkgs
| Ways -> Way -> Bool
hasWay Ways
ways Way
WayDyn
, OS -> Bool
osElfTarget (Platform -> OS
platformOS (UnitEnv -> Platform
ue_platform UnitEnv
unit_env))
= [UnitInfo] -> [UnitInfo]
forall a. [a] -> [a]
reverse [UnitInfo]
ps
| Bool
otherwise = [UnitInfo]
ps
hs_libs :: [[Char]]
hs_libs = (UnitInfo -> [[Char]]) -> [UnitInfo] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char]
"-l" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++) ([[Char]] -> [[Char]])
-> (UnitInfo -> [[Char]]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GhcNameVersion -> Ways -> UnitInfo -> [[Char]]
unitHsLibs GhcNameVersion
namever Ways
ways) [UnitInfo]
hs_pkgs
([[Char]]
_, [[Char]]
extra_libs, [[Char]]
other_flags) = GhcNameVersion
-> Ways -> [UnitInfo] -> ([[Char]], [[Char]], [[Char]])
collectLinkOpts GhcNameVersion
namever Ways
ways [UnitInfo]
ps
([[Char]], [[Char]], [[Char]]) -> IO ([[Char]], [[Char]], [[Char]])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([[Char]]
hs_libs, [[Char]]
extra_libs, [[Char]]
other_flags)
collectLinkOpts :: GhcNameVersion -> Ways -> [UnitInfo] -> ([String], [String], [String])
collectLinkOpts :: GhcNameVersion
-> Ways -> [UnitInfo] -> ([[Char]], [[Char]], [[Char]])
collectLinkOpts GhcNameVersion
namever Ways
ways [UnitInfo]
ps =
(
(UnitInfo -> [[Char]]) -> [UnitInfo] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char]
"-l" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++) ([[Char]] -> [[Char]])
-> (UnitInfo -> [[Char]]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GhcNameVersion -> Ways -> UnitInfo -> [[Char]]
unitHsLibs GhcNameVersion
namever Ways
ways) [UnitInfo]
ps,
(UnitInfo -> [[Char]]) -> [UnitInfo] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ([Char]
"-l" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++) ([[Char]] -> [[Char]])
-> (UnitInfo -> [[Char]]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ShortText -> [Char]) -> [ShortText] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ShortText -> [Char]
ST.unpack ([ShortText] -> [[Char]])
-> (UnitInfo -> [ShortText]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitInfo -> [ShortText]
forall srcpkgid srcpkgname uid modulename mod.
GenericUnitInfo srcpkgid srcpkgname uid modulename mod
-> [ShortText]
unitExtDepLibsSys) [UnitInfo]
ps,
(UnitInfo -> [[Char]]) -> [UnitInfo] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((ShortText -> [Char]) -> [ShortText] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ShortText -> [Char]
ST.unpack ([ShortText] -> [[Char]])
-> (UnitInfo -> [ShortText]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitInfo -> [ShortText]
forall srcpkgid srcpkgname uid modulename mod.
GenericUnitInfo srcpkgid srcpkgname uid modulename mod
-> [ShortText]
unitLinkerOptions) [UnitInfo]
ps
)
collectArchives :: GhcNameVersion -> Ways -> UnitInfo -> IO [FilePath]
collectArchives :: GhcNameVersion -> Ways -> UnitInfo -> IO [[Char]]
collectArchives GhcNameVersion
namever Ways
ways UnitInfo
pc =
([Char] -> IO Bool) -> [[Char]] -> IO [[Char]]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM [Char] -> IO Bool
doesFileExist [ [Char]
searchPath [Char] -> [Char] -> [Char]
</> ([Char]
"lib" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
lib [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".a")
| [Char]
searchPath <- [[Char]]
searchPaths
, [Char]
lib <- [[Char]]
libs ]
where searchPaths :: [[Char]]
searchPaths = [[Char]] -> [[Char]]
forall a. Ord a => [a] -> [a]
ordNub ([[Char]] -> [[Char]])
-> (UnitInfo -> [[Char]]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char] -> Bool) -> [[Char]] -> [[Char]]
forall a. (a -> Bool) -> [a] -> [a]
filter [Char] -> Bool
forall (f :: * -> *) a. Foldable f => f a -> Bool
notNull ([[Char]] -> [[Char]])
-> (UnitInfo -> [[Char]]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ways -> UnitInfo -> [[Char]]
libraryDirsForWay Ways
ways (UnitInfo -> [[Char]]) -> UnitInfo -> [[Char]]
forall a b. (a -> b) -> a -> b
$ UnitInfo
pc
libs :: [[Char]]
libs = GhcNameVersion -> Ways -> UnitInfo -> [[Char]]
unitHsLibs GhcNameVersion
namever Ways
ways UnitInfo
pc [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ (ShortText -> [Char]) -> [ShortText] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ShortText -> [Char]
ST.unpack (UnitInfo -> [ShortText]
forall srcpkgid srcpkgname uid modulename mod.
GenericUnitInfo srcpkgid srcpkgname uid modulename mod
-> [ShortText]
unitExtDepLibsSys UnitInfo
pc)
libraryDirsForWay :: Ways -> UnitInfo -> [String]
libraryDirsForWay :: Ways -> UnitInfo -> [[Char]]
libraryDirsForWay Ways
ws
| Ways -> Way -> Bool
hasWay Ways
ws Way
WayDyn = (ShortText -> [Char]) -> [ShortText] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ShortText -> [Char]
ST.unpack ([ShortText] -> [[Char]])
-> (UnitInfo -> [ShortText]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitInfo -> [ShortText]
forall srcpkgid srcpkgname uid modulename mod.
GenericUnitInfo srcpkgid srcpkgname uid modulename mod
-> [ShortText]
unitLibraryDynDirs
| Bool
otherwise = (ShortText -> [Char]) -> [ShortText] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map ShortText -> [Char]
ST.unpack ([ShortText] -> [[Char]])
-> (UnitInfo -> [ShortText]) -> UnitInfo -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnitInfo -> [ShortText]
forall srcpkgid srcpkgname uid modulename mod.
GenericUnitInfo srcpkgid srcpkgname uid modulename mod
-> [ShortText]
unitLibraryDirs
getLibs :: GhcNameVersion -> Ways -> UnitEnv -> [UnitId] -> IO [(String,String)]
getLibs :: GhcNameVersion
-> Ways -> UnitEnv -> [UnitId] -> IO [([Char], [Char])]
getLibs GhcNameVersion
namever Ways
ways UnitEnv
unit_env [UnitId]
pkgs = do
[UnitInfo]
ps <- MaybeErr UnitErr [UnitInfo] -> IO [UnitInfo]
forall a. MaybeErr UnitErr a -> IO a
mayThrowUnitErr (MaybeErr UnitErr [UnitInfo] -> IO [UnitInfo])
-> MaybeErr UnitErr [UnitInfo] -> IO [UnitInfo]
forall a b. (a -> b) -> a -> b
$ UnitEnv -> [UnitId] -> MaybeErr UnitErr [UnitInfo]
preloadUnitsInfo' UnitEnv
unit_env [UnitId]
pkgs
([[([Char], [Char])]] -> [([Char], [Char])])
-> IO [[([Char], [Char])]] -> IO [([Char], [Char])]
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[([Char], [Char])]] -> [([Char], [Char])]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (IO [[([Char], [Char])]] -> IO [([Char], [Char])])
-> ((UnitInfo -> IO [([Char], [Char])]) -> IO [[([Char], [Char])]])
-> (UnitInfo -> IO [([Char], [Char])])
-> IO [([Char], [Char])]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [UnitInfo]
-> (UnitInfo -> IO [([Char], [Char])]) -> IO [[([Char], [Char])]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [UnitInfo]
ps ((UnitInfo -> IO [([Char], [Char])]) -> IO [([Char], [Char])])
-> (UnitInfo -> IO [([Char], [Char])]) -> IO [([Char], [Char])]
forall a b. (a -> b) -> a -> b
$ \UnitInfo
p -> do
let candidates :: [([Char], [Char])]
candidates = [ ([Char]
l [Char] -> [Char] -> [Char]
</> [Char]
f, [Char]
f) | [Char]
l <- Ways -> [UnitInfo] -> [[Char]]
collectLibraryDirs Ways
ways [UnitInfo
p]
, [Char]
f <- (\[Char]
n -> [Char]
"lib" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
n [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".a") ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GhcNameVersion -> Ways -> UnitInfo -> [[Char]]
unitHsLibs GhcNameVersion
namever Ways
ways UnitInfo
p ]
(([Char], [Char]) -> IO Bool)
-> [([Char], [Char])] -> IO [([Char], [Char])]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM ([Char] -> IO Bool
doesFileExist ([Char] -> IO Bool)
-> (([Char], [Char]) -> [Char]) -> ([Char], [Char]) -> IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Char], [Char]) -> [Char]
forall a b. (a, b) -> a
fst) [([Char], [Char])]
candidates