factor out library code (also used by propellor)
This commit is contained in:
parent
acda14abc9
commit
611e060385
2 changed files with 63 additions and 43 deletions
|
@ -14,12 +14,10 @@ import System.FilePath
|
||||||
import System.Directory
|
import System.Directory
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.List.Utils
|
|
||||||
import System.Posix.Files
|
import System.Posix.Files
|
||||||
import Data.Char
|
|
||||||
import Control.Monad.IfElse
|
import Control.Monad.IfElse
|
||||||
|
|
||||||
import Utility.PartialPrelude
|
import Utility.LinuxMkLibs
|
||||||
import Utility.Directory
|
import Utility.Directory
|
||||||
import Utility.Process
|
import Utility.Process
|
||||||
import Utility.Monad
|
import Utility.Monad
|
||||||
|
@ -41,7 +39,7 @@ mklibs top = do
|
||||||
libs <- parseLdd <$> readProcess "ldd" exes
|
libs <- parseLdd <$> readProcess "ldd" exes
|
||||||
glibclibs <- glibcLibs
|
glibclibs <- glibcLibs
|
||||||
let libs' = nub $ libs ++ glibclibs
|
let libs' = nub $ libs ++ glibclibs
|
||||||
libdirs <- nub . catMaybes <$> mapM (installLib top) libs'
|
libdirs <- nub . catMaybes <$> mapM (installLib installFile top) libs'
|
||||||
|
|
||||||
-- Various files used by runshell to set up env vars used by the
|
-- Various files used by runshell to set up env vars used by the
|
||||||
-- linker shims.
|
-- linker shims.
|
||||||
|
@ -53,26 +51,6 @@ mklibs top = do
|
||||||
|
|
||||||
mapM_ (installLinkerShim top) exes
|
mapM_ (installLinkerShim top) exes
|
||||||
|
|
||||||
{- 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 (Maybe FilePath)
|
|
||||||
installLib 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
|
|
||||||
let target = relPathDirToFile (parentDir f) absl
|
|
||||||
installFile top absl
|
|
||||||
nukeFile (top ++ f)
|
|
||||||
createSymbolicLink target (inTop top f)
|
|
||||||
checksymlink absl
|
|
||||||
|
|
||||||
{- Installs a linker shim script around a binary.
|
{- Installs a linker shim script around a binary.
|
||||||
-
|
-
|
||||||
- Note that each binary is put into its own separate directory,
|
- Note that each binary is put into its own separate directory,
|
||||||
|
@ -108,10 +86,6 @@ installFile top f = do
|
||||||
where
|
where
|
||||||
destdir = inTop top $ parentDir f
|
destdir = inTop top $ parentDir f
|
||||||
|
|
||||||
-- Note that f is not relative, so cannot use </>
|
|
||||||
inTop :: FilePath -> FilePath -> FilePath
|
|
||||||
inTop top f = top ++ f --
|
|
||||||
|
|
||||||
checkExe :: FilePath -> IO Bool
|
checkExe :: FilePath -> IO Bool
|
||||||
checkExe f
|
checkExe f
|
||||||
| ".so" `isSuffixOf` f = return False
|
| ".so" `isSuffixOf` f = return False
|
||||||
|
@ -127,18 +101,3 @@ checkFileExe s = and
|
||||||
[ "ELF" `isInfixOf` s
|
[ "ELF" `isInfixOf` s
|
||||||
, "executable" `isInfixOf` s || "shared object" `isInfixOf` s
|
, "executable" `isInfixOf` s || "shared object" `isInfixOf` s
|
||||||
]
|
]
|
||||||
|
|
||||||
{- 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 = catMaybes . map (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'"]
|
|
||||||
|
|
61
Utility/LinuxMkLibs.hs
Normal file
61
Utility/LinuxMkLibs.hs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
{- Linux library copier and binary shimmer
|
||||||
|
-
|
||||||
|
- Copyright 2013 Joey Hess <joey@kitenet.net>
|
||||||
|
-
|
||||||
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
|
-}
|
||||||
|
|
||||||
|
module Utility.LinuxMkLibs where
|
||||||
|
|
||||||
|
import Control.Applicative
|
||||||
|
import Data.Maybe
|
||||||
|
import System.Directory
|
||||||
|
import Data.List.Utils
|
||||||
|
import System.Posix.Files
|
||||||
|
import Data.Char
|
||||||
|
import Control.Monad.IfElse
|
||||||
|
|
||||||
|
import Utility.PartialPrelude
|
||||||
|
import Utility.Directory
|
||||||
|
import Utility.Process
|
||||||
|
import Utility.Monad
|
||||||
|
import Utility.Path
|
||||||
|
|
||||||
|
{- 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
|
||||||
|
let target = relPathDirToFile (parentDir 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 = catMaybes . map (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'"]
|
Loading…
Add table
Reference in a new issue