cabal-macosx (empty) → 0.1.0
raw patch · 7 files changed
+684/−0 lines, 7 filesdep +Cabaldep +MissingHdep +basesetup-changed
Dependencies added: Cabal, MissingH, base, directory, fgl, filepath, parsec, process
Files
- Distribution/MacOSX.hs +190/−0
- Distribution/MacOSX/Common.hs +120/−0
- Distribution/MacOSX/DG.hs +75/−0
- Distribution/MacOSX/Dependencies.hs +221/−0
- LICENSE +36/−0
- Setup.hs +2/−0
- cabal-macosx.cabal +40/−0
+ Distribution/MacOSX.hs view
@@ -0,0 +1,190 @@+{- | Cabal support for creating Mac OSX application bundles.++GUI applications on Mac OSX should be run as application /bundles/;+these wrap an executable in a particular directory structure which can+also carry resources such as icons, program metadata, images, other+binaries, and copies of shared libraries.++This module provides a Cabal post-build hook for creating such+application bundles, and controlling their contents.++For more information about OSX application bundles, look for the+/Bundle Programming Guide/ on the /Apple Developer Connection/+website, <http://developer.apple.com/>.++-}++module Distribution.MacOSX (+ appBundleBuildHook,+ MacApp(..),+ ChaseDeps(..),+ Exclusions,+ defaultExclusions+) where++import Control.Monad (forM_)+import Data.String.Utils (replace)+import Distribution.PackageDescription (PackageDescription(..),+ Executable(..))+import Distribution.Simple+import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))+import Distribution.Simple.Setup (BuildFlags)+import System.Cmd (system)+import System.FilePath+import System.Info (os)+import System.Directory (copyFile, createDirectoryIfMissing)++import Distribution.MacOSX.Common+import Distribution.MacOSX.Dependencies++-- | Post-build hook for OS X application bundles. Does nothing if+-- called on another O/S.+appBundleBuildHook ::+ [MacApp] -- ^ List of applications to build; if empty, an+ -- application is built for each executable in the package,+ -- with no icon or plist, and no dependency-chasing.+ -> Args -- ^ All other parameters as per+ -- 'Distribution.Simple.postBuild'.+ -> BuildFlags -> PackageDescription -> LocalBuildInfo -> IO ()+appBundleBuildHook apps _ _ pkg localb =+ case os of+ "darwin" -> forM_ apps' $ makeAppBundle localb+ where apps' = case apps of+ [] -> map mkDefault $ executables pkg+ xs -> xs+ mkDefault x = MacApp (exeName x) Nothing Nothing [] [] DoNotChase+ _ -> putStrLn "Not OS X, so not building an application bundle."++-- | Given a 'MacApp' in context, make an application bundle in the+-- build area.+makeAppBundle ::+ LocalBuildInfo -> MacApp -> IO ()+makeAppBundle localb app =+ do appPath <- createAppDir localb app+ maybeCopyPlist appPath app+ maybeCopyIcon appPath app+ `catch` \err -> putStrLn ("Warning: could not set up icon for " +++ appName app ++ ": " ++ show err)+ includeResources appPath app+ includeDependencies appPath app+ osxIncantations appPath app++-- | Create application bundle directory structure in build directory+-- and copy executable into it. Returns path to newly created+-- directory.+createAppDir :: LocalBuildInfo -> MacApp -> IO FilePath+createAppDir localb app =+ do putStrLn $ "Creating application bundle directory " ++ appPath+ createDirectoryIfMissing False appPath+ createDirectoryIfMissing True $ takeDirectory exeDest+ createDirectoryIfMissing True $ appPath </> "Contents/Resources"+ putStrLn $ "Copying executable " ++ appName app ++ " into place"+ copyFile exeSrc exeDest+ return appPath+ where appPath = buildDir localb </> appName app <.> "app"+ exeDest = appPath </> pathInApp app (appName app)+ exeSrc = buildDir localb </> appName app </> appName app++-- | Include any external resources specified.+includeResources ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp -> IO ()+includeResources appPath app = mapM_ includeResource $ resources app+ where includeResource :: FilePath -> IO ()+ includeResource p =+ do let pDest = appPath </> pathInApp app p+ putStrLn $ "Copying resource " ++ p ++ " to " ++ pDest+ createDirectoryIfMissing True $ takeDirectory pDest+ copyFile p $ pDest+ return ()++-- | If a plist has been specified, copy it into place. If not, but+-- an icon has been specified, construct a default shell plist so the+-- icon is honoured.+maybeCopyPlist ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp -> IO ()+maybeCopyPlist appPath app =+ case appPlist app of+ Just plPath -> do -- Explicit plist path, so copy it in and assume OK.+ putStrLn $ "Copying " ++ plPath ++ " to " ++ plDest+ copyFile plPath plDest+ Nothing -> case appIcon app of+ Just icPath ->+ do -- Need a plist to support icon; use default.+ let pl = replace "$program" (appName app) plistTemplate+ pl' = replace "$iconPath" (takeFileName icPath) pl+ writeFile plDest pl'+ return ()+ Nothing -> return () -- No icon, no plist, nothing to do.+ where plDest = appPath </> "Contents/Info.plist"++-- | If an icon file has been specified, copy it into place.+maybeCopyIcon ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp -> IO ()+maybeCopyIcon appPath app =+ case appIcon app of+ Just icPath ->+ do putStrLn $ "Copying " ++ icPath ++ " to app's icon"+ copyFile icPath $+ appPath </> "Contents/Resources" </> takeFileName icPath+ Nothing -> return ()++-- | Perform various magical OS X incantations for turning the app+-- directory into a bundle proper.+osxIncantations ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp -> IO ()+osxIncantations appPath app =+ do putStrLn "Running Rez, etc."+ system $ rez ++ " Carbon.r -o " ++ appPath </> pathInApp app (appName app)+ writeFile (appPath </> "PkgInfo") "APPL????"+ -- Tell Finder about the icon.+ system $ setFile ++ " -a C " ++ appPath </> "Contents"+ return ()++-- | Path to @Rez@ tool.+rez :: FilePath+rez = "/Developer/Tools/Rez"++-- | Path to @SetFile@ tool.+setFile :: FilePath+setFile = "/Developer/Tools/SetFile"++-- | Default plist template, based on that in macosx-app from wx (but+-- with version stuff removed).+plistTemplate :: String+plistTemplate = "\+ \<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\+ \<!DOCTYPE plist SYSTEM \"file://localhost/System/Library/DTDs/PropertyList.dtd\">\n\+ \<plist version=\"0.9\">\n\+ \<dict>\n\+ \<key>CFBundleInfoDictionaryVersion</key>\n\+ \<string>6.0</string>\n\+ \<key>CFBundleIdentifier</key>\n\+ \<string>org.haskell.$program</string>\n\+ \<key>CFBundleDevelopmentRegion</key>\n\+ \<string>English</string>\n\+ \<key>CFBundleExecutable</key>\n\+ \<string>$program</string>\n\+ \<key>CFBundleIconFile</key>\n\+ \<string>$iconPath</string>\n\+ \<key>CFBundleName</key>\n\+ \<string>$program</string>\n\+ \<key>CFBundlePackageType</key>\n\+ \<string>APPL</string>\n\+ \<key>CFBundleSignature</key>\n\+ \<string>????</string>\n\+ \<key>CFBundleVersion</key>\n\+ \<string>1.0</string>\n\+ \<key>CFBundleShortVersionString</key>\n\+ \<string>1.0</string>\n\+ \<key>CFBundleGetInfoString</key>\n\+ \<string>$program, bundled by cabal-macosx</string>\n\+ \<key>LSRequiresCarbon</key>\n\+ \<true/>\n\+ \<key>CSResourcesFileMapped</key>\n\+ \<true/>\n\+ \</dict>\n\+ \</plist>"
+ Distribution/MacOSX/Common.hs view
@@ -0,0 +1,120 @@+module Distribution.MacOSX.Common where++import Data.List+import System.FilePath++-- | Mac OSX application information.+data MacApp = MacApp {+ -- | Application name. This should be the name of the executable+ -- produced by Cabal's build stage. The app bundle produced will be+ -- @dist\/build\//appName/.app@, and the executable /appName/ will+ -- be copied to @Contents\/MacOSX\/@ in the bundle.+ appName :: String,+ -- | Path to icon file, to be copied to @Contents\/Resources\/@ in+ -- the app bundle. If omitted, no icon will be used.+ appIcon :: Maybe FilePath,+ -- | Path to /plist/ file ('property-list' of application metadata),+ -- to be copied to @Contents\/Info.plist@ in the app bundle. If+ -- omitted, and if 'appIcon' is specified, a basic default plist+ -- will be used.+ appPlist :: Maybe FilePath,+ -- | Other resources to bundle in the application, e.g. image files,+ -- etc. Each will be copied to @Contents\/Resources\/@, with the+ -- proviso that if the resource path begins with @resources\/@, it+ -- will go to a /relative/ subdirectory of @Contents\/Resources\/@.+ -- For example, @images/splash.png@ will be copied to+ -- @Contents\/Resources\/splash.png@, whereas+ -- @resources\/images\/splash.png@ will be copied to+ -- @Contents\/Resources\/resources\/images\/splash.png@.+ --+ -- Bundled resources may be referred to from your program relative+ -- to your executable's path (which may be computed, e.g., using+ -- Audrey Tang's FindBin package).+ resources :: [FilePath],+ -- | Other binaries to bundle in the application, e.g. other+ -- executables from your project, or third-party programs. Each+ -- will be copied to a relative sub-directory of+ -- @Contents\/Resources\/@ in the bundle. For example,+ -- @\/usr\/bin\/ftp@ would be copied to+ -- @Contents\/Resources\/usr\/bin\/ftp@ in the app.+ --+ -- Like 'resources', bundled binaries may be referred to from your+ -- program relative to your executable's path (which may be+ -- computed, e.g., using Audrey Tang's FindBin package).+ otherBins :: [FilePath],+ -- | Controls inclusion of library dependencies for executable and+ -- 'otherBins'; see below.+ appDeps :: ChaseDeps+ } deriving (Eq, Show)++-- | Application bundles may carry their own copies of shared+-- libraries, which enables distribution of applications which 'just+-- work, out of the box' in the absence of static linking. For+-- example, a wxHaskell app can include the wx library (and /its/+-- dependencies, recursively), meaning end users do not need to+-- install wxWidgets in order to use the app.+--+-- This data type controls this process: if dependency chasing is+-- activated, then the app's executable and any 'otherBins' are+-- examined for their dependencies, recursively (usually with some+-- exceptions - see below), the dependencies are copied into the app+-- bundle, and any references to each library are updated to point to+-- the copy.+--+-- (The process is transparent to the programmer, i.e. requires no+-- modification to code. In case anyone is interested: @otool@ is+-- used to discover a binary's library dependencies; each library is+-- copied to a relative sub-directory of @Contents\/Frameworks\/@ in+-- the app bundle (e.g. @\/usr\/lib\/libFoo.a@ becomes+-- @Contents\/Frameworks\/usr\/lib\/libFoo.a@); finally,+-- @install_name_tool@ is used to update dependency references to+-- point to the new version.)+data ChaseDeps+ = -- | Do not include any dependencies - a sensible default if not+ -- distributing your app.+ DoNotChase+ -- | Include any libraries which the executable and 'otherBins'+ -- depend on, excluding a default set which we would expect to be+ -- present on any machine running the same version of OSX on which+ -- the executable was built. (n.b.: Creation of application+ -- bundles which work transparently across different versions of+ -- OSX is currently beyond the scope of this package.)+ | ChaseWithDefaults+ -- | Include any libraries which the executable and 'otherBins'+ -- depend on, excluding a user-defined set. If you specify an+ -- empty exclusion list, then /all/ dependencies will be included,+ -- recursively, including various OSX Frameworks; /this/+ -- /probably/ /isn't/ /ever/ /sensible/. The intended use,+ -- rather, is to allow extension of the default list, which can be+ -- accessed via 'defaultExclusions'.+ | ChaseWith Exclusions+ deriving (Eq, Show)++-- | A list of exclusions to dependency chasing. Any library whose+-- path contains any exclusion string /as a substring/ will be+-- excluded when chasing dependencies.+type Exclusions = [String]++-- | Default list of exclusions; excludes OSX standard frameworks,+-- libgcc, etc. - basically things which we would expect to be present+-- on any functioning OSX installation.+defaultExclusions :: Exclusions+defaultExclusions = + ["/System/Library/Frameworks/",+ "/libSystem.",+ "/libgcc_s.",+ "/libobjc."+ ]++-- | Compute item's path relative to app bundle root.+pathInApp :: MacApp -> FilePath -> FilePath+pathInApp app p+ | p == appName app = "Contents/MacOS" </> p+ | p `elem` otherBins app = "Contents/Resources" </> relP+ | p `elem` resources app = + let p' = if "resources/" `isPrefixOf` p then+ makeRelative "resources/" p+ else takeFileName p+ in "Contents/Resources" </> p'+ | otherwise = "Contents/Frameworks" </> relP+ where relP = makeRelative "/" p
+ Distribution/MacOSX/DG.hs view
@@ -0,0 +1,75 @@+-- | Dependency graph handling.++module Distribution.MacOSX.DG (+ DG(..),+ FDeps(..),+ dgEmpty,+ dgFDeps,+ dgAddPaths,+ dgAddFDeps+) where++import Data.Graph.Inductive.Graph as G+import Data.Graph.Inductive.Tree (Gr)+import Data.List+import Data.Maybe++-- | A dependency graph is an ordinary fgl graph with 'FilePath's on+-- its nodes, and directed edges. An edge from A to B indicates that+-- A depends on B.+data DG = DG (Gr FilePath ())+ deriving Show++-- | An FDeps represents some file and its list of library+-- dependencies.+data FDeps = FDeps FilePath [FilePath]+ deriving (Eq, Ord, Show)++-- | Add a file dependency to a dependency graph.+dgAddFDeps :: DG -> FDeps -> DG+dgAddFDeps dg (FDeps src tgts) = dgAddDeps src tgts $ dg `dgAddPaths` (src:tgts)++-- | Turn a dependency graph back into a list of FDeps.+dgFDeps :: DG -> [FDeps]+dgFDeps (DG g) = map mkFDep (G.labNodes g)+ where mkFDep :: G.LNode FilePath -> FDeps+ mkFDep (i, src) = FDeps src $ mapMaybe (G.lab g) (G.suc g i)++-- | Create an empty dependency graph.+dgEmpty :: DG+dgEmpty = DG G.empty++-- | Get the node number of a dependency graph node with a specified label.+dgPathIdx :: DG -> FilePath -> Maybe Int+dgPathIdx (DG g) p = case find (\x -> p == snd x) (G.labNodes g) of+ Just (i, _) -> Just i+ Nothing -> Nothing++-- | Check if a certain path is already in a dependency graph.+dgHasPath :: DG -> FilePath -> Bool+dgHasPath dg p = case dgPathIdx dg p of+ Just _ -> True+ Nothing -> False++-- | Add a list of paths as nodes to a dependency graph, dropping+-- duplicates.+dgAddPaths :: DG -> [FilePath] -> DG+dgAddPaths = foldl dgAddPath++-- | Add a single path as a node to a dependency graph, unless already+-- present.+dgAddPath :: DG -> FilePath -> DG+dgAddPath dg@(DG g) p = if dg `dgHasPath` p then dg+ else DG $ G.insNode (head $ G.newNodes 1 g, p) g++-- | Given a source path and a list of target paths, add a list of+-- dependencies (ie edges) to a dependency graph.+dgAddDeps :: FilePath -> [FilePath] -> DG -> DG+dgAddDeps src tgts dg = foldl dgAddDep dg $ zip (repeat src) tgts++-- | Add a (src, tgt) dependency (ie edge) to a dependency graph.+dgAddDep :: DG -> (FilePath, FilePath) -> DG+dgAddDep dg@(DG g) (src, tgt) = DG $ G.insEdge (getI src, getI tgt, ()) g+ where getI x = case dgPathIdx dg x of+ Just x' -> x'+ Nothing -> error "Can't happen" -- if called in context.
+ Distribution/MacOSX/Dependencies.hs view
@@ -0,0 +1,221 @@+{- | Inclusion of bundle-local copies of libraries in application bundles.++OS X application bundles can include local copies of libraries and+frameworks (ie dependencies of the executable) which aids distribution+and eases installation. Xcode and the traditional OS X development+toolchain support this fairly transparently; this module is an attempt+to provide similar functionality in the cabal-macosx package.++The basic approach is as follows:++ 1. Discover the libraries an object file (executable, other binary, or+ library) references using @otool -L /path/@++ 2. Copy those libraries into the application bundle, at the right+ place, ie @\@executable_path\/..\/Frameworks\/@ where+ @\@executable_path@ represents the path to the exeutable in the+ bundle.++ 3. Modify the object file so it refers to the local copy, using+ @install_name_tool -change /oldLibPath/ /newLibPath/ /path/@ where+ @/newlibPath/@ points to @\@executable_path\/..\/Frameworks@ as+ described above (@\@executable_path@ is a special symbol recognised+ by the loader).++Complications:++ * There's some stuff we don't want to include because we can+ expect it to be present everywhere, eg the Cocoa framework; see+ /Exclusions/, below.++ * Libraries can themselves depend on other libraries; thus, we+ need to copy them in recursively.++ * Because of these transitive dependencies, dependencies can+ arise on multiple copies of the same library, in different+ locations (eg @\/usr\/lib\/libfoo@ and @\/opt\/local\/lib\/libfoo@).+ Thus, we preserve that path info, and (for example) copy+ @\/usr\/lib\/libFoo@ to+ @\@executable_path\/..\/Frameworks\/usr\/lib\/@.++The approach followed is to build a dependency graph, seeded with the+executable and any other binaries being included in the bundle, using+@otool@; then to walk that graph, copying in the libraries, and+calling @install_name_tool@ to update the dependencies of entities in+the bundle. Going via a dependency graph is a bit unnecessary - we+could just recursively @otool@/@install_name_tool@, but its helpful if+we need to debug, etc., and a nice clear abstraction.++/Exclusions/: as described above, a lot of truly common stuff would+get copied in, so we provide a mechanism to exclude libraries from+this process: 'buildDependencyGraph' can be passed a list of strings,+and a library whose path includes any of those strings is excluded.+If an empty list is passed, then nothing is excluded (which is almost+certainly not what you want).++-}++module Distribution.MacOSX.Dependencies (+ includeDependencies,+ appDependencyGraph+) where++import Control.Monad+import Data.List+import System.Directory+import System.FilePath+import System.IO+import System.Process+import Text.ParserCombinators.Parsec++import Distribution.MacOSX.Common+import Distribution.MacOSX.DG++-- | Include any library dependencies required in the app.+includeDependencies ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp -> IO ()+includeDependencies appPath app =+ do dg <- appDependencyGraph appPath app+ let fDeps = dgFDeps dg+ mapM_ (copyInDependency appPath app) fDeps+ mapM_ (updateDependencies appPath app) fDeps++-- | Compute application's library dependency graph.+appDependencyGraph ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp -> IO DG+appDependencyGraph appPath app =+ case (appDeps app) of+ ChaseWithDefaults -> appDependencyGraph appPath app {+ appDeps = ChaseWith defaultExclusions+ }+ ChaseWith xs -> do putStrLn "Building dependency graph"+ buildDependencyGraph appPath app dgInitial roots [] xs+ DoNotChase -> return dgInitial+ where roots = appName app : otherBins app+ dgInitial = dgEmpty `dgAddPaths` roots++-- | Recursive dependency-graph builder.+buildDependencyGraph ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp+ -> DG -- ^ Dependency graph to be extended.+ -> [FilePath] -- ^ Queue of paths to object files to be examined for+ -- dependencies.+ -> [FilePath] -- ^ List of paths of object files which have already+ -- been dealt with.+ -> Exclusions -- ^ List of exclusions for dependency-chasing.+ -> IO DG+buildDependencyGraph _ _ dg [] _ _ = return dg+buildDependencyGraph appPath app dg (x:xs) done excls =+ do (dg', tgts) <- addFilesDependencies appPath app dg x excls+ let done' = (x:done)+ xs' = addToQueue xs done' tgts+ buildDependencyGraph appPath app dg' xs' done' excls+ where addToQueue :: [FilePath] -> [FilePath] -> [FilePath] -> [FilePath]+ addToQueue q done' = foldl (addOneToQueue (q ++ done')) q+ addOneToQueue :: [FilePath] -> [FilePath] -> FilePath -> [FilePath]+ addOneToQueue done' q n = if n `elem` done' then q else q ++ [n]++-- | Add an object file's dependencies to a dependency graph,+-- returning that new graph and a list of the discovered dependencies.+addFilesDependencies ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp+ -> DG -- ^ Dependency graph to be extended.+ -> FilePath -- ^ Path to object file to be examined for dependencies.+ -> Exclusions -- ^ List of exclusions for dependency chasing.+ -> IO (DG, [FilePath])+addFilesDependencies appPath app dg p excls =+ do (FDeps _ tgts) <- getFDeps appPath app p excls+ let dg' = dgAddFDeps dg (FDeps p tgts)+ return (dg', tgts)++-- | Compute the library dependencies for some file, removing any+-- exclusions.+getFDeps ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp+ -> FilePath -- ^ Path to object file to be examined for dependencies.+ -> Exclusions -- ^ List of exclusions for dependency chasing.+ -> IO FDeps+getFDeps appPath app path exclusions =+ do contents <- readProcess oTool ["-L", absPath] ""+ case parse parseFileDeps "" contents of+ Left err -> error $ show err+ Right fDeps -> return $ exclude exclusions fDeps+ where absPath = if path == appName app then+ appPath </> pathInApp app (appName app)+ else path+ parseFileDeps :: Parser FDeps+ parseFileDeps = do f <- manyTill (noneOf ":") (char ':')+ char '\n'+ deps <- parseDep `sepEndBy` char '\n'+ eof+ return $ FDeps f deps+ parseDep :: Parser FilePath+ parseDep = do char '\t'+ dep <- manyTill (noneOf " ") (char ' ')+ char '('+ manyTill (noneOf ")") (char ')')+ return dep++-- | Apply an exclusion list to an 'FDeps' value; any dependencies+-- which contain any of the exclusions as substrings are excluded.+exclude :: Exclusions -> FDeps -> FDeps+exclude excls (FDeps p ds) = FDeps p $ filter checkExclude ds+ where checkExclude :: FilePath -> Bool+ checkExclude f = not $ any (`isInfixOf` f) excls++-- | Copy some object file's library dependencies into the application+-- bundle.+copyInDependency ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp+ -> FDeps -- ^ Dependencies to copy in.+ -> IO ()+copyInDependency appPath app (FDeps src _) =+ Control.Monad.unless (src == appName app) $+ do putStrLn $ "Copying " ++ src ++ " to " ++ tgt+ createDirectoryIfMissing True $ takeDirectory tgt+ copyFile src tgt+ where tgt = appPath </> pathInApp app src++-- | Update some object file's library dependencies to point to+-- bundled copies of libraries.+updateDependencies ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp+ -> FDeps -- ^ Dependencies to update.+ -> IO ()+updateDependencies appPath app (FDeps src tgts) =+ mapM_ (updateDependency appPath app src) tgts++-- | Update some object file's dependency on some particular library,+-- to point to the bundled copy of that library.+updateDependency ::+ FilePath -- ^ Path to application bundle root.+ -> MacApp+ -> FilePath -- ^ Path to object file to update.+ -> FilePath -- ^ Path to library which was copied in (path before copy).+ -> IO ()+updateDependency appPath app src tgt =+ do putStrLn $ "Updating " ++ newLib ++ "'s dependency on " ++ tgt +++ " to " ++ tgt'+ let cmd = iTool ++ " -change " ++ show tgt ++ " " ++ show tgt' +++ " " ++ show newLib+ --putStrLn cmd+ runCommand cmd+ return ()+ where tgt' = "@executable_path/../Frameworks/" </> makeRelative "/" tgt+ newLib = if src == appName app then src+ else appPath </> pathInApp app src++-- | Path to @otool@ tool.+oTool :: FilePath+oTool = "/usr/bin/otool"++-- | Path to @install_name_tool@ tool.+iTool :: FilePath+iTool = "/usr/bin/install_name_tool"
+ LICENSE view
@@ -0,0 +1,36 @@+Copyright (c) 2009, Eric Kow, Andy Gimblett+All rights reserved.++Developed by:++ Eric Kow <eric.kow@gmail.com>+ Andy Gimblett <haskell@gimbo.org.uk>++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are+met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditi ons and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the names of Eric Kow, Andy Gimblett, nor the names of+ its contributors may be used to endorse or promote products+ derived from this software without specific prior written+ permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cabal-macosx.cabal view
@@ -0,0 +1,40 @@+Name: cabal-macosx+Version: 0.1.0+Stability: Alpha+Synopsis: Cabal support for creating Mac OSX application bundles.+Description:++ GUI applications on Mac OSX must be run as application /bundles/;+ these wrap an executable in a particular directory structure which+ can also carry resources such as icons, program metadata, other+ binaries, and copies of shared libraries.++ This package provides Cabal support for creating such application+ bundles.++ For more information about OSX application bundles, look for the+ /Bundle Programming Guide/ on the /Apple Developer Connection/+ website, <http://developer.apple.com/>.++Category: Distribution+License: BSD3+License-file: LICENSE+Copyright: Eric Kow & Andy Gimblett+Author: Eric Kow <eric.kow@gmail.com> & Andy Gimblett <haskell@gimbo.org.uk>+Maintainer: Andy Gimblett <haskell@gimbo.org.uk>+Homepage: http://github.com/gimbo/cabal-macosx+Build-Type: Simple+Cabal-Version: >=1.6++Source-Repository head+ Type: git+ Location: http://github.com/gimbo/cabal-macosx++Library+ Build-Depends: base >= 4 && < 5, Cabal >= 1.6, directory, fgl,+ filepath, MissingH, parsec, process+ Exposed-modules: Distribution.MacOSX+ Other-modules: Distribution.MacOSX.Common,+ Distribution.MacOSX.Dependencies,+ Distribution.MacOSX.DG+ ghc-options: -fwarn-tabs -Wall