
Homebrew: OS X’s Missing Package Manager - mrduncan
http://www.engineyard.com/blog/2010/homebrew-os-xs-missing-package-manager/
======
jrockway
What OS X really needs is a package manager (erm, "app store", yeah, that's
it) for native GUI apps. Every program seems to want you to update it every
time you open it, which is just silly when there is already Software Update
for that purpose.

Also, installing software on OS X is really difficult. Going from saying "I
want VLC" to actually having VLC is an annoying multi-step process on OS X.
Google for VLC's website, find the download link, download, wait, mount dmg,
drag-and-drop app to app folder, unmount dmg, remove files, empty trash,
launch app. On Linux, I just say "apt-get install vlc", go get a cup of tea,
and type "vlc" to run VLC. Much easier.

~~~
GeneralMaximus
<http://metaquark.de/appfresh/>

------
pquerna
First step:

    
    
      # Take ownership of /usr/local so you don't have to sudo
      sudo chown -R `whoami` /usr/local
    

Hell no, bad idea, do not want.

~~~
jrockway
Yeah, now an attacker will be able to delete the binaries you downloaded from
the Internet, in addition to all of your personal files.

If your single-user system is compromised to the point where it matters what
files you can and can't write, you've already lost. And the "low hanging
fruit" in this attack scenario was the files you actually cared about.

(Also, this is a dupe of the top-rated comment. Maybe read _one comment_
before replying?)

~~~
JadeNB
> single-user system

Am I missing something in the grand-parent that suggests that his is a single-
user system?

Even if it is the case, then, as you pointed out elsewhere
(<http://news.ycombinator.com/item?id=1096327>), the solution's still sub-
optimal: better `~/bin` than `/usr/local` (right?).

------
guns
> MacPorts is an autarky -- you get a duplicate copy of zlib, OpenSSL, Python,
> etc. Homebrew uses what is already there, and consequently, most stuff has
> zero dependencies and builds faster.

MacPort's self-sufficiency is its strength. Apple's system is managed by
Apple, via Software Update. Depending on and modifying that system is
foolhardy. What happens when the next point upgrade of OS X updates a library
to a non-compatible version? Or what if you need ruby 1.8.7, but Leopard's
ruby is at 1.8.6 (1.8.7 was a large release)? Your package system doesn't talk
to Apple. Apple's update either breaks you, or your updates break OS X.

In fact, MacPorts once linked to OS X's libraries, but they found out how
brittle this was, and switched to the current system.

OS X is not a Linux distribution, and it is not organized and defined by its
package management system. If you want the flexibility of an open source Unix
package system in OS X, you have to build one separately from Apple's Emerald
City. The thing is, you can, and it works pretty well.

The problem I see most people having with the MacPorts / OS X duality actually
stems from improper management of their shell's PATH. One way to manage
namespace collisions is this: place MacPorts bin directories below the system
PATH:

    
    
        export PATH="/usr/local/bin:$PATH:/opt/local/bin:/opt/local/sbin"
    

and then create symlinks in /usr/local/bin to specific MacPorts executables
that you would like to have on the top of the search stack. That way, you'll
use Apple's binaries by default, and then you can cherry pick the MacPorts
binaries that you would like to use in place of OS X's defaults. The inverse
of this works quite well too.

> Dependency resolution and updates are basic or not working yet.

I'm sure this is in the works, but my feeling is that managing dependencies
and updates are the raison d'être of a package management system. Without
this, you just have an installation management system; a shortcut around
`make' and `ln'.

------
rbanffy
"Take ownership of /usr/local so you don't have to sudo"

Ouch!

~~~
jrockway
Yeah, don't put stuff in /usr/local. Put it in ~/bin.

~~~
azanar
This works if you want it to be available for just you.

Say for instance you have a dev server, so security isn't _as_ big a deal*
used by a team of people, all of whom would want access to the same basic
packages. It seems that /usr/local/ or some other world-visible place would be
the location for this stuff.

That you don't have to be root is the same way that you don't _necessarily_
have to be root to install programs in the usual MacOS way of running a GUI
installer. If you are part of admin, you're already privileged to sudo anyway,
so the protection you get is primarily psychological; you type 'sudo', and it
triggers the part of your brain that pays much closer attention to what you
put on the command-line.

But as I mentioned to rbanffy, it is very possible I am missing a key risk
that makes this a very bad thing to do. I am open to enlightenment. ;-)

