summaryrefslogtreecommitdiff
path: root/Build/OSXMkLibs.hs
blob: cb8c017aedcb2c37303abcc239a1e89865eae484 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
{- OSX library copier
 -
 - Copyright 2012 Joey Hess <joey@kitenet.net>
 -
 - Licensed under the GNU GPL version 3 or higher.
 -}

module Build.OSXMkLibs where

import Control.Applicative
import System.Environment
import Data.Maybe
import System.FilePath
import System.Directory
import System.IO
import Control.Monad
import Data.List

import Utility.PartialPrelude
import Utility.Directory
import Utility.Process
import Utility.Monad
import Utility.SafeCommand
import Utility.Path

{- Recursively find and install libs, until nothing new to install is found. -}
mklibs :: FilePath -> [FilePath] -> IO [FilePath]
mklibs appbase libdirs = do
	new <- catMaybes <$> installLibs appbase
	if null new
		then return (libdirs++new)
		else mklibs appbase (libdirs++new)

{- Returns directories into which new libs were installed. -}
installLibs :: FilePath -> IO [Maybe FilePath]
installLibs appbase = do
	needlibs <- otool appbase
	forM needlibs $ \lib -> do
		let libdir = parentDir lib
		let dest = appbase ++ lib
		ifM (doesFileExist dest)
			( return Nothing
			, do
				createDirectoryIfMissing True (appbase ++ libdir)
				_ <- boolSystem "cp" [File lib, File dest]
				putStrLn $ "installing " ++ lib
				return $ Just libdir
			)

otool :: FilePath -> IO [FilePath]
otool appbase = do
	files <- filterM doesFileExist =<< dirContentsRecursive appbase
	s <- readProcess "otool" ("-L" : files)
	return $ nub $ parseOtool s

parseOtool :: String -> [FilePath]
parseOtool = catMaybes . map parse . lines
  where
	parse l
		| "\t" `isPrefixOf` l = headMaybe $ words l
		| otherwise = Nothing

main :: IO ()
main = getArgs >>= go
  where
	go [] = error "specify OSXAPP_BASE"
	go (appbase:_) = do
		libdirs <- mklibs appbase []
		writeFile (appbase </> "libdirs") $
			unlines $ nub libdirs