Tuesday, February 06, 2007

Compiling GD on Mac OS X HOWTO

1. Introduction and Prerequisites
2. Setting up the environment
3. Getting the archives
4. Unpacking the archives
5. Building zlib
6. Building libpng
7. Building libjpeg
8. Building freetype2
9. Building GD
10. Testing GD
11. Cleaning up
12. If anything fails…

1. Introduction and Prerequisites

This document explains (in the prescriptive, somewhat haughty tone characteristic of other HOWTOS) in a step-by-step fashion the procedure for compiling and installing GD 2.0.33 (the latest version as of 2006-01-19) from sources on Tiger (Mac OS X 10.4). However, this HOWTO also assumes a more-than-passing acquaintance with the Mac OS X Terminal application and the UNIX command line.

I am a tcsh user, and that is what these instructions assume you use as shell. If you are an irredent bash user, do not despair: when applicable, I have noted the differences. If any discrepancies remain, please tell me so that I can correct them.

Also, and this might seem obvious, it is imperative to have installed the Mac OS X Development Tools. It is an excellent idea to keep current with the latest, as available on Apple's ADC site. The instructions assume you have installed the XCode and the X11 SDK, as found on the XCode CD (the third one). If not, things that depend on X11's header files won't work (fontconfig support comes to mind.)

That said, I can't foresee every possible operating environment (and I'm certain to have overlooked some critical assumption or other.) I'm not able to test this procedure on any earlier version of Mac OS X, and I've not taken much care to avoid breakage. I apologize of any inconvenience. In any case, you might find helpful the previous version of this document.

The primary objective of this endeavor was to compile GD4O (GD for OCaml), which I did.

Many thanks to Brad Koehn, Jules, Felipe Wettstein, Scott Forbes, Christie P. Robertson, Ted Fines, Gerd Pleyer and Erik Anderson, whose helpful hints and comments contributed to make this HOWTO more correct.
2. Setting up the environment

First of all, make sure you have /usr/local/bin in your PATH. If you are using tcsh, this variable is slave to the path list variable. Add the following to your .cshrc, .tcshrc or, if you have it, ~/Library/init/tcsh/path:

set path = ( /usr/local/bin ${path} )

If you have bash, add the following to your .profile:

export PATH=/usr/local/bin:$PATH

Probably the easiest thing to do for the changes to take effect is to log out from your terminal session, and then back in. Alternatively, you may source the init script.
3. Getting the archives

Caveat: Whenever there is a choice of archive format (.tar.gz, .tar.bz, .zip), prefer .tar.gz for reasons of uniformity and coherence of the instructions. However, if you are confident in the process, feel free to use the format that you prefer, and be sure to modify the unpacking instructions as appropriate.

