[Haskell-cafe] install-dirs on Mac OS X

wren ng thornton wren at freegeek.org
Wed Dec 23 01:34:26 EST 2009


Mark Lentczner wrote:
> Taking a cue from the various preinstalled language systems on Mac OS X, up over in /Library might be a better place:
> 
> 	Python puts installed packages in:
> 	/Library/Python/<version>/site-packages
> 
> 	Ruby puts installed packages in:
> 	/Library/Ruby/Gems/<version>
> 	/Library/Ruby/Site/<version>
> 
> 	Java appears to use
> 	/Library/Java/Extensions
> 	and has a link to the packages that come the framework as:
> 	/Library/Java/Home

Which is just part of the symlink chain:

/Library/Java/Home
/System/Library/Frameworks/JavaVM.framework/Home
/System/Library/Frameworks/JavaVM.framework/Versions/Current/Home
/System/Library/Frameworks/JavaVM.framework/Versions/<shortVersion>/Home
/System/Library/Frameworks/JavaVM.framework/Versions/<longVersion>/Home

Which is rather convoluted, but is designed to allow switching over the 
default Java used internally by OSX. (Java6 is only available on 
10.5+intel. And it's not recommended to switch the version registered 
for OSX, though it's fine to munge your $PATH to pick the new one since 
OSX internals doesn't use $PATH to resolve things.)



Overall, I'd like taking the cue to break things out by version number 
and then have some symlinking (or tool) in order to select one of many 
installed versions. This would be helpful for people who want to have 
multiple versions installed for debugging purposes. Even though the 
compiler version is already interposed on the lib dir path, giving a 
high-level separation by version makes it easier to deal with the 
different sets of libraries compiled by/for each version*compiler.

However, I would be opposed to storing anything in /Library or /System. 
Those are for system use and sysadmin experience tells me never to mess 
with the system installs. For things used by the system, it's liable to 
break the system; and for everything, it's liable to be broken on system 
upgrade. OSX does have their framework packaging system, which has been 
used successfully in previous versions of GHC; if anything happens in 
/Library or /System then it has to go through the framework packaging 
system IMO, which means having someone as the OSX maintainer. But I 
think the framework system isn't really a great option for the kinds of 
development we end up doing. I.e., many Haskell hackers are devoted 
developers and many of the packages require other *nix tools to be 
installed as well. Because of that, I think it'd be a lot nicer to try 
to integrate with the way other *nix installs are done on OSX: that is, 
via Fink or MacPorts, or in /usr/local.

Besides, if we used something like a $HASKELL_PATH, or a tool for 
querying and recording installation paths, then it doesn't really matter 
where the default is since people can choose their own. All that matters 
is the structure of the tree rooted there.



> 2) Structure of package pieces
> 
> 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.

Again, it's good not to mess with system internals (where GHC is the 
"system" here). In general we *want* Cabal to install things in a 
different location than the GHC base libraries. Cabal packages can be 
upgraded and removed and maybe even have multiple versions installed. If 
someone borks their set of Cabal packages, they shouldn't have to 
reinstall GHC as well in order to fix things. Similarly, the libraries 
used by Cabal itself should be separate from the packages for users to 
use. Both GHC and Cabal libraries could be accessible if the user 
packages can't satisfy some dependency, but their maintenance should be 
kept distinct.

I'm not saying the current Cabal defaults are the best or shouldn't be 
changed, but those questions are orthogonal to the issue of interacting 
with GHC's base libraries.


> I think it best if everything for a package is in one place - making removal very easy:
>    executables: --prefix--/packages/--pkgid--/bin
>    libraries:   --prefix--/packages/--pkgid--/lib/--compiler--
>    data:        --prefix--/packages/--pkgid--/share
>    doc:         --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.

I would be supportive of a setup with ./packages/<packageName>/ as the 
root of <packageName>'s files. This is the strategy used by stow[1], as 
well as texmf trees for LaTeX[2]. It works really well for avoiding and 
resolving conflicts. There's some development overhead for setting up a 
tool for merging the trees, but I think it's worth it (i.e., I'd be 
willing to help write it).

The stow approach to tree merging is to symlink everything together into 
one canonical directory, but that's not the only option. The texmf 
approach is to direct queries through a program which maintains database 
information, rather than directing queries through the filesystem. Both 
approaches are used by other projects as well. The latter has a higher 
development cost, but is ultimately more powerful and configurable.


[1] http://www.gnu.org/software/stow/
[2] http://www.tug.org/tds/tds.html (namely ./tex/latex/<pkg>/* stuff)

-- 
Live well,
~wren


More information about the Haskell-Cafe mailing list