Rolling your own on Mac OS X Part I (would it be a MAMP?)
(A HOWTO on compiling and installing PHP, MySQL, Apache and associated support libraries on Mac OS X.)
- Introduction and Prerequisites
- Setting up the environment
- Getting the archives
- Unpacking the archives
- Building zlib
- Building Apache
- Considering extra modules for PHP5
- Building libiconv
- Building gettext
- Building readline
- Building libxml2
- Building cURL
- Preparing for compiling with GD support
- Building libpng
- Building libjpeg
- Building freetype2
- Building MySQL
- Building Bzip2
- Building PHP5
- Editing the Apache config file
- Testing your handy work
- Notes on configuration files
- Just time left over for some house keeping
I've spent most of my afternoon dealing with an unknown quantity (more accurately described as setting up a webserver on MAC OS X). Given that my experience with MACs is limited to a short term exposure some 8 years ago, I came to the conclusion that it may be prudent to take some notes on my afternoons activities.
This document represents my notes on the problems encountered and steps taken during the setup process, all rolled together to form a (sort of) HOWTO. This document also assumes that you have some experience of working with a UNIX style command line environment.
The MAC in question is one MAC G4 with a fresh clean install of MAC OS X Server v10.2.8, as my knowledge of MACs is extremely limited I cannot guarantee how much (if any) of my notes are relevant to any other versions of MAC OS X, but my notes are offered up here to serve as a help/reference to anyone else who may find themselves in a similar situation.
2. Setting up the environment
It may seem obvious but I thought it worthy of mention, it is imperative that you have installed the Mac OS X Development Tools. The package is available on Apple's ADC site, you have to register to get to the download section but it's free to do so and you won't get far without them.
Now, being new to MAC OS X myself, two things I noticed straight away were that:
- The root user appears to be disabled by default
- The default shell is an unknown quantity to me (I'm used to the bash shell).
So, first up, as I don't particularly want to be typing 'sudo' and be prompted for a password every five minutes, let's open up a terminal window and enable to root user:
Code: Select all
shell> sudo passwd rootYou can now logout, and then log back into a terminal session as root. So, about this shell, I'm sure I'll go back and investigate it at some point but certainly for the moment I wanted to make bash my default shell, all command line instructions within this document will assume you are using a bash shell, so let's make the switch:
Code: Select all
shell> niutil -createprop . /users/root shell /bin/bashFirst of all, make sure you have '/usr/local/bin' in your PATH add the following to your ~/.profile:
Code: Select all
shell> export PATH=/usr/local/bin:$PATH3. Getting the archives
Old habits die hard, I tend to download all source files into the /usr/local/src directory, a directory which doesn't exist by default on MAC OS X Server, so you may want to create that as I'll be referencing it more than once within this document.
Another old habit is that I always head straight for the .tar.gz format when downloading sources archives. There is no real reason for it but again
Download zlib 1.2.3, gettext 0.14.5, libiconv 1.9.2, readline 5, libxml2 2.6.22, PHP 5.0.5, cURL 7.14.1, MySQL 4.1.14, httpd 2.0.54 (Apache), Bzip2 1.0.3, libpng 1.2.8, libjpeg v6b and FreeType 2.1.10 (version numbers are as of 12-10-2005).
The official URLs for these libraries are:
- zlib -- http://www.gzip.org/zlib/
- gettext -- ftp://ftp.gnu.org/gnu/gettext/
- libiconv -- ftp://ftp.gnu.org/gnu/libiconv/
- readline -- ftp://ftp.gnu.org/gnu/readline/
- libxml2 -- ftp://ftp.gnome.org/pub/GNOME/sources/libxml2/
- PHP -- http://www.php.net/downloads.php
- Apache -- http://httpd.apache.org/download.cgi
- MySQL -- http://dev.mysql.com/downloads/
- cURL -- http://curl.haxx.se/download.html
- Bzip2 -- http://www.bzip.org/downloads.html
- libpng -- http://www.libpng.org/pub/png/libpng.html
- libjpeg (jpegsrc.v6b.tar.gz) -- ftp://ftp.uu.net/graphics/jpeg/
- freetype2 -- http://freetype.sourceforge.net/download.html
Code: Select all
shell> md5 'filename'With all archives in the same directory (preferably /usr/local/src), do:
Code: Select all
shell> ls *gz | xargs -n 1 tar -xzvfI thought I'd break myself in gently, as zlib builds on almost anything with no real problems it seemed a good place to start:
Code: Select all
shell> cd zlib-1.2.3
shell> ./configure --shared && make all install
shell> cd ..Apache is another relatively pain free source package to compile and slightly more exciting
A couple of points here, the default installation directory of Apache /usr/local/apache2 I prefer to build into a dedicated directory for each version and symlink it to /usr/local/apache.
Also, I have deliberately choosen not to attempt to build anywhere near the MAC OS X default installation of Apache for a few reasons
- I did not want to run the risk of a software update borking our own installation of apache.
- I did not want to run the risk that attempting to configure Apache through the MAC OS X GUI may break our config files
Code: Select all
shell> cd httpd-2.0.54
shell> ./configure --prefix=/usr/local/apache2.0.54 --enable-mods-shared=most --enable-deflate --with-z=/usr/local && make all installDon't forget the symlink and to change back up into the source directory:
Code: Select all
shell> ln -s /usr/local/apache{2.0.54,}
shell> cd ..Code: Select all
shell> /usr/local/apache/bin/apachectl startWe will be editing the Apache config file once all the build work has been completed, for the moment shutdown Apache and let's move on:
Code: Select all
shell> /usr/local/apache/bin/apachectl stopThe minimum requirement to building PHP5 is that you have libxml2 built and installed. However, there are many useful modules that can be compiled in to add to the many standard functions available to you from within PHP5. I'm certainly not going to be compiling with every concievable module included but I will be documenting the compiling of some of the more problematic (on MAC OS X at least) hopefully with this information it may help you to add in extra modules that you may require.
8. Building libiconv
For some odd reason, libiconv reports the wrong deployment target. This doesn't stop the build and infact I only noticed later when compiling PHP5 that it was complaining about it and subsequently not compiling the module. I got round that problem by defining the MACOSX_DEPLOYMENT_TARGET prior to configuring and building:
Code: Select all
shell> export MACOSX_DEPLOYMENT_TARGET=10.2
shell> cd libiconv-1.9.2
shell> ./configure && make all install
shell> cd ..gettext is another seemingly pain free compile, it's also a big old boy so may take some time:
Code: Select all
shell> cd gettext-0.14.5
shell> ./configure && make all install
shell> cd ..10. Building readline
readline required a small amount of 'hoop jumping' now is the time to crank up your text editor of choice and open the file './readline-5.0/support/shobj-conf' I'm using 'vi', if you are not using vi then you can ignore the next line:
Code: Select all
shell> vi readline-5.0/support/shobj-confCode: Select all
# Darwin/MacOS X
darwin*|macosx*)
SHOBJ_STATUS=unsupported
SHLIB_STATUS=supported
SHOBJ_CFLAGS='-fno-common'
SHOBJ_LD='${CC}'
SHLIB_LIBVERSION='$(SHLIB_MAJOR)$(SHLIB_MINOR).$(SHLIB_LIBSUFF)'
SHLIB_LIBSUFF='dylib'
case "${host_os}" in
darwin7*) SHOBJ_LDFLAGS=''
SHLIB_XLDFLAGS='-dynamiclib -arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
;;
*) SHOBJ_LDFLAGS='-dynamic'
SHLIB_XLDFLAGS='-arch_only `/usr/bin/arch` -install_name $(libdir)/$@ -current_version $(SHLIB_MAJOR)$(SHLIB_MINOR) -compatibility_version $(SHLIB_MAJOR) -v'
;;
esac
SHLIB_LIBS='-lncurses' # see if -lcurses works on MacOS X 10.1
;;Code: Select all
*) SHOBJ_LDFLAGS='-dynamic'Code: Select all
*) SHOBJ_LDFLAGS='-dynamiclib'Code: Select all
shell> cd readline-5.0
shell> ./configure && make all install
shell> cd ..A relatively straight forward one:
Code: Select all
shell> cd libxml2-2.6.22
shell> ./configure --with-zlib=/usr/local && make all install
shell> cd ..MAC OS X 10.2.8 already has cURL installed, but there is nothing wrong with bringing it up to date:
Code: Select all
shell> cd curl-7.14.1
shell> ./configure --with-ssl=/usr && make all install
shell> cd ..While access to the GD library on it's own comes in useful, the functionality of GD can be further enhanced by adding support for additional formats.
13.1 Building libpng (.png support)
Note: Despite what the INSTALL file suggests, there is no makefile.macosx, however, there is makefile.darwin.
Change into libpng's build directory, and copy the relevant Makefile:
Code: Select all
shell> cd libpng-1.2.8-config
shell> cp scripts/makefile.darwin MakefileCode: Select all
# Where the zlib library and include files are located
ZLIBLIB=/usr/local/lib
ZLIBINC=/usr/local/include
#ZLIBLIB=../zlib
#ZLIBINC=../zlibCode: Select all
shell> make all install
shell> cd ..13.2 Building libjpeg (.jpeg support)
A quick bit of symlinking required to build the dynamic version of libjpeg prior to compiling:
Code: Select all
shell> cd jpeg-6b/
shell> ln -s `which glibtool` ./libtoolCode: Select all
shell> ./configure --enable-shared && make all install
shell> cd ..13.3 Building freetype2 (TrueType font support)
Enter freetype2's build directory:
Code: Select all
shell> cd freetype-2.1.10Code: Select all
#define TT_CONFIG_OPTION_BYTECODE_INTERPRETERCode: Select all
shell> ./configure && make all install
shell> cd ..There are binary packages available for installing MySQL on MAC OS X. Although, from what I can gather they can throw up just as many problems as compiling your own (I'm guessing most of that is down to not reading the docs).
Also, all the binary packages I've seen so far are geared towards installing on top of the default MySQL installation that ships with MAC OS X or, if it's not doing that, it's attempting to install a (at least to me) rather starnge layout/structure.
This one is a bit more involved but all in all, if you read the docs it's pretty pain free.
In a similar vein to Apache, we will be installing MySQL into it's own discrete location and symlinking to /usr/local/mysql:
Code: Select all
shell> cd mysql-4.1.14
shell> ./configure --prefix=/usr/local/mysql4.1.14 --with-isam --without-docs --without-man --without-bench
shell> make all installCode: Select all
shell> ln -s /usr/local/mysql{4.1.14,}Code: Select all
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> cd /usr/local/mysql4.1.14
shell> bin/mysql_install_db --user=mysqlCode: Select all
shell> chown -R root .
shell> chown -R mysql var
shell> chgrp -R mysql .Code: Select all
shell> share/mysql/mysql.server startCode: Select all
shell> bin/mysqladmin -u root password 'new-password'Code: Select all
shell> share/mysql/mysql.server stop
shell> cd /usr/local/src/Last one before we actually get to build PHP5. MAC OS X 10.2.8 ships with Bzip2 but we also require the dynamic library in order to compile PHP5 with Bzip compression support
First, let's build the static libraries:
Code: Select all
shell> cd bzip2-1.0.3
shell> make all install PREFIX=/usr/localCode: Select all
# This Makefile builds a shared version of the library,
# libbz2.1.0.3.dylib, with install name libbz2.1.0.dylib,
# at least on MAC OS X 10.2.8 with gcc-3.1 (pre-release) it does.
SHELL=/bin/sh
CC=gcc
BIGFILES=-D_FILE_OFFSET_BITS=64
CFLAGS=-no-cpp-precomp -fpic -fPIC -Wall -Winline -O2 -fomit-frame-pointer -fno-strength-reduce
$(BIGFILES)
OBJS= blocksort.o \
huffman.o \
crctable.o \
randtable.o \
compress.o \
decompress.o \
bzlib.o
all: $(OBJS)
$(CC) -dynamiclib -install_name libbz2.1.0.dylib -o libbz2.1.0.3.dylib $
(OBJS)
$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.1.0.3.dylib
clean:
rm -f $(OBJS) bzip2.o libbz2.1.0.3.dylib libbz2.1.0.dylib bzip2-shared
blocksort.o: blocksort.c
$(CC) $(CFLAGS) -c blocksort.c
huffman.o: huffman.c
$(CC) $(CFLAGS) -c huffman.c
crctable.o: crctable.c
$(CC) $(CFLAGS) -c crctable.c
randtable.o: randtable.c
$(CC) $(CFLAGS) -c randtable.c
compress.o: compress.c
$(CC) $(CFLAGS) -c compress.c
decompress.o: decompress.c
$(CC) $(CFLAGS) -c decompress.c
bzlib.o: bzlib.c
$(CC) $(CFLAGS) -c bzlib.cNow it's a simple case of building the dynamic library:
Code: Select all
shell> make -f Makefile-libbz2_dylibCode: Select all
shell> install -m 644 libbz2.1.0.3.dylib /usr/local/lib
shell> ln -s /usr/local/lib/libbz2.1.0{.3,}.dylib
shell> ranlib /usr/local/lib/libbz2.a
shell> cd ..16. Building PHP5
We are now ready to build PHP5 again we will be building into a discrete directory and symlinking to /usr/local/php:
Code: Select all
shell> cd php-5.0.5
shell> ./configure --prefix=/usr/local/php5.0.5 --with-mysql=/usr/local/mysql \
--with-mysqli=/usr/local/mysql/bin/mysql_config --with-zlib --with-openssl \
--with-ncurses=/usr --with-gettext=/usr/local --with-iconv=/usr/local \
--with-iconv-dir=/usr/local --with-readline=/usr/local --with-curl=/usr/local \
--with-bz2=/usr/local --with-apxs2=/usr/local/apache/bin/apxs \
--enable-exif --enable-mbstring --enable-ftp --with-gd --with-png-dir=/usr/local \
--with-jpeg-dir=/usr/local --with-freetype-dir=/usr/local --without-pear
shell> make all installCode: Select all
shell> cp php.ini-recommended /usr/local/php5.0.5/lib/php.iniCode: Select all
shell> ln -s /usr/local/php{5.0.5,}With everything now built, we need to edit the Apache config file to include PHP support and also to enable output compression that we compiled into Apache with mod_deflate
So, grab your favourite text editor and open the file '/usr/local/apache/conf/httpd.conf'
As you scroll down through the file, it's always good to give it a quick sanity check, especially double cheking that the required modules are being loaded. The first section that you'll come across that may require editing is the LoadModule section. In particular, check that mod_deflate and the PHP5 modules are loaded, you should see three lines which look like this:
Code: Select all
LoadModule deflate_module modules/mod_deflate.soCode: Select all
LoadModule headers_module modules/mod_headers.soCode: Select all
LoadModule php5_module modules/libphp5.soAs you scroll further down, you will also see lines for ServerAdmin and ServerName. ServerAdmin should be self explanatory, if you don't know or don't have a ServerName then you should use 127.0.0.1:80
The next line we are looking is:
Code: Select all
DirectoryIndex index.html index.html.varCode: Select all
DirectoryIndex index.html index.html.var index.phpNext, scroll right to the end of the file and add the following to enable Apache's output compression:
Code: Select all
<Location />
<IfModule mod_deflate.c>
# compress all html, text and css content
AddOutputFilterByType DEFLATE text/html text/plain text/css
# handle old browsers that do not support compression
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
<IfModule mod_headers.c>
# handle request coming via proxy
Header append Vary User-Agent
</IfModule>
</IfModule>
</Location>Code: Select all
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps18. Testing your handy work
Everything is built and we have basic configuration files in place, all that's left to do is to run a quick test.
Much as I'm tempted to run the time honured traditional 'Hello World!' test, I think I'll refrain. Something a bit more appropriate is to display our PHP configuration within a web browser.
Turning to your text editor, open a new file and place the following line within:
Code: Select all
<?php phpinfo() ?>All that remains is to start the Apache web server:
Code: Select all
shell> /usr/local/apache/bin/apachectl startYou can obviously now go on and test some more, remember to start your MySQL server before trying out any database testing.
19. Notes on configuration files
The configuration that we have setup should be regarded as nothing more than basic, there are some configuration options which have not as yet been set. Most notably PHP's temp directory, upload directory and session save path.
Also, the packages we have just built, have a vast array of configuration options which is far out with the scope of this document, some of these options can lead to reduced security of your server. All of the packages come with either a README or INSTALL file, I strongly recommend that you take some time to view these documents.
A short description and overview of options for most of the packages can be viewed by typing:
Code: Select all
shell> ./configure --helpWhile the objective of this document is to provide you a step by step guide to building a web server, it should not be regarded as a guide to building a production class server. In other words, it's up to you to ensure that your server is secured and risk of hacking is minimised.
20. Just time left over for some house keeping
If you want to keep the source archives, you may want to move them to another directory for safe keeping; otherwise, delete them:
Code: Select all
shell> rm /usr/local/src/*.gzCode: Select all
shell> make clean