a1730cd6af
Removed dependency on MissingH, instead depending on the split library. After laying groundwork for this since 2015, it was mostly straightforward. Added Utility.Tuple and Utility.Split. Eyeballed System.Path.WildMatch while implementing the same thing. Since MissingH's progress meter display was being used, I re-implemented my own. Bonus: Now progress is displayed for transfers of files of unknown size. This commit was sponsored by Shane-o on Patreon.
62 lines
1.8 KiB
Haskell
62 lines
1.8 KiB
Haskell
{- Linux library copier and binary shimmer
|
|
-
|
|
- Copyright 2013 Joey Hess <id@joeyh.name>
|
|
-
|
|
- License: BSD-2-clause
|
|
-}
|
|
|
|
module Utility.LinuxMkLibs where
|
|
|
|
import Utility.PartialPrelude
|
|
import Utility.Directory
|
|
import Utility.Process
|
|
import Utility.Monad
|
|
import Utility.Path
|
|
import Utility.Split
|
|
|
|
import Data.Maybe
|
|
import System.FilePath
|
|
import System.Posix.Files
|
|
import Data.Char
|
|
import Control.Monad.IfElse
|
|
import Control.Applicative
|
|
import Prelude
|
|
|
|
{- 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
|
|
return $ Just $ parentDir lib
|
|
, return Nothing
|
|
)
|
|
where
|
|
checksymlink f = whenM (isSymbolicLink <$> getSymbolicLinkStatus (inTop top f)) $ do
|
|
l <- readSymbolicLink (inTop top f)
|
|
let absl = absPathFrom (parentDir f) l
|
|
target <- relPathDirToFile (takeDirectory f) absl
|
|
installfile top absl
|
|
nukeFile (top ++ f)
|
|
createSymbolicLink target (inTop top f)
|
|
checksymlink absl
|
|
|
|
-- 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]
|
|
parseLdd = mapMaybe (getlib . dropWhile isSpace) . lines
|
|
where
|
|
getlib l = headMaybe . words =<< lastMaybe (split " => " l)
|
|
|
|
{- Get all glibc libs and other support files, including gconv files
|
|
-
|
|
- XXX Debian specific. -}
|
|
glibcLibs :: IO [FilePath]
|
|
glibcLibs = lines <$> readProcess "sh"
|
|
["-c", "dpkg -L libc6:$(dpkg --print-architecture) libgcc1:$(dpkg --print-architecture) | egrep '\\.so|gconv'"]
|