~~~
kree10
Say there's a hole in your web browser that lets an attacker run arbitrary
code. That's bad news for your home directory, but at least if the binaries on
your machine (under /usr/local or wherever) are owned by root, the browser is
running as "you" so it can't overwrite them with malware.

Then again, making /usr/local writable by admins goes along with the OS X
convention of giving admins write permission to /Applications but I'm not a
fan of that either.

~~~
azanar
Hmm. Good point.

This becomes a much larger problem if something runs things from /usr/local
with increased privileges -- something from launchd run as root, for instance.

I was originally thinking just from the perspective of the active user, but a
lot of things get run without the logged in user's knowledge, and with a
varying level of privilege.

Ok, yeah, I agree with the original poster of this thread: yikes, time to
start chmodding things.

~~~
dhess
I think it's much more likely that something bad will happen during a build
with "sudo brew install some-package" than someone successfully hijacking,
say, my Safari session and then installing a trojan in my user-writable
/usr/local directory. This _is_ Mac OS X we're talking about: if you've
written an exploit like that, why would you bother attacking apps in a
directory that doesn't even exist on the vast majority of Mac installs when
you could just as easily modify something in /Applications instead, and
exploit practically all of them?

Anyway, back to the dangers of using sudo with Homebrew or Macports. When you
build software by hand, without a package manager, do you ever do it as root?
I sure don't. But that's exactly what Macports does in its default
configuration, and that's what Homebrew would require if you used it with a
non-writeable /usr/local. It doesn't have to be a malicious attack, either:
just a simple bug in the build system would suffice. For example, if a "clean"
rule in a Makefile has a step that looks something like, god forbid, "rm -rf
$(BUILD_ROOT)/" and you're running the make as root, you'd better hope that
BUILD_ROOT is not defined to be "".

Ideally, all of these package managers would separate the step of _building_
from the step of _installing_ so that you would only need root privileges for
the latter, a la Debian's sbuild and friends. Then using a traditional
privileged /usr/local directory would be a no-brainer, for the theoretically
smaller attack surface it would provide. But none of the Mac packaging systems
work like that, to my knowledge. They go for the convenience of a single
build+install command. Given that, I'll stick with my user-writable directory
and risk the hijacking scenario.

~~~
bl4k
ports does have the separation, you fetch/build as the local user and run
install escalated.

running a fetch as root or blindly changing the permission structure of
/usr/local should scare everybody.

~~~
dhess
> ports does have the separation, you fetch/build as the local user and run
> install escalated.

I see from the Macports 1.8 release notes that privilege dropping is
supported. That's good news, but is it the default? The release notes indicate
that you need to pass command-line options to get this behavior. I assume that
most people just "sudo port install foopkg".

> blindly changing the permission structure of /usr/local should scare
> everybody.

On Mac OS X (as of Snow Leopard, anyway), there are no permissions to change,
since /usr/local doesn't even exist until you create it. Nothing in the OS
itself depends on it or anything that lives there. There's nothing special or
privileged, neither by design nor by convention, about /usr/local on Mac OS X.
Making it user-writable and using it with a package manager is no different
than creating a 2nd home directory for that purpose. If you're running that
rare bird that is a multi-user Mac and co-managing packages with other trusted
users, then you can simply make it group-writable by those users. It's safer
than giving them any sudo privileges.

~~~
bl4k
$ port fetch wget

$ port build wget

$ sudo port install wget

> "is no different than creating a 2nd home directory for that purpose"

except that a million build scripts and make files out there assume
/usr/local/ as a default location. setting up something like '/home/shared/'
is not a problem, just don't mess with paths that are defaults

~~~
dhess
Thanks, I didn't know about fetch/build in Macports.

> except that a million build scripts and make files out there assume
> /usr/local/ as a default location. setting up something like '/home/shared/'
> is not a problem, just don't mess with paths that are defaults

Yet Macports puts everything in /opt/local and that doesn't cause any
significant problems. I haven't run across a free software project in years
that didn't have support for an install prefix.

Anyway, I should have been more specific: on a Mac, making /usr/local user-
writable and using it with a package manager is no different than creating a
2nd home directory for that purpose, _from a security standpoint_. I agree
that putting things in /usr/local is the most logical place to put compiled
software (mainly for consistency with one's own scripts that run on multiple
platforms), and that's one of the reasons I use /usr/local with Homebrew
instead of something in my home directory.

------
telemachos
Just because people never seem to mention it, I will also throw in a good word
for Rudix. From their project page (<http://rudix.org/>):

 _Rudix features a world class collection of pre-compiled and ready to use
Unix compatible software which are not available from a fresh installation of
Mac OS X but are popular among other Unix environments. Here you can find
utilities, programming languages, libraries and tools delivered as standard
Mac OS X packages._

The packages are pre-compiled dmgs, easily downloaded and installed, or you
can download the whole suite if you prefer.

The nice thing here is that if you _only_ want coreutils and you don't want to
install Xcode to get gcc, you don't have to.

~~~
delackner
This may be slight, but the name is horrible. Maybe the originator doesn't
speak english as a first language, but the word just sounds like someone is
poking you in the eye.

------
bryansum
I think the real genius of Homebrew is in integrating it with git & Github and
in turn making it something social. In my experience, sometimes a formula
wasn't available in the main repository and I could easily merge in another
Github fork's changes.

------
tvon
antonovka had some interesting comments on why macports does the things it
does when homebrew was doing the rounds a few months back:

<http://news.ycombinator.com/item?id=872072>

It's worth a quick read, imo.

~~~
jokull
That is indeed a good read. Maybe MacPorts needs a better website where they
explain this stuff. You gotta give it to Homebrew - the one page README is
better then the "MacPorts Official Homepage" front page. (In fact, GitHub's
one-page-README-intro is a terrific example of restraint producing better
results).

I still like the git-recipe idea. Perhaps MacPorts should have a Git
repository of 'rouge' community ports they can periodically review for merging
and then inclusion.

~~~
tvon
I think Rails (or 37signals) taught developers that a little marketing savvy
isn't a bad thing, and that thinking has in turn permeated the ruby community
and shows itself in projects like Homebrew. Not smarmy marketing, it's just
hackers asking themselves "how can I most simply show how powerful this is",
more or less.

------
bts
This looks pretty interesting (and I particularly like the ability to have a
package pointed at the bleeding edge), but I'm not sure how I feel about
/usr/local being owned by an arbitrary user. What happens if there's more than
one user on the machine?

~~~
akirk
You can have homebrew reside in any place you want on your hard drive. The
Readme actually suggests to first install it into a directory "brew" in your
home dir. You just need to adapt the $PATH in your bashrc accordingly.

From my own experience: beware with moving that directory after installing
some formulae somewhere else. It caused quite some trouble for me and i wound
up recompiling everything in the new directory.

------
ComputerGuru
_Installing packages is faster, too, because Homebrew also works hard to avoid
package duplication. No more installing yet another version of Perl as a
package dependency when you already have a working install of Perl built into
OS X. Best of all, Homebrew has a basic philosophy that you shouldn’t have to
use sudo to install or manage software on your computer._

Finally! At last! I hope this takes off, because I've been manually
∂ownloading and compiling everything in order to avoid conflicting versions,
redundancy, et. al. that come with Fink and MacPorts.

------
telemachos
I think the project overall is great, but I don't understand the dislike of
sudo. There's simply nothing wrong with sudo (or su or entering your password
in the GUI). OSX is a UNIX (a certified one, in fact), and it follows the
principle that some actions require elevated privileges. Installing software
system wide has historically required elevated privileges (I think for good
reason), and so sudo is necessary to put software into /usr/local. There's
nothing bad about using sudo for this.

~~~
blasdel
I dislike sudo because I want my user-installed stuff to be installed in my
damn home directory, not mixed in with system software. I want to me able to
install things on a multi-user system without affecting anyone else.

Every other non-language-specific package manager blithely assumes that it's
the only one on the system, so they assume that nothing is already present,
and don't even think about the possibility of independent unprivileged use.

~~~
telemachos
Fair enough, but there are two separate questions here:

    
    
        1. Where do you want the software?
        2. Are elevated privileges required to put the software where you want?
    

If you want to load all your software into $HOME/bin, then more power to you
and no sudo is required. However, /usr/local serves an important and valid
purpose (to provide packages system-wide), and it _should not_ be available
without elevated privileges. (By the way, 'not mixed in with system software'
is misleading, since OSX ships with an empty /usr/local. Nothing you put in
/usr/local mixes with anything.)

Homebrew's official README suggests changing the ownership of /usr/local, and
I think that's a terrible idea for multi-user machines. (Having said that, I
suppose that many people have single-user machines, and in that case the issue
is largely moot.)

Finally, a simple way to put software into your $HOME without ever needing
sudo is available in most cases:

    
    
        ./configure --prefix=$HOME

~~~
blasdel
And those two separate questions are both ones that no other package manager
even bothers to ask!

/usr/local does start off empty on OS X, but it's where every random .pkg you
download likes to put stuff. You'll get mixing unless every non-app you
install comes from a package manager. On FreeBSD every package that didn't
ship in the default install goes there. There's a reason that MacPorts uses
/opt/local by default.

------
akirk
Articles like this is what Homebrew needs. I was already using it and doing my
own Formulae, now I know how to contribute back. Nice!

(Had a lot of pain trying to install GTK through homebrew and finally gave up.
If someone succeeds, please ping me :)

------
mhd
I've been using brew for a while, and it's a nice, somewhat hack-ish solution
to the problem. OS X already comes with a lot of software, so anything that
you use in addition is basically a secondary system. So if it's a kludge, make
it a small and fast one.

The wiki page has some interesting notes on integrating it somewhat with
scripting language modules (cpan/easy_install/gem).

------
hypermatt
I'm excited because package management has really sucked on OSX. Port usually
works well enough for everything I need to do. But I always end up with
dueling tool chains, the primary osx ones and Port's copies. Compiling in
xcode is always odd since you don't which lib imports to use etc ..

------
trevorturk
I just switched from macports to homebrew a few weeks ago, and I love it. Most
definitely recommended.

~~~
apinstein
What's better? Aside from the easier pkg generation, I don't yet see a
difference from the handful of articles I've read.

Explain to me a pain point of Macports that homebrew solves.

~~~
trevorturk
Installation is faster. You can understand how the formulas work. You can make
your own. You can find lots of them very easily. You can contribute more
easily. It's on GitHub.

I dunno - there's probably more, but that's a quick list.

What really drove me to move was that I was having trouble with Snow Leopard
not being supported very quickly by MacPorts. Even once everything I needed
was working, I still had problems with CouchDB and couchdb-lucene. I'm not
sure what the problem was, but I tried a few things that were suggested, and
nothing worked.

So, I did the whole Scorched Earth thing and started fresh with Homebrew.
Everything worked right away, and quickly. I found formulas were added very
quickly. I found some that weren't in the main repo (I think couchdb-lucene
was one of them) and they were all understandable and worked well.

All in all, I just had a much nicer experience with Homebrew than with
MacPorts. I'm not hating on MacPorts, I'm just saying Homebrew hasn't caused
me one moment of grief since I started using it. Well... maybe one, because I
had to find and install the OS X package for Git to get started with
installing everything else ;)

~~~
natch
Cool. Not surprised that it went smoothly at first, but do let us know how
that works out for you after a few OS X updates.

------
masomenos
Sounds very promising. I've done OK over the years using MacPorts, but like
the idea of not installing Yet Another Perl dist, etc.

~~~
dschobel
I've used homebrew a bunch (and even contributed a few formulae) after I heard
Al3x tweet about it.

There is so much less friction than using macports or fink that I dropped them
immediately. Definitely check it out.

------
runjake
First question that should be answered by anyone trying to selling this:

Why is it better for me than MacPorts and why should I use it?

~~~
telemachos
C'mon though - you need to meet people half way and read a little. From the
Github README (<http://github.com/mxcl/homebrew/>):

Here's why you may prefer Homebrew to the alternatives:

Zero configuration installation

Copy the contents of this directory to /usr/local. Homebrew is now ready for
use.

Or… install anywhere!

You can actually stick this directory anywhere. Like ~/.local or /opt or /lol
if you like. You can even move this directory somewhere else later. Homebrew
never changes any files outside of its prefix.

The GoboLinux approach

Packages are installed into their own prefix (eg. /usr/local/Cellar/wget) and
then symlinked into the Homebrew prefix (eg. /usr/local).

This way the filesystem is the package database and packages can be managed
with existing command line tools. For example, you can uninstall with rm -rf,
list with find, query with du. It also means you can install multiple versions
of software or libraries and switch on demand.

Of course, you don't have to do anything by hand, we also provide a convenient
and fully-featured four-letter tool called brew.

You don't have to sudo

It's up to you.

Create new package descriptions in seconds

Package descriptions (formula) are simple Ruby scripts. Generate a template
with:

    
    
        brew create http://foo.com/tarball-0.8.9.tgz
    

Or edit an existing formula:

    
    
        brew edit foo
    

Package descriptions not required

MacPorts doesn't support the beta version? Need an older version? Need custom
compile flags? The Homebrew tool-chain is carefully segregated so you can
build stuff by hand but still end up with package management.

Just install to the Cellar and then call brew link to symlink that
installation into your PATH, eg.

    
    
        ./configure --prefix=/usr/local/Cellar/wget/1.10
        make install
        brew ln wget
    

Or Homebrew can figure out the prefix:

    
    
        ./configure `brew diy`
        cmake . `brew diy`
    

Optimization

We optimize for (Snow) Leopard Intel, binaries are stripped, compile flags are
tuned to your exact Mac model. Slow software sucks.

Making the most of OS X

A touch of RubyCocoa, a cheeky sysctl query or two and a smattering of FSEvent
monitoring. In these manic days of cross-platform development, it's can be a
welcome relief to use something that is better because it isn't too
generalized.

No duplication

MacPorts is an autarky -- you get a duplicate copy of zlib, OpenSSL, Python,
etc. Homebrew uses what is already there, and consequently, most stuff has
zero dependencies and builds faster.

We resist packaging stuff that is already packaged. So we have a wiki page
that describes how best to use RubyGems, Pip (or easy_install) and CPAN with
OS X and Homebrew.

Fork with Git

The formula are all on git, so just fork to add new packages, or add extra
remotes to get packages from more exotic maintainers.

Surfing the cutting edge

If the package provides a git://, svn://, cvs:// or hg:// url you can choose
to install that instead and then update as often as you like.

~~~
stevenwei
"MacPorts is an autarky -- you get a duplicate copy of zlib, OpenSSL, Python,
etc. Homebrew uses what is already there, and consequently, most stuff has
zero dependencies and builds faster."

MacPorts made the decision to package and version their own versions of
everything for a reason. Conflicts can start to arise when you start compiling
against Apple's default shipped libraries for X11, Python, etc. Especially if
the default shipped versions don't provide what you need. E.g. the PHP install
that shipped with Snow Leopard is missing several notable extensions.

It might be safe to ignore these issues now but as the app grows they will
need to be addressed. (Or of course they can ignore it and just point to
MacPorts as an alternative for some subset of packages).

------
there
now all it needs is a gui. and the ability to buy commercial apps directly
through it. you could call it a sort of... application store, or "app store"
for short. people will love it!

------
tkahn6
_Managing software packages on Unix has always been, to put it politely, a
giant pain, and most Linux distributions are built around the different ways
we’ve all been trying to alleviate that pain_

Ubuntu (Debian) seems to do this very well in my opinion.

    
    
      sudo aptitude update; sudo aptitude upgrade
    

And with 9.10, to add a repository you can just do

    
    
      ppa:$repository
    

To add Wine for example,

    
    
      ppa:ubuntu-wine/ppa

~~~
brettnak
I actually came to OSX from Ubuntu and felt like I was in the dark ages
without a package manager. The first time I tried to compile PHP ( 5.3.2 ) on
an upgraded ( Leopard -> Snow Leopard ) machine, I had a million problems with
the system's iconv and had to recompile a million packages. I then had to
delete my iconv stuff, recompile it into /usr/local, then figure out exactly
which binary from the original install to leave behind so that things would be
detected properly with everything else. I think a lot of that has to do with
php's build and search paths ( eg, it was finding headers in /usr/local, but
trying to link to binaries in /usr ) but I can't help but feeling that with a
proper package manager, that never would have happened. Macports can be pretty
good, but I don't want to have to have so many things duplicated on my system.

EDIT: Grammar

------
klodolph
Gah. It looks like it doesn't support removing packages. I won't call it a
package manager if it can't remove packages.

~~~
emeryc
brew remove <formula>

~~~
stevelosh
I've been using homebrew for a few months now and while I love it I still
can't figure out how to 'brew remove' packages that have more than one version
installed.

For example:

$ brew remove git Error: git has multiple installed versions

I've looked at the (very sparse) 'brew help' and the wiki and still haven't
found a solution other than manually deleting the extra version directories.

Am I missing something obvious?

~~~
dhess
brew's documentation isn't fully baked, but this should do what you want:

    
    
      $ brew cleanup git
      Uninstalling /usr/local/Cellar/git/1.6.5.4...
      Uninstalling /usr/local/Cellar/git/1.6.5.7...
      Uninstalling /usr/local/Cellar/git/1.6.6...
    

Or just "brew cleanup" to clean everything. (That doesn't appear to work with
projects built from version control repos, though, like emacs with Cocoa
support.)

edit: Maybe you meant that you want to remove the whole thing, i.e., all
versions, not just the unused ones. Looks like you have to "cleanup" first,
then "remove". That seems like a bug to me.

