2014-04-04 01:25:59 +00:00
|
|
|
{- Linux library copier and binary shimmer
|
|
|
|
-
|
2020-07-31 18:42:03 +00:00
|
|
|
- Copyright 2013-2020 Joey Hess <id@joeyh.name>
|
2014-04-04 01:25:59 +00:00
|
|
|
-
|
2014-05-10 14:01:27 +00:00
|
|
|
- License: BSD-2-clause
|
2014-04-04 01:25:59 +00:00
|
|
|
-}
|
|
|
|
|
2019-11-21 19:38:06 +00:00
|
|
|
module Utility.LinuxMkLibs (
|
|
|
|
installLib,
|
|
|
|
parseLdd,
|
|
|
|
glibcLibs,
|
2020-07-31 18:42:03 +00:00
|
|
|
gconvLibs,
|
2019-11-22 16:35:57 +00:00
|
|
|
inTop,
|
2019-11-21 19:38:06 +00:00
|
|
|
) where
|
2014-04-04 01:25:59 +00:00
|
|
|
|
2015-05-10 20:19:56 +00:00
|
|
|
import Utility.PartialPrelude
|
|
|
|
import Utility.Directory
|
|
|
|
import Utility.Process
|
|
|
|
import Utility.Monad
|
|
|
|
import Utility.Path
|
2020-10-28 19:40:50 +00:00
|
|
|
import Utility.Path.AbsRel
|
2017-05-16 03:32:17 +00:00
|
|
|
import Utility.Split
|
2020-10-28 19:40:50 +00:00
|
|
|
import Utility.FileSystemEncoding
|
2015-05-10 20:19:56 +00:00
|
|
|
|
2014-04-04 01:25:59 +00:00
|
|
|
import Data.Maybe
|
2015-01-06 22:59:13 +00:00
|
|
|
import System.FilePath
|
2014-04-04 01:25:59 +00:00
|
|
|
import System.Posix.Files
|
|
|
|
import Data.Char
|
|
|
|
import Control.Monad.IfElse
|
2015-05-10 20:19:56 +00:00
|
|
|
import Control.Applicative
|
|
|
|
import Prelude
|
2014-04-04 01:25:59 +00:00
|
|
|
|
|
|
|
{- Installs a library. If the library is a symlink to another file,
|
|
|
|
- install the file it links to, and update the symlink to be relative. -}
|
|
|
|
installLib :: (FilePath -> FilePath -> IO ()) -> FilePath -> FilePath -> IO (Maybe FilePath)
|
|
|
|
installLib installfile top lib = ifM (doesFileExist lib)
|
|
|
|
( do
|
|
|
|
installfile top lib
|
|
|
|
checksymlink lib
|
2020-10-28 19:40:50 +00:00
|
|
|
return $ Just $ fromRawFilePath $ parentDir $ toRawFilePath lib
|
2014-04-04 01:25:59 +00:00
|
|
|
, return Nothing
|
|
|
|
)
|
|
|
|
where
|
|
|
|
checksymlink f = whenM (isSymbolicLink <$> getSymbolicLinkStatus (inTop top f)) $ do
|
|
|
|
l <- readSymbolicLink (inTop top f)
|
2020-10-28 19:40:50 +00:00
|
|
|
let absl = absPathFrom
|
|
|
|
(parentDir (toRawFilePath f))
|
|
|
|
(toRawFilePath l)
|
|
|
|
target <- relPathDirToFile (toRawFilePath (takeDirectory f)) absl
|
|
|
|
installfile top (fromRawFilePath absl)
|
2020-10-29 14:33:12 +00:00
|
|
|
removeWhenExistsWith removeLink (top ++ f)
|
2020-10-28 19:40:50 +00:00
|
|
|
createSymbolicLink (fromRawFilePath target) (inTop top f)
|
|
|
|
checksymlink (fromRawFilePath absl)
|
2014-04-04 01:25:59 +00:00
|
|
|
|
|
|
|
-- Note that f is not relative, so cannot use </>
|
|
|
|
inTop :: FilePath -> FilePath -> FilePath
|
|
|
|
inTop top f = top ++ f
|
|
|
|
|
|
|
|
{- Parse ldd output, getting all the libraries that the input files
|
|
|
|
- link to. Note that some of the libraries may not exist
|
|
|
|
- (eg, linux-vdso.so) -}
|
|
|
|
parseLdd :: String -> [FilePath]
|
2014-04-26 23:25:05 +00:00
|
|
|
parseLdd = mapMaybe (getlib . dropWhile isSpace) . lines
|
2014-04-04 01:25:59 +00:00
|
|
|
where
|
|
|
|
getlib l = headMaybe . words =<< lastMaybe (split " => " l)
|
|
|
|
|
2020-07-31 18:42:03 +00:00
|
|
|
{- Get all glibc libs.
|
2014-04-04 01:25:59 +00:00
|
|
|
-
|
|
|
|
- XXX Debian specific. -}
|
|
|
|
glibcLibs :: IO [FilePath]
|
|
|
|
glibcLibs = lines <$> readProcess "sh"
|
2021-10-21 07:02:16 +00:00
|
|
|
["-c", "dpkg -L libc6:$(dpkg --print-architecture) | egrep '\\.so' | grep -v /gconv/ | grep -v ld.so.conf | grep -v sotruss-lib"]
|
2020-07-31 18:42:03 +00:00
|
|
|
|
|
|
|
{- Get gblibc's gconv libs, which are handled specially.. -}
|
|
|
|
gconvLibs :: IO [FilePath]
|
|
|
|
gconvLibs = lines <$> readProcess "sh"
|
|
|
|
["-c", "dpkg -L libc6:$(dpkg --print-architecture) | grep /gconv/"]
|
|
|
|
|