Mac OS X Common Installation Paths

From HaskellWiki
Revision as of 12:07, 6 September 2010 by ChrisKuklewicz (talk | contribs)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

There is also now the Mac OS X Strike Force that aims to improve using Haskell on OS X.

The following is a proposal for common default locations of various Haskell system components on Mac OS X. The aim is to ensure that Haskell on Mac OS X experience:

  • Follows Apple's Guidelines for file system layout
  • Makes it easy for a user to locate all the Haskell components, especially user installed packages
  • Enables easy removal of a user installed package, whether they have installed it --user or --global.
  • Facilitate creation of unified, hyper-linked Haddock documentation, optionally with source

Context

Users will want to installed packages, generally using cabal, on their local machine for development work. They may choose to installed packages --user or --global, depending on any number of factors: experimentation, need to access from multiple accounts, personal preference.

It is assumed that most developers will have one Haskell implementation installed. However, this layout should not preclude there being multiple implementations installed on a given machine.

End users of software written in Haskell generally don't have to deal with Haskell components since at present executables are statically linked against the packages. However, some packages may require access to data files or other package supplied executables. These are special situations, discussed below.

Implementations

Haskell implementations are generally installed for use by all accounts on the system. They consist of large collections of executables, libraries, and other files. These should packaged using Apple's framework, versioning, and bundling techniques and installed in:

 /Library/Frameworks

Executables intended for use from the command line, should be symlink'd from:

 /usr/bin

back into the framework bundle. [Q: Would /usr/local/bin be more appropriate? ]

Packages that come with the implementation, should be located within the Framework bundle.

If the implementation has any GUI applications, these should be installed in:

 /Applications

NB: Haskell Platform already installs GHC and included packages in precisely this way. Woot!

NB: These guidelines allow for multiple implementations and multiple versions to co-exist. (With the exception of multiple versions of GUI applications which can only be done by distinct naming, and the symlinks in /usr/bin which can achieved in the normal way: Append the version number to the executable and then symlink the 'bare' name to the most recent.

If implementations want to be able to be installed "per user", then the above paths should be:

 ~/Library/Frameworks
 ~/bin
 ~/Applications

Not all software for Mac OS X offers such an option on installation, and while nice, it is by no means universal.


User Installed Packages

User installed packages are placed under a "prefix" that depends on if the user choose to install for all users (--global) for just their own use (--user):

 /Library/Haskell  --global
 ~/Library/Haskell --user

Package Component Layout

Cabal offers a large amount of flexibility in where the various pieces of a package are installed. The GHC package system is rather agnostic about where these pieces are, and insulates the implementation from such differences. These combine to enable the choice of package layout to be largely to serve the user.

For both --global and --user installs, the package layout should be:

 executables: --prefix--/packages/--pkgid--/bin
 libraries:   --prefix--/packages/--pkgid--/lib/--compiler--
 lib-exec:    --prefix--/packages/--pkgid--/libexec/--compiler--
 data:        --prefix--/packages/--pkgid--/share
 doc:         --prefix--/packages/--pkgid--/doc
 html:        --prefix--/packages/--pkgid--/doc

This can be achieved with the following cabal configuration defaults:

 install-dirs user
   prefix:     ~/Library/Haskell/packages
   bindir:     $prefix/$pkgid/bin
   libdir:     $prefix/$pkgid/lib
   libsubdir:     $compiler
   libexecdir: $prefix/$pkgid/libexec
   datadir:    $prefix/$pkgid/share
   datasubdir:    .
   docdir:     $datadir/doc
   htmldir:    $docdir
   haddockdir: $htmldir
 
 install-dirs global
   prefix:     /Library/Haskell/packages
   bindir:     $prefix/$pkgid/bin
   libdir:     $prefix/$pkgid/lib
   libsubdir:     $compiler
   libexecdir: $prefix/$pkgid/libexec
   datadir:    $prefix/$pkgid/share
   datasubdir:    .
   docdir:     $datadir/doc
   htmldir:    $docdir
   haddockdir: $htmldir
 

N.B.:

  • All components for a package are under a single directory. This facilitates easy location and removal of a package.
  • When installed via Haskell Platform, the packages bundled with GHC do not use either this layout, or the layout that cabal defaults to. It would nice, though by no means essential, if the packages there (within the GHC.framework bundle) had the same layout. (It might be needed to support integrated Haddock documentation.)
  • While this might look like one could move packages about by simply dragging their directories, you can't in general because libraries, if they reference data files or package executables, have their installed locations compiled in.

Executables

Packages that build executables to be run from the command line present a difficultly. The should be installed in a place that is only on the user's PATH. In general, on a stock Mac OS X install, this means one of:

/usr/bin
/usr/local/bin
~/bin

Cabal already supports this issue somewhat with the symlink-bindir option. This feature, if extended so it can support separate options for --global and --user would enable the following scheme:

All binaries should have symlinks in $prefix/../bin, linking back to $prefix/$pkgid/bin. This puts all package build executables as commands available in these two directories:

/Library/Haskell/bin
~/Library/Haskell/bin

The user can then choose to put these on their PATH if they wish. Alternatively, users could choose to alter the smlink-bindir directives to point at

/usr/local/bin
~/bin


Framework Quick Link

It is often convienent to have quick access to the installed implementation's packages. For GHC, this is accomplished by adding a symlink at:

 /Library/Haskell/GHC

to:

 /Library/Frameworks/GHC.framework/Versions/Current/usr/

Other implementations should use the same idea.


References

  1. Apple guidelines for the /Library and ~/Library files
  2. MtnViewMark's original e-mail on this topic.