Skip to content
mxcl edited this page Sep 13, 2010 · 128 revisions

Terminology

Formula The package description /usr/local/Library/Formula/foo.rb
Keg The installation prefix of a Formula /usr/local/Cellar/foo/0.1
Cellar All kegs are installed in here /usr/local/Cellar

Basic Instructions

Formula we don’t accept

The mxcl fork doesn’t dupe stuff that comes with OS X or stuff that is provided by RubyGems, CPAN or PyPi. If you find such a dupe. It should be reported so that it can be removed (there are four exceptions: Ruby, Python, libxml2 and libpng).

We’re hoping other people will maintain forks that contain dupes. Currently AdamV is maintaining a duplicates branch.

Grab the URL

All you need to make a formula is a URL to the tarball.

brew create http://example.com/foo-0.1.tar.gz

This creates:

/usr/local/Library/Formula/foo.rb

And opens it in your $EDITOR. It’ll look like:

require 'formula'

class Foo <Formula
  url 'http://example.com/foo-0.1.tar.gz'
  homepage ''
  md5 ''

# depends_on 'cmake'

  def install
    system "./configure", "--prefix=#{prefix}", "--disable-debug", "--disable-dependency-tracking"
#   system "cmake . #{std_cmake_parameters}"
    system "make install"
  end
end

Fill in the Homepage

We don’t accept formula without homepages!

Homebrew doesn’t have a description field because the homepage is always up to date, and Homebrew is not. Thus it’s less maintenance for us. To satisfy the description we’re going to invent a new packaging microformat and persuade everyone to publish it on their homepage.

Fill in the MD5

 brew install -i foo

This downloads the formula and extracts it to a sandbox. Homebrew tells you the MD5 as it does this. Fill the formula in.

Check the build system

You’re now at new prompt with the tarball extracted to a temporary sandbox.

Check the package’s README. Does the package install with autotools, cmake or something else? Delete the commented out cmake lines if the package uses autotools (ie. it has a configure script).

Check for dependencies

The README probably tells you about dependencies. Homebrew or OS X probably already has them. You can check for Homebrew deps with brew search. These are the common deps that OS X comes with:

Freetype
libexpat
libGL
libiconv
libpcap
libpng
libxml2
Python
Ruby
X11

There are plenty of others. Check /usr/lib, /usr/X11/lib to see.

We try to never duplicate libraries and complicated tools. We dupe some common tools (eg scons). But generally we avoid dupes because it is a foundation of Homebrew, and because it causes build and usage problems.

We encourage you to maintain your own fork with dupes as you require them.

Specifying other formula as dependencies

class Foo < Formula
  depends_on 'jpeg'
end

Test the formula

Exit out of the interactive shell.

brew install -vd foo

The v is for verbose, the d debug. Debug mode dumps you to an interactive shell if the build fails so you can try to figure out what went wrong.

Submit to Homebrew

Everything is built on git, so contribution is easy:

brew install git
brew update  # required in more ways than you think
git add Library/Formula/foo.rb
git commit

Now you just need to push back to Github. If you haven’t forked Homebrew yet, then the easiest way to do that is with the github gem:

gem install github
github fork
git push myname master

Now create an issue so that one of the Homebrew collaborators can schedule a merge.

Overview of the Formula Install Process

  1. The result of Formula.download_strategy is instantiated.
  2. DownloadStrategy.fetch is called — eg. downloads tarball, checks out git repository, etc.
  3. A temporary sandbox is created in /tmp/homebrew
  4. DownloadStrategy.stage is called — eg. extracts tarball to above sandbox, exports git repository to sandbox, etc.
  5. Patches are applied
  6. Current directory is changed to the stage root (so when you system “Make”, it works)
  7. Formula.install is called
  8. Anything installed to the keg is cleaned (see later)
  9. The keg is symlinked into Homebrew’s prefix
  10. Caveats are displayed

Convenience Tools

bin.install(‘foo’)

You’ll see stuff like that in other formula. This installs the file foo into the Formula’s bin directory (`/usr/local/Cellar/pkg/0.1/bin`).

inreplace

A convenience function that can edit files in-place. Eg:

inreplace 'path', before, after

`before` and `after` can be strings or regexps. You can also use the block form:

inreplace 'path' do |contents| 
  contents.gsub! /foo/, 'bar'
end

Make sure you modify `contents` — this block ignores the returned value.

There are some special functions you can use inside the block that makes it easier to modify Makefiles:

inreplace 'Makefile' do |contents| 
  contents.remove_make_var! %w[CFLAGS LDFLAGS CC LD]
  contents.change_make_var! "CC", ENV.cc
end

Advanced Formula Tricks

If anything isn’t clear you can usually figure it out with some grep and the Library/Formula directory. Please amend this wiki page if you think it will help!

HEAD formula

HEAD formula have an alternate URL that users can choose with --HEAD. This URL points to trunk/master/HEAD. It will build the development cutting edge. Specifying it is easy:

class Foo < Formula
  head 'git://github.com/mxcl/lastfm-cocoa.git'
end

Homebrew understands git, svn, cvs and hg URLs.

Specifying the Download Strategy explicitly

Override the Formula::download_strategy function. Return the class type. Eg:

class Foo < Formula
  def download_strategy
    GitDownloadStrategy
  end
end

This can be useful when used with a local repo, where specifying a url would not let you specify how to access it. For example:

class Bar < Formula
  def download_strategy; GitDownloadStrategy; end
  head '/users/abc/src/git.git'
end

Clone this wiki locally