Download zlib 1.2.3, libpng 1.2.12 (do not download any later version, as GD 2.0.33 doesn't support it), libjpeg v6b, FreeType 2.1.10, and GD 2.0.33 (version numbers are verified as of 2006-09-25).

The official URLs for these libraries are:

zlib
http://www.gzip.org/zlib/
libpng
http://www.libpng.org/pub/png/libpng.html
libjpeg
ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz
freetype2
http://freetype.sourceforge.net/download.html
GD
http://www.boutell.com/gd/

I advise to locally compute and compare MD5 checksums, if the distribution home lists them. You do that by executing:

% md5 filename

4. Unpacking the archives

With all archives in the same directory (on the Desktop, for instance), do:

% ls *gz | xargs -n 1 tar zxvf

(I know, xargs is evil). If you downloaded any Bzipped archives, do:

% ls *.bz2 | xargs -n 1 tar jxvf

5. Building zlib

It's a simple matter of

% cd zlib-1.2.3; ./configure --shared && make && sudo make install

You may omit the --shared parameter if you don't care for shared libraries. If you do, you may test the build by executing ./example after installation.
6. Building libpng

Change into libpng's build directory, and copy the relevant Makefile:

% cd ../libpng-1.2.12
% cp scripts/makefile.darwin Makefile

The Makefile needs configuring to find zlib. You have to uncomment and recomment lines 14–17 to read:

# Where the zlib library and include files are located
ZLIBLIB=/usr/local/lib
ZLIBINC=/usr/local/include
#ZLIBLIB=../zlib
#ZLIBINC=../zlib

Now build and install:

% make && sudo make install

Finally, to test the build, you may execute:

% setenv srcdir .; ./test-pngtest.sh

(If you use bash, use instead export srcdir=.; ./test-pngtest.sh). You could have used configure instead to create the Makefile; however, the compiler options hardwired in makefile.darwin seem to be especially tuned.
7. Building libjpeg

As pointed out to me by a kind correspondent, Mac OS X 10.3 and later ship with GNU libtool, albeit under a slightly different name, glibtool. We need only link to it to build the dynamic version of libjpeg that GD4O needs to work. Change into the build directory:

% cd ../jpeg-6b/
% ln -s `which glibtool` ./libtool

Furthermore, on Mac OS X 10.4 (Tiger), the libtool needs to be specified the build environment. Enter:

% setenv MACOSX_DEPLOYMENT_TARGET 10.4

in tcsh, or:

$ export MACOSX_DEPLOYMENT_TARGET=10.4

in bash. Now configure with shared library support, then build and install:

% ./configure --enable-shared && make && sudo make install

configure will complain about ltconfig: cannot guess host type; you must specify one. An alternative to symlinking libtool is to copy its skeletal configuration defaults, as suggested by a correspondent (meaning, I haven't verified this):

cd ../jpeg-6b
cp /usr/share/libtool/config.sub .
cp /usr/share/libtool/config.guess .
./configure --enable-shared
make
sudo make install
sudo ranlib /usr/local/lib/libjpeg.a

8. Building freetype2

Enter freetype2's build directory:

% cd ../freetype-2.1.10

By default, freetype2's support for hinting TrueType fonts is disabled. US citizens using this library for commercial purposes might be liable for patent infringement by turning it back on; those of us to which US patents don't apply, or whomever may not care (I am not advocating infringement), edit the file include/freetype/config/ftoption.h and uncomment line 439 to read:

#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER

Proceed as before:

% ./configure && make && sudo make install

9. Building GD

First, if you have installed the X11 SDK, link fontconfig header files where GD can find them:

sudo ln -s /usr/X11R6/include/fontconfig /usr/local/include

(Beware of trailing slashes if using TAB autocompletion.)

A quick check might save you from much puzzlement later on: upon issuing a ls /usr/local/include/fontconfig/ (note the trailing slash), you should see:

fcfreetype.h fcprivate.h fontconfig.h

Now everything is in place. Go to GD's build directory, link in glibtool and configure:

% cd ../gd-2.0.33
% ./configure

Presently, configure should report that GD will support PNG, JPEG and FreeType:

** Configuration summary for gd 2.0.33:

Support for PNG library: yes
Support for JPEG library: yes
Support for Freetype 2.x library: yes
Support for Fontconfig library: yes
Support for Xpm library: yes
Support for pthreads: yes

If you don't see Freetype support, or if configure complained with a configure: WARNING: not found - disabling freetype support, you downloaded Freetype 2.2.1, which is not supported by GD. If you don't see Fontconfig support, you didn't linked correctly the fontconfig headers as indicated at the beginning of this section.

Finally, build and install:

% make && sudo make install

Nota bene: Apparently, configure insists on installing its own version of libtool, one that I suspect is not very au courant the Mac OS-on-Intel situation, and is possibly responsible for repeatedly-reported build failures on that platform. These are, as the alliteration might have alerted the astute reader, all speculations on my part; but I shan't blame you for trying. If you get an Undefined symbols error, make sure that the build process uses the version of glibtool supplied with Mac OS X: after configure does its magic, please delete libtool with rm ./libtool and then ln -s `which glibtool` ./libtool.
10. Testing GD

GD includes a battery of tests that can be run. A first, basic test, is:

% ./gdtest test/gdtest.png

(As noted in the test results, it is expected to fail on color images, and in particular, on the Windows Bitmap test.) Then, you will need a TrueType font that freetype2 can read: Windows or X-Windows .ttfs and Mac OS X .dfonts do nicely. If you don't find /Library/Fonts/Zapfino.dfont, get any one (I recommend Bitstream Vera) and copy it to your user's ~/Library/Fonts:

% ./gdtestft Zapfino.dfont

All files produced will reside in the test directory. You can view them with:

% open test/*.jpg

If fontconfig support is not available, with a little coercion GD can find fonts on its own. If in tcsh, type the following:

% setenv GDFONTPATH $HOME/Library/Fonts:/Library/Fonts:/System/Library/Fonts

In bash, type the following:

$ export GDFONTPATH=$HOME/Library/Fonts:/Library/Fonts:/System/Library/Fonts

(In any case, you might want to add the definition to your shell's init script.)
11. Cleaning up

Once you're satisfied with the results, you can proceed to clean up the build directories:

% cd ..
% rm -rf zlib-1.2.3/ libpng-1.2.12/ jpeg-6b/ freetype-2.1.10/ gd-2.0.33/

If you want to keep the .gz archives (I don't; the bandwidth incurred in downloading the archives is far less important to me than the disk space occupied), you may want to move them to your Public folder or wherever; otherwise, delete them:

% rm zlib-1.2.3.tar.gz libpng-1.2.12-config.tar.gz \
jpegsrc.v6b.tar.gz freetype-2.1.10.tar.gz \
gd-2.0.33.tar.gz

12. If anything fails…

As written, these instructions work in a clean installation of Mac OS X 10.4, updated to Mac OS X 10.4.7, with XCode 2.4. Many of the reported problems seem to be caused by GNU-Darwin, because of what it installs or the modifications it makes to the environment. If this HOWTO is your last resort after unfruitful attempts at installing GD for use with, for instance, PHP, your runtime environment is probably very polluted at this point.

I'd recommend ticking off the following checklist:

1. Review your environment variables

You can do it with setenv in tcsh, or export in bash. If you're having problems, the first thing to do is to set PATH to a sane value. I recommend having only:
* /usr/local/bin
* /usr/bin
* /bin
* /usr/local/sbin
* /usr/sbin
* /sbin

in the search path, at least until everything compiles fine. Remember to issue a rehash command whenever you modify the PATH variable in tcsh. Also, if DYLD_LIBRARY_PATH is set in Mac OS X 10.4, unset it and/or remove it from your startup scripts.
2. Review your startup scripts, and modify them accordingly, if need be (see §2).
3. Clean up /usr/local/{bin,lib,include} of any extraneous residues of previous essays. This will need care if you have compiled and installed any other programs that you might want to keep; if in doubt, abstain.

However, if you don't have already done that, or if you do not care, you needn't be subtle about this. Just:

% sudo rm -rf /usr/local/bin/* /usr/local/lib/* /usr/local/include/*

Of course, this be done at your own peril. I shan't be held liable.
4. Start anew compiling the failed module, by doing a make distclean (if that doesn't work, try make clean, or remove the source directory and unpack the archive again) and following the instructions for the module once more from the beginning.
5. Start afresh from §4, after cleaning up the build directories as per §11.

Good luck!

Author: Matías Giovannini
Last revision: 2006-09-25

No comments :