Hacker News new | past | comments | ask | show | jobs | submit login
Using /usr/local (hivelogic.com)
65 points by wolfish on Mar 26, 2009 | hide | past | web | favorite | 28 comments

"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.

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.

The statement seems accurate enough. FHS is not directly followed by any BSDs, so here is Mac OS X's hier(7) man page:

/usr/local/ executables, libraries, etc. not included by the basic operating system

'/opt' is not documented by hier(7) on FreeBSD, Mac OS X, or OpenBSD.

+1 for /opt

The only way I feel comfortable compiling software into my system because I KNOW I can delete it by just removing the directory created inside /opt.

The only tricky part is making sure your compiled binaries in /opt/*/bin are in your executable path.

This is the way I do it. Will this make problems?

/usr for stuff installed by apt-get.

/usr/local for stuff I install with "./configure && make && make install" or similar commands.

/opt for self-contained application bundles.

That's not what Gentoo does. It uses /opt for any closed-source software, while /usr/local is left untouched. I believe Ubuntu doesn't use /usr/local either.

Wikipedia (http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard) says it's for "Tertiary hierarchy for local data, specific to this host."

Creating yet another complication for jails and chroot.

> 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.

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.

> 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.

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.

> and you're suddenly wasting so much time just trying to get all this stuff to work.

Yes,I've lost hundreds of hours to this kind of thing.

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.

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.

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

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

I(well really it's make install --prefix=/usr/local/python2.5) do the same thing in /usr/local.

I don't see the need or point for /opt. I guess I'm socially unacceptable?

I like /opt for one big reason: the default path for a lot of packages is /usr/local, so putting things in /opt can help protect them from being accidentally overwritten.

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.

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

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


Which one is better?

Macports generally builds the latest version from source. I've had problems with a few things in the past needing manual patching, but overall I like it. You can keep multiple versions installed, but only one can be active at a time.

Fink downloads pre-built binaries, but AFAIR, it can build from source, too. It also has a GUI interface.

That's about all the insight I can provide.

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.

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.

I'm using a Mac and use Macports for almost everything. Fink was the best choice back on OS X 10.2 but MacPorts generally has the latest versions you'll be wanting to use. My hierarchy is usually /opt and then /usr/local for stuff I don't want the MacPorts version of.

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.)

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

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact