How to compile git under Mac OS X El Capitan

Posted on So 19 Juni 2016 in misc

Installing git on El Capitan is easy: brew install git and you’re set. If you want a fancier version, then activate some options brew gives you, e.g. brew install git --with-brewed-openssl --with-brewed-svn --with-gettext --with-pcre and brew will do its magic. But suppose you’d like to dig deeper and compile git yourself. If brew can do it, so can you, right?

First things first: let’s get the source code. Using the preinstalled git you can clone the repository from Github:

git clone https://github.com/git/git.git
cd git

You can also download a zipfile from Github – there’s not much of a difference.

Usually you should be able to compile everything by just typing make, but that would be too simple. Instead you’ll see the following error:

GIT_VERSION = 2.9.0
    * new build flags
    CC credential-store.o
In file included from credential-store.c:1:
In file included from ./cache.h:4:
./git-compat-util.h:280:10: fatal error: 'openssl/ssl.h' file not found
#include <openssl/ssl.h>
         ^
1 error generated.
make: *** [credential-store.o] Error 1

Problem: our C-Compiler doesn’t know where openssl/ssl.h is located.

Let’s install OpenSSL first using brew: brew install openssl. After the installation you’ll see additional information that will benefit us greatly:

This formula is keg-only, which means it was not symlinked into /usr/local.

Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/openssl/lib
    CPPFLAGS: -I/usr/local/opt/openssl/include

If OpenSSL is already installed on your system, you can see this by executing brew info openssl.

Let’s try compiling it again:

make CPPFLAGS=-I/usr/local/opt/openssl/include LDFLAGS=-L/usr/local/opt/openssl/lib

It should fail again with the following error:

    * new build flags
    CC credential-store.o
In file included from credential-store.c:1:
In file included from ./cache.h:8:
./gettext.h:17:11: fatal error: 'libintl.h' file not found
#       include <libintl.h>
                ^
1 error generated.
make: *** [credential-store.o] Error 1

We have to install gettext to get rid of this: brew install gettext. Again we’ll see some additional information:

This formula is keg-only, which means it was not symlinked into /usr/local.

OS X provides the BSD gettext library and some software gets confused if both
are in the library path.

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/gettext/lib
    CPPFLAGS: -I/usr/local/opt/gettext/include

And again we have to hand these information over to make so that it knows where to find these header files. But this process is getting a little tedious. There must be a better way. There is!

The key idea is this: you define two environment variables (one for the compiler, one for the linker) where they should look for header files and libraries. So in your ~/.bashrc or ~/.zshrc you’ll add the following lines:

export CPATH="/usr/local/opt/openssl/include:/usr/local/opt/gettext/include"
export LIBRARY_PATH="/usr/local/opt/openssl/lib:/usr/local/opt/gettext/lib"

and reload your rc-file with . ~/.bashrc or . ~/.zshrc.

One last thing before you can compile git easily: gettext comes with a little program called msgfmt which we need to compile git. When brew installed gettext it didn’t link msgfmt. It’s installed, but not in your $PATH. So let’s link the gettext programs:

brew link gettext --force

Now you should be able to compile git as advertised: just type make. After that you can check if it worked by executing this:

./git --version
git version 2.9.0