Personal tools

Mac OS X Common Installation Paths

From HaskellWiki

(Difference between revisions)
Jump to: navigation, search
(re-written as a proposal)
(Implementations)
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
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:
+
The default layout for installed Haskell components follows the conventions of most unix-like systems. On Mac OS X, this layout isn't optimal, and a different layout is used. The layout presented here has several advantages:
  +
 
* Follows Apple's Guidelines for file system layout
 
* Follows Apple's Guidelines for file system layout
 
* Makes it easy for a user to locate all the Haskell components, especially user installed packages
 
* 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.
+
* Enables easy removal of a user installed package, whether they have installed it <tt>--user</tt> or <tt>--global</tt>.
 
* Facilitate creation of unified, hyper-linked Haddock documentation, optionally with source
 
* Facilitate creation of unified, hyper-linked Haddock documentation, optionally with source
   
== Context ==
+
Haskell Platform 2011.2.0.0 (March 2011) and later uses this layout and sets up cabal to use it for built packages. On new installs, if you didn't already have a <tt>~/.cabal/config</tt> file, then it is set up by default. Otherwise, the config file for this layout is placed in <tt>~/.cabal/config.platform</tt> and you can manually move it over, or incorporate it into your existing <tt>config</tt> file.
 
Users will want to installed packages, generally using cabal, on their local machine for development work. They may choose to installed packages <tt>--user</tt> or <tt>--global</tt>, 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 ==
 
== Implementations ==
Line 13: Line 12:
 
Haskell implementations are generally installed for use by all accounts on the
 
Haskell implementations are generally installed for use by all accounts on the
 
system. They consist of large collections of executables, libraries, and other
 
system. They consist of large collections of executables, libraries, and other
files. These should packaged using Apple's framework, versioning, and bundling
+
files. These are packaged using Apple's framework, versioning, and bundling
 
techniques and installed in:
 
techniques and installed in:
 
/Library/Frameworks
 
/Library/Frameworks
   
Executables intended for use from the command line, should be symlink'd from:
+
For example, GHC 7.0.2 is installed in:
  +
/Library/Frameworks/GHC.framework/Versions/7.0.2-i386
  +
  +
Executables intended for use from the command line, are be symlink'd into:
 
/usr/bin
 
/usr/bin
back into the framework bundle. ''[Q: Would <tt>/usr/local/bin</tt> be more appropriate? ]''
+
''[Q: Would <tt>/usr/local/bin</tt> be more appropriate? ]''
   
Packages that come with the implementation, should be located within the Framework
+
Packages that come with the implementation, are be located within the Framework
 
bundle.
 
bundle.
   
If the implementation has any GUI applications, these should be installed in:
+
If the implementation has any GUI applications, these are installed in:
 
/Applications
 
/Applications
 
'''NB:''' Haskell Platform already installs GHC and included packages in
 
precisely this way. Woot!
 
   
 
'''NB:''' These guidelines allow for multiple implementations and multiple
 
'''NB:''' These guidelines allow for multiple implementations and multiple
Line 42: Line 38:
 
~/Applications
 
~/Applications
   
Not all software for Mac OS X offers such an option on installation, and while
+
Not all software for Mac OS X offers a "per user" option on installation, and while
 
nice, it is by no means universal.
 
nice, it is by no means universal.
 
   
 
== User Installed Packages ==
 
== User Installed Packages ==
Line 60: Line 55:
 
choice of package layout to be largely to serve the user.
 
choice of package layout to be largely to serve the user.
   
For both <tt>--global</tt> and <tt>--user</tt> installs, the package layout should
+
For both <tt>--global</tt> and <tt>--user</tt> installs, this is the recommended package layout on Mac OS X:
be:
+
executables: --prefix--/packages/--pkgid--/bin
+
{prefix}
libraries: --prefix--/packages/--pkgid--/lib/--compiler--
+
{compiler}
lib-exec: --prefix--/packages/--pkgid--/libexec/--compiler--
+
lib
data: --prefix--/packages/--pkgid--/share
+
{pkgid}
doc: --prefix--/packages/--pkgid--/doc
+
bin -- binaries ($bindir)
html: --prefix--/packages/--pkgid--/doc
+
lib -- libraries & .hi files ($libdir, $libdir/$libsubdir, $dynlibdir)
  +
include -- include files ($includedir)
  +
libexec -- private binaries ($libexecdir)
  +
share -- data files ($datadir, $datadir/$datasubdir)
  +
doc -- documentation ($docdir)
  +
html -- html doc ($htmldir, $haddockdir)
  +
man -- man pages ($mandir)
   
 
This can be achieved with the following cabal configuration defaults:
 
This can be achieved with the following cabal configuration defaults:
 
install-dirs user
 
install-dirs user
prefix: ~/Library/Haskell/packages
+
prefix: ~/Library/Haskell/$compiler/lib/$pkgid
bindir: $prefix/$pkgid/bin
+
bindir: $prefix/bin
libdir: $prefix/$pkgid/lib
+
libdir: $prefix/lib
libsubdir: $compiler
+
libsubdir:
libexecdir: $prefix/$pkgid/libexec
+
libexecdir: $prefix/libexec
datadir: $prefix/$pkgid/share
+
datadir: $prefix/share
datasubdir: .
+
datasubdir:
 
docdir: $datadir/doc
 
docdir: $datadir/doc
htmldir: $docdir
+
htmldir: $docdir/html
 
haddockdir: $htmldir
 
haddockdir: $htmldir
 
 
 
install-dirs global
 
install-dirs global
prefix: /Library/Haskell/packages
+
prefix: /Library/Haskell/$compiler/lib/$pkgid
bindir: $prefix/$pkgid/bin
+
bindir: $prefix/bin
libdir: $prefix/$pkgid/lib
+
libdir: $prefix/lib
libsubdir: $compiler
+
libsubdir:
libexecdir: $prefix/$pkgid/libexec
+
libexecdir: $prefix/libexec
datadir: $prefix/$pkgid/share
+
datadir: $prefix/share
datasubdir: .
+
datasubdir:
 
docdir: $datadir/doc
 
docdir: $datadir/doc
htmldir: $docdir
+
htmldir: $docdir/html
 
haddockdir: $htmldir
 
haddockdir: $htmldir
 
 
 
'''N.B.:'''
 
'''N.B.:'''
* All components for a package are under a single directory. This facilitates easy location and removal of a package.
+
* Cabal configuration files don't actually support <tt>~</tt>. You must replace that with <tt>/Users/xxx</tt> where <tt>xxx</tt> is your account name.
* 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.)
+
* All packages for a given compiler are under a single directory. When an old compiler is removed, all the packages compiled for it can be easily removed too.
* 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.
+
* All components for a package are under a single directory. This facilitates easy location and removal of a single package, for either a single compiler, or all installed versions.
  +
* If a package generates different doc for different compilers (it may have different APIs available), then this structure preserves each.
  +
* Executables are also per compilation, which is sometimes important (for Haddock, for example).
   
 
== Executables ==
 
== Executables ==
   
 
Packages that build executables to be run from the command line present a
 
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
+
difficultly. They are built into a per-package <tt>bin</tt> directory, and then should be symlink'd somewhere on the user's PATH. For global installs, the logical place is one of:
PATH. In general, on a stock Mac OS X install, this means one of:
 
 
/usr/bin
 
/usr/bin
 
/usr/local/bin
 
/usr/local/bin
~/bin
 
   
Cabal already supports this issue somewhat with the <tt>symlink-bindir</tt> option.
+
For user installs, since <tt>~/bin</tt> is not on the <tt>PATH</tt> by default on Mac OS X and may not exist, binaries are symlink'd into:
This feature, if extended so it can support separate options for <tt>--global</tt> and <tt>--user</tt> would enable the following scheme:
 
 
All binaries should have symlinks in <tt>$prefix/../bin</tt>, linking back to
 
<tt>$prefix/$pkgid/bin</tt>. This puts all package build executables as commands
 
available in these two directories:
 
/Library/Haskell/bin
 
 
~/Library/Haskell/bin
 
~/Library/Haskell/bin
   
The user can then choose to put these on their PATH if they wish. Alternatively,
+
Alas, cabal only supports one location for both kinds of build, and so it is set to tbe the later.
users could choose to alter the <tt>smlink-bindir</tt> 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.
 
   
 
----
 
----

Revision as of 11:20, 25 April 2012

The default layout for installed Haskell components follows the conventions of most unix-like systems. On Mac OS X, this layout isn't optimal, and a different layout is used. The layout presented here has several advantages:

  • 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

Haskell Platform 2011.2.0.0 (March 2011) and later uses this layout and sets up cabal to use it for built packages. On new installs, if you didn't already have a ~/.cabal/config file, then it is set up by default. Otherwise, the config file for this layout is placed in ~/.cabal/config.platform and you can manually move it over, or incorporate it into your existing config file.


Contents

1 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 are packaged using Apple's framework, versioning, and bundling techniques and installed in:

 /Library/Frameworks

For example, GHC 7.0.2 is installed in:

 /Library/Frameworks/GHC.framework/Versions/7.0.2-i386

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

 /usr/bin

[Q: Would /usr/local/bin be more appropriate? ]

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

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

 /Applications

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 a "per user" option on installation, and while nice, it is by no means universal.

2 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

3 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, this is the recommended package layout on Mac OS X:

{prefix}
  {compiler}
    lib
      {pkgid}
        bin         -- binaries ($bindir)
        lib         -- libraries & .hi files ($libdir, $libdir/$libsubdir, $dynlibdir)
          include   -- include files ($includedir)
        libexec     -- private binaries ($libexecdir)
        share       -- data files ($datadir, $datadir/$datasubdir)    
        doc         -- documentation ($docdir)
          html      -- html doc ($htmldir, $haddockdir)
          man       -- man pages ($mandir)

This can be achieved with the following cabal configuration defaults:

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

N.B.:

  • Cabal configuration files don't actually support ~. You must replace that with /Users/xxx where xxx is your account name.
  • All packages for a given compiler are under a single directory. When an old compiler is removed, all the packages compiled for it can be easily removed too.
  • All components for a package are under a single directory. This facilitates easy location and removal of a single package, for either a single compiler, or all installed versions.
  • If a package generates different doc for different compilers (it may have different APIs available), then this structure preserves each.
  • Executables are also per compilation, which is sometimes important (for Haddock, for example).

4 Executables

Packages that build executables to be run from the command line present a difficultly. They are built into a per-package bin directory, and then should be symlink'd somewhere on the user's PATH. For global installs, the logical place is one of:

/usr/bin
/usr/local/bin

For user installs, since ~/bin is not on the PATH by default on Mac OS X and may not exist, binaries are symlink'd into:

~/Library/Haskell/bin

Alas, cabal only supports one location for both kinds of build, and so it is set to tbe the later.



5 References

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