Difference between revisions of "Mac OS X Common Installation Paths"

From HaskellWiki
Jump to navigation Jump to search
 
(re-written as a proposal)
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 following is my initial e-mail to haskell-cafe about installation paths Mac OS X. I'll clean this up from an e-mail to a proposal soon. [[User:MtnViewMark|MtnViewMark]] 05:44, 23 December 2009 (UTC)
 
  +
* 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 ==
I have been thinking about the location of installed Haskell package files on Mac OS X. The choice of location affects:
 
* GHC & other Haskell implementations
 
* Haskell Platform
 
* Cabal & cabal-install
 
* Haddock
 
If all those agreed on directory locations and layouts, I think the state of Haskell on Mac OS X would be nicer for users. In particular, my hope is for users to end up with an automatically complete Haddock documentation incorporating everything they install.
 
   
  +
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.
1) Packages the user installs --global
 
   
  +
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.
I noticed that the default location for global installation with cabal is on Mac OS X is /usr/local:
 
install-dirs global
 
-- prefix: /usr/local
 
   
  +
== Implementations ==
This then intermingles all the Haskell package files along with all sorts of other things that live in /usr/local and environs. While this is arguably convenient for executables that end up in /usr/local/bin (in most people's PATH), it does make things less than tidy, and harder to clean up.
 
   
  +
Haskell implementations are generally installed for use by all accounts on the
Taking a cue from the various preinstalled language systems on Mac OS X, up over in /Library might be a better place:
 
  +
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:
* Python puts installed packages in: <br /><tt>/Library/Python/''version''/site-packages</tt>
 
  +
/usr/bin
* Ruby puts installed packages in: <br /><tt>/Library/Ruby/Gems/''version''</tt><br /><tt>/Library/Ruby/Site/''version''</tt>
 
  +
back into the framework bundle. ''[Q: Would <tt>/usr/local/bin</tt> be more appropriate? ]''
* Java appears to use <br /><tt>/Library/Java/Extensions</tt><br />and has a link to the packages that come the framework as:<br /><tt>/Library/Java/Home</tt>
 
* Perl put installed packages in:<br /><tt>/Library/Perl/<version></tt>
 
   
  +
Packages that come with the implementation, should be located within the Framework
I suggest that the default place for global installs on Mac OS X be:
 
  +
bundle.
* <tt>/Library/Haskell/</tt>
 
   
  +
If the implementation has any GUI applications, these should be installed in:
Since cabal already by default interposes the compiler version into the lib dir, path, there doesn't appear to be a need to put a <version> dir level near the top.
 
  +
/Applications
   
  +
'''NB:''' Haskell Platform already installs GHC and included packages in
  +
precisely this way. Woot!
   
  +
'''NB:''' These guidelines allow for multiple implementations and multiple
2) Structure of package pieces
 
  +
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 <tt>/usr/bin</tt>
  +
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
I notice that cabal/cabal-install's default layout of where a package's pieces go, and GHC's layout of its base packages don't agree. Further, cabal/cabal-install's are not set up so that one can easily delete an installed package without hunting down its parts.
 
  +
paths should be:
  +
~/Library/Frameworks
  +
~/bin
  +
~/Applications
   
  +
Not all software for Mac OS X offers such an option on installation, and while
cabal/cabal-install defaults the parts as follows:
 
  +
nice, it is by no means universal.
executables: --prefix--/bin
 
libraries: --prefix--/lib/--pkgid--/--compiler--
 
data: --prefix--/share/--pkgid--
 
doc: --prefix--/share/doc/--pkgid--/
 
html: --prefix--/share/doc/--pkgid--/html
 
That's at least four directories you need to hunt down if you want to clean out a package, and rummaging through bin to figure out which things to remove. (Not to mention libexec, which isn't used by any packages on my system, so I can't say where it goes...)
 
   
GHC/Haskell Platform use a different layout:
 
executables: --prefix--/bin
 
libraries: --prefix--/lib/--compiler--/--pkgid--
 
data: --prefix--/share/--pkgid--
 
doc: --prefix--/share/doc/ghc/libraries/--pkgid--/
 
html: --prefix--/share/doc/ghc/libraries/--pkgid--/
 
   
  +
== User Installed Packages ==
I think it best if everything for a package is in one place - making removal very easy:
 
  +
  +
User installed packages are placed under a "prefix" that depends on if the user
  +
choose to install for all users (<tt>--global</tt>) for just their own use (<tt>--user</tt>):
  +
/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 <tt>--global</tt> and <tt>--user</tt> installs, the package layout should
  +
be:
 
executables: --prefix--/packages/--pkgid--/bin
 
executables: --prefix--/packages/--pkgid--/bin
 
libraries: --prefix--/packages/--pkgid--/lib/--compiler--
 
libraries: --prefix--/packages/--pkgid--/lib/--compiler--
  +
lib-exec: --prefix--/packages/--pkgid--/libexec/--compiler--
 
data: --prefix--/packages/--pkgid--/share
 
data: --prefix--/packages/--pkgid--/share
 
doc: --prefix--/packages/--pkgid--/doc
 
doc: --prefix--/packages/--pkgid--/doc
 
html: --prefix--/packages/--pkgid--/doc
 
html: --prefix--/packages/--pkgid--/doc
I put the "packages" level at the top, so that other things, like a master Haddock index dir could be put easily directly under the prefix.
 
   
  +
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 ==
3) Symlinks for binaries
 
   
  +
Packages that build executables to be run from the command line present a
This does suggest that it would be nice for the symlink-bindir facility (is that in cabal itself, or added by cabal-install?) to have a version for --global installs. Users could then either set something like:
 
  +
difficultly. The should be installed in a place that is only on the user's
symlink-global-bindir: /usr/local/bin
 
  +
PATH. In general, on a stock Mac OS X install, this means one of:
in .cabal/config.
 
  +
/usr/bin
  +
/usr/local/bin
  +
~/bin
   
  +
Cabal already supports this issue somewhat with the <tt>symlink-bindir</tt> option.
Or
 
  +
This feature, if extended so it can support separate options for <tt>--global</tt> and <tt>--user</tt> would enable the following scheme:
symlink-global-bindir: /Library/Haskell/bin
 
and then put that in their PATH
 
   
  +
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
   
  +
The user can then choose to put these on their PATH if they wish. Alternatively,
4) Quick access to the Framework
 
  +
users could choose to alter the <tt>smlink-bindir</tt> directives to point at
  +
/usr/local/bin
  +
~/bin
   
  +
I like Java's convenience link 'Home', and suggest that
 
  +
== 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
 
/Library/Haskell/GHC
  +
to:
be a symlink to where the framework's package files are stored:
 
 
/Library/Frameworks/GHC.framework/Versions/Current/usr/
 
/Library/Frameworks/GHC.framework/Versions/Current/usr/
   
Other implementations could use the same idea.
+
Other implementations should use the same idea.
   
  +
----
Having this here would also (I suspect) help in getting Haddock to be able to find all the bits needed to generate a comprehensive index.
 
  +
== References ==
 
  +
# [http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPFileSystem/Articles/LibraryDirectory.html#//apple_ref/doc/uid/20002282-BAJHCHJI Apple guidelines for the /Library and ~/Library files]
 
  +
# [http://www.haskell.org/pipermail/haskell-cafe/2009-December/071150.html MtnViewMark's original e-mail on this topic.]
Thoughts? I'd be happy to help by supplying patches for various tools to normalize all this on some agreed upon layout. I admit that I'm a bit unclear where the directory choices are being made: Haskell Platform's build process, or GHC's? Cabal's defaults or cabal-install's? And then clearly parts of Haddock. Given the number of tools that need to agree, seems best that we hash it out (here or in the wiki) first, before making patches.
 
 
[[User:MtnViewMark|MtnViewMark]] 05:44, 23 December 2009 (UTC)
 

Revision as of 17:59, 26 December 2009

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.