

Using /usr/local - wolfish
http://hivelogic.com/articles/2005/11/using_usr_local

======
briansmith
"Today’s UNIX and UNIX-like systems (such as Mac OS X, Linux, FreeBSD,
Solaris, etc.) allow you to create a special place in the filesystem where you
can compile and install your own software independent of and without affecting
the rest of the system."

Yes, that is called "/opt", not /usr/local. /usr/local is for local extensions
to the operating system itself, not applications.

~~~
SwellJoe
Depends on where you live, OS-wise. But, yes, /opt has mostly been settled on
in the past few years for most third party applications...and it's a place
where randomly named paths are not considered a faux pas. Such as,
"/opt/ruby-1.9.1" and "/opt/perl5.005_04" and such, and they don't have to
live in normal /usr/local/usr, /usr/local/etc, and so on, paths, which is the
norm in /usr/local. One can argue all day about what makes something a "local
extension to the operating system itself". Is Python a local extension to the
OS itself? What if a large number of system tools use Python (as is the case
on Red Hat based systems, Gentoo, and Ubuntu more with every release)? But,
because the /usr/local binary directories tend to already be in the path (and
before the / equivalents) installing random stuff in there is probably a
horrible idea.

But, folks really ought not be encouraging this sort of thing, in general.
Unless you really know you need some specific version of software, and why,
you should probably be using the OS-provided packages, which are better tested
(so they're generally more reliable), better supported (so you can complain to
someone when you run into a problem), and more widely used (so you can find
people talking about your specific version when you hit up Google for advice).

Anyway, I agree. /opt is the socially acceptable place to put random crap on a
system.

------
there
> It turns out that the update has actually overwritten the Ruby binary she’s
> compiled with a different version, and her software no longer works. > >
> This could have been avoided if she’d installed the Ruby binary in a safer
> place, and set her shell and her software to use that binary.

and then every time you try to work with other ruby-related software, it
either picks up the new version in /usr/local or the old version in /usr or
some random version in /opt/local that macports installed, and you may not be
sure which. this problem gets much worse when you are dealing with shared
libraries like graphics libraries. the autoconf junk may help by allowing you
to specify something like "./configure --with-jpeg=/usr/local ..." but
sometimes you have to override LDFLAGS and you're suddenly wasting so much
time just trying to get all this stuff to work.

3rd party port/package systems for mac os just made the problem worse by
forcing you to install duplicate copies of everything that comes with mac os
because of package dependencies. i think a better solution would be to only
have one version of the software on the system at a time. if macports wants to
upgrade your ruby, make it delete everything in /usr/lib/ruby or setup
symlinks to the new version in /usr/local/lib/ruby.

~~~
ankhmoop
On one hand, you decry mismatched dependencies between independent versions of
the software.

On the other, you decry 3rd party port/package systems because they use their
own entirely independent dependency hierarchy for the purpose of wholly
avoiding incompatibility issues.

Then you recommend that 3rd party port/package systems actually delete
operating system managed components and replace them with their own.

This position is, at best, inconsistent.

~~~
there
> This position is, at best, inconsistent.

and that is why i gave up trying to use mac os as my desktop. there was no
proper way to install 3rd party software that dealt with conflicting versions.

if macports or some other package solution could get it right, then articles
like this one would be irrelevant and users could just do something simple
like "<some utility> install ruby", get a new ruby installed and have the old
built-in version disabled. until something like that happens, you are going to
run into issues where some software picks up one version and something else
picks up another. relying on a properly set $PATH is not a solution.

~~~
ankhmoop
Relying on a properly set $PATH is exactly the solution.

Any other approach will directly interfere with other operating system
components and lead to exactly the bizarre failure cases you are reporting.

------
donw
A few years of systems have given me a really good way for handling this
problem (other than the obvious bit of just using whatever packaging system
the OS provides). I use /opt rather than /usr/local, but you can do either.

Build all your packages into /opt/package-version, and set up a symlink from
/opt/package to /opt/package-version for whatever you want the default version
to be. As an example, Ruby 1.8.7 goes into /opt/ruby-1.8.7, and /opt/ruby
points to this directory.

The only disadvantage is you need to add each bin/ directory into your path,
which will be a problem if you install hundreds of applications in this
fashion.

On the other hand, being able to do in-place upgrade and rollback almost
instantly (just re-point the symlink) is a big, big win in a production
environment. Plus, because everything is located in one place, you can readily
move your /opt/app-version directory to other systems.

~~~
pfaux
Yes, essentially I follow the same simple system. But to avoid adding each bin
directory to the path, I create for each application an executable script in
/usr/local/bin that performs an "exec /opt/package/bin/app-name $@". The only
directory to add to the path is /usr/local/bin. Then, as you say, managing
multiple application versions is as easy as repointing the symlink in /opt.

No need for package managers that do who knows what to your system.

The one exception is for shared libraries, which I build to /usr/local. That
way 'make' can find them easily without fiddling with LDPATH.

~~~
donw
Why not just do symlinks in /usr/local/bin?

~~~
pfaux
A script can pass specific environment variables to the particular instance of
the application.

------
graywh
I'm surprised no one's mentioned the utility "stow". It lets you install
things to their own /usr/local-style hierarchy and will symlink all the files
for you. That way you can easily remove something after you've deleted the
source directory.

------
pert
Readers of this article might also be interested in Fink: a package manager
for OS X, based on dpkg and apt from Debian.

About Fink: <http://www.finkproject.org/about.php>

Guide to building your own packages: <http://www.finkproject.org/doc/quick-
start-pkg/index.php>

~~~
wolfish
Macports is a similar project. I usually use it as a last resort when I can't
"roll my own".

<http://www.macports.org/>

~~~
blackguardx
Which one is better?

~~~
SwellJoe
apt/dpkg is a better package management system. macports seems to have more
recent packages, and a higher quantity, because building and updating a port
is somewhat simpler and less resource intensive. I would choose a good package
manager over the latest and greatest packages from a poor package manager
every single time. So, I would choose fink, were I using a Mac (and when I've
been charged with maintaining developer Macs in the past, I used fink, though
I also experimented with darwinports, as it was called back then). Neither was
great, since you still have to get fancy with paths and such in order to
select between which versions of things to use, and header file paths can be a
problem when building your own software, if you have the Apple developer tools
installed, too. And, if you're distributing binaries, you have to be careful
you're building against the libraries your users will have available.
Developing on a Mac can be pretty painful in this regard.

~~~
lincolnq
This is one of the major reasons I need Linux for development instead of OS X
or anything else. I tried Fink and Macports and got really frustrated with
both.

------
silentbicycle
See also hier(7) (<http://www.openbsd.org/cgi-bin/man.cgi?query=hier>). That's
the OpenBSD man page, something comparable will probably be present on other
Unices. (OpenBSD's pkg system installs all non-base packages in /usr/local/ ,
fwiw.)

------
geuis
This is a great article. It's been around for a while but it completely
changed how I build projects on my Mac.

