
Document history | ||
---|---|---|
v 1.0-1 | JUN 2006 |
|
v 1.1-1 | JUL 2006 |
|
v 1.2-1 | SEP 2006 |
|
v 1.4-4 | SEP 2006 |
|
v 1.4-5 | OCT 2006 |
|
v 1.4-9 | NOV 2006 |
|
v 1.5-0 | FEB 2008 |
|
v 1.5-1 | DEC 2008 |
|
v 1.6-1 | JAN 2009 |
|
v 1.6-2 | MAR 2009 |
|
v 1.7-0 | APR 2009 |
|
1 - Introduction
This document details how to compile a full-featured Apache/PHP distribution.
The main difference with other tutorials you may find on the web is that this document not only explains how to compile Apache and PHP, but also every library they depend on.
This is a 'black-box' approach, where the software comes with everything it needs to run. It is longer and more complex to build such a package but, once it is done, it brings a lot of benefits, such as an independance between your software package and the libraries that may be already installed on the target host. Such a 'self-contained' approach makes it easier to build and deploy functionaly-identical packages on several different platforms/OS. Of course, the software still uses the low-level system libraries, but the dependencies are limited to the bare minimum, minimizing the risk of inconsistent behaviors between different hosts/platforms.
To complement this 'black-box' approach, we install the software in a private directory. This makes the package much simpler to manage, deploy , upgrade, or remove (compared to the traditional method of installing everything under /usr/local/[bin|lib|...]).
Actually, we don't include everything needed by the package, as we only include everything we can compile. The exceptions are the Oracle client library and the JAVA JRE, which are considered as 'external dependencies' and accessed through symbolic links (so that they can be physically located anywhere on the target host).
1.1 - Intended audience
This document can be used in two different ways :
- In order to apply the procedure and build the software exactly as it is
described here, you don't need to be an expert : it just requires some basic
Unix and shell knowledge, such as being able to download the source
packages, uncompress/untar them, and create files with a text editor.
At this level, the procedure given below can be splitted in two main steps :- you first set a limited number of environment variables (essentially the installation directory)
- and the rest is just a suite of copy/paste operations from the document to your shell environment.
- Now, if you want to understand everything that is explained below, or if
you want to adapt it to your specific needs, it requires of course more
knowledge on different domains, mostly :
- build mechanisms in general,
- compile and link operations (with a strong focus on shared libraries),
- makefiles,
- the Gnu autoconf-based configure/make process,
- and even, when it is really needed, the ability to understand and adapt some C source code.
So, to resume, most people will just apply the procedure described below, which is relatively easy and just requires a basic working knowledge of the Unix shell environment.
Don't hesitate to post comments on issues you may have with this
document. Each time you do it, you help me and the community in general to make
the procedure more robust and reliable. I promise to reply to every question
asked in comments. Please prefer comments to direct mail as they may benefit
others.
1.2 - Getting the source packages
Some readers sometimes ask why I don't provide copies of the source packages I list below. Sure, it would be easier for you, but I won't do it as you MUST get your source packages from a repository you can trust ! You don't know me, you CANNOT trust source code downloaded from my site (except for my own projects).
So, once again, always get your software from a trusted source and, when a package signature is provided, check it to make sure you get the official code.
I insist on this because compiling some modified source code or installing some corrupted precompiled binaries would give hackers everything they need to take control on your site (remember that most software we compile here runs as root).
In every chapter below, you will find a link to the best place to get the source package from.
So, remain a good, slightly paranoid, system administrator, and everything will go well.
1.3 - Modules & extensions
We are building Apache 2.0, PHP 4, and PHP 5 with the following modules and extensions :
- Apache modules :
These Apache modules are all compiled as
shared
objects (DSOs).
- PHP 4 extensions :
- PHP 5 extensions :
We also include the mm session handler support in PHP 4 & 5 (to be activated via the 'session_handler=mm' directive in php.ini)
1.4 - Software dependencies
The following diagrams display the dependencies between the software packages and libraries we are integrating together (split as two diagrams for clarity) :
Note that we use the GD bundled library provided in the PHP source packages (4 &
5).
The package also includes the tools you need to build
additional PHP extensions from the PECL library (http://pecl.php.net).
Although these tools (autoconf & m4) are available in every Linux
distribution, it is not the case
on older/traditional/proprietary Unix. In order to remain consistent for every OS we support
in this set of documents, the package includes an embedded version of m4 and autoconf.
The phpize scripts are also modified to use this version.
1.5 - Notational conventions
Everything written in black on grey can be copy/pasted without any modification.
Everything written in red and between '<' and '>' symbols must be replaced by a value corresponding to your environment.
Example : when you read this :
dir=<$BASE> |
you must replace <$BASE> with your base directory path in the line you will actually type.
but, when you read this :
dir=$BASE |
you copy and paste it asis into your environment.
Everything related to Oracle is printed in green and can be safely ignored if you don't need Oracle connectivity.
1.6 - Context
Host model : | VMWare virtual host (on a Dell R900) |
OS : | Linux 2.6.18-92.el5 |
Hardware platform : | i386 (32 bits) |
RedHat release : | Red Hat Enterprise Linux Server release 5.2 (Tikanga) |
Shell : | /bin/bash |
1.7 - Pre-requisite
These products are mandatory but the versions are not. They are just the versions I
used, so they are known to work.
Product | Version |
---|---|
gcc (C & C++) | 4.1.2-42.el5 |
glibc, glibc-devel, glibc-headers | 2.5-24 |
Gettext | 0.14.6-4.el5 |
Flex | 2.5.4a-41.fc6 |
GNU make | 3.81-3.el5 |
pam-devel | 0.99.6.2-3.27.el5 |
JDK | 1.6.0_03-fcs |
rpm-build | 4.4.2-48.el5 |
Oracle client | 10.2.0.4 |
2 - Building
2.1 - Environment
First, we define the install (target) base directory :
export BASE=<your install directory> |
We ensure that the LIBPATH, LD_LIBRARY_PATH, and SHLIB_PATH variables are unset. Only one of them applies to this system but it is simpler to unset them all on every OS :
unset LIBPATH LD_LIBRARY_PATH SHLIB_PATH || : |
If the shell environment contains aliases for cp, rm, or mv, it is time to unalias them :
unalias cp rm mv 2>/dev/null || : |
Then, we set the variables we use for every software and on every OS. Among others, we ensure that /usr/local/bin is in the PATH :
export BLIB=$BASE/libs |
C compilers can have such different behaviors that I strongly recommend
using gcc. If you are using another compiler, please don't ask for support.
Now, we set the 'make' commands we'll use in the rest of the document. The difference between $MK and $SMK is that, in $MK, you can add options for a 'parallel make' ('-j', '-l', ...). $SMK stands for 'serial make' and is used where parallel builds are known to fail.
Mileage varies concerning parallel make. Depending on your host characteristics and the options you set, the build can be faster or slower. Personnally, after trying several options, I did not observe a noticeable gain in performance and reverted to the default 'serial' make.
Please note that parallel make can
cause compilation failures. So, if you get unexpected results
while parallel make options are active, the first thing to do is to retry the same
without the parallel options. For more info about parallel make, see the
GNU make manual.
GNU make is mandatory as several packages absolutely require it. On
Linux, GNU make is native but, on non-Linux systems, you are strongly advised
not to use the native make.
export MAKE='gmake' |
We also un-localize the shell environment :
unset LANG LC_MONETARY LC_TIME LC_MESSAGES LC_CTYPE \ |
We now set the variables specific to this operating system :
export LDFLAGS="-L$BLIB/common/lib -Wl,-rpath -Wl,$BLIB/common/lib" |
We define the Oracle installation directory :
export ORACLE_HOME=<your
Oracle home> |
We define where the JDK is installed :
export JAVA_HOME=<your Java home> |
We now set the environment specific to this software :
export BAP=$BASE/apache |
2.2 - Creating the target structure
Every libraries and auxiliary software are installed under '$BASE/libs'. There, each software/library is assigned a subdirectory, and we populate a 'common' subdirectory with symbolic links to the actual file locations. Using a common directory populated with symbolic links brings several benefits :
- it allows to set a single path in the dynamic lib search path (LDFLAGS).
- it also allows to set a single path in the include file search path (CPPFLAGS)
- Putting a common 'bin' subdirectory as first element of the PATH ensures that anything we put in this directory will be found first when searching for an executable command.
- Last, it allows to set a single path in the PKG_CONFIG_PATH variable.
Thanks to this directory structure, we don't have to modify the environment variables each time we add a library to the package. It becomes also easier to ensure that the compilation will reference our embedded library/include files, and not the ones that can be installed elsewhere in the system.
First, we create the base common directory.
mkdir -p $BLIB/common |
Then, we create the script to populate the common directories. Every time we build and install a library we need to reference in a subsequent build, we call this script to register the files in the common structure. This is done through the $LINKDIR environment variable.
Note that the
link creation script is not in the common PATH. This way, it cannot conflict
with another file.
#-- Declare the variable we use to
call the script |
#-- Create the script |
2.3 - External dependencies
We use symbolic links for the external dependencies (Oracle & Java). This way, the package can easily run on a target host where Oracle and/or Java are installed in different locations. On the target host, we just need to create two symbolic links at the same locations and the Oracle and Java dependencies will be resolved through them.
I clearly prefer this solution to the ones based on the LD_LIBRARY_PATH/SHLIB_PATH/LIBPATH
environment variables.
This is consistent with the 'black-box' philosophy described above, as I
consider that I cannot
really control the environment my software will run in.
2.3.1 - Oracle
As explained above, we create a symbolic link from $BLIB/oracle_home to the Oracle install directory.
We also create a second indirection level because the Oracle library hardware path is recorded with the version suffix (libclntsh.so.9.0, libclntsh.so.10.1,...). So, at runtime, the software expects the same library version it was compiled with. As we want to be able to run with any Oracle library, even if it is not the one we used at compile time, we need to create a redirection from this 'versioned' library file to the actual 'not-versioned' file.
ln -s
$ORACLE_HOME $BLIB/oracle_home
#-- Redirect from versioned lib to non-versioned one
_pwd=`pwd`
cd $BLIB/oracle_home
for _f in `echo lib*/libclntsh.so.*`
do
_d=`dirname $_f`
mkdir -p $BLIB/oracle/$_d
rm -f $BLIB/oracle/$_d/libclntsh.so
ln -s ./`basename $_f`
$BLIB/oracle/$_d/libclntsh.so
ln -s ../../oracle_home/$_d/libclntsh.so $BLIB/oracle/$_f
done
#-- we also need the header files, but just for compiling
for _d in precomp rdbms
do
ln -s ../oracle_home/$_d $BLIB/oracle/$_d
done
cd $_pwd
#-- Modify ORACLE_HOME for compile time
export ORACLE_HOME=$BLIB/oracle Note that the package is
never guaranteed to run with an Oracle client of a version different than the
one it was compiled with. For instance, if you compile with an Oracle 10
library, it won't run with an Oracle 9 version (because of a symbol added in
version 10). When it is possible, the best solution is always to compile and run
a software with the same library versions.
2.3.2 - Java
The external Java SDK will be accessed through a symbolic link.
ln -s $JAVA_HOME $BLIB/java_home |
At
runtime, we just need a Java Runtime Environment, not the whole JDK.
2.4 - Compiling zlib (1.2.3)
Source : http://www.zlib.net/
The zlib library provides the gzip (GNU zip) compression/decompression features.
./configure --shared --prefix=$BLIB/z |
2.5 - Compiling the OpenSSL library (0.9.8j)
Source : http://www.openssl.org/source/
Web site : http://www.openssl.org/
The OpenSSL library provides the mechanisms to establish SSL-secured connections. It is used by Apache to handle HTTPS connections, by PHP to provide SSL features, and also by OpenLDAP, curl, MySql and PostgreSql.
As the configuration process ignores the LDFLAGS environment
variable, we modify several variables related to the way
the libraries will be linked.
./config --openssldir=$BLIB/ssl shared zlib no-krb5 |
2.6 - Compiling the OpenLDAP library (2.4.11 - 20080813)
Source : http://www.openldap.org/software/download/
Web site : http://www.openldap.org/
We only compile the LDAP client, excluding the server and the replication daemon. Then, we keep the library and include files only.
./configure --prefix=$BLIB/ldap --without-cyrus-sasl \ |
2.7 - Compiling the expat library (2.0.1)
Source : http://sourceforge.net/project/showfiles.php?group_id=10127
Web site : http://expat.sourceforge.net/
./configure --prefix=$BLIB/expat $CF_OPTS |
2.8 - Compiling the iconv library (1.12)
Source : ftp://ftp.gnu.org/gnu/libiconv
Web site : http://www.gnu.org/software/libiconv/
./configure --prefix=$BLIB/iconv
\ |
2.9 - Compiling the Berkeley DB library (4.7.25)
Source : http://www.oracle.com/technology/software/products/berkeley-db/index.html
The TCL stuff is useless here. So, we don't compile it.
cd build_unix |
2.10 - Compiling Apache (2.0.63)
Source : http://httpd.apache.org/
As our LDAP library is not in the standard location, we need to build and install the apr and apr-util libraries first, splitting the compile process in 3 steps.
We also modifiy the apr-config script because we want apxs to link with the hardcoded library search path.
Fix : if the host contains an older version of the zlib headers in /usr/include, it may contain a file named zutil.h. In this case, the Apache configure phase wrongly states that it can include this file. But, this header file is incompatible with the version of zlib embedded in the package, and the compilation fails. In order to force this header file not to be used, we un-define the corresponding symbol in the auto-generated Apache header file.
#-- Build apr |
2.11 - Compiling the bzip2 library (1.0.1)
Source : http://www.digistar.com/bzip2/
As the current makefile ignores our LDFLAGS settings, we link the shared library with our own command.
We also must install the files ourselves as the Makefile is unable to do it.
$MK -f Makefile-libbz2_so |
2.12 - Compiling managelogs (1.0.1)
Source : http://managelogs.tekwire.net
managelogs is a log processing program to be used in conjunction with Apache's piped logfile feature. It automatically rotates and purges log files based on a set of user-defined options.
This is a software I wrote as an alternative to rotatelogs, as rotatelogs is not able to purge the log files and, typically, must be complemented with cron jobs to avoid filling up the file system.
$MK "APACHE=$BAP"
"ZLIB=$BLIB/z" "BZ2LIB=$BLIB/bz2" install install-man |
2.13 - Compiling mod_jk (tomcat-connectors 1.2.27)
Source : http://tomcat.apache.org/download-connectors.cgi
Web site : http://tomcat.apache.org/connectors-doc/
The configure script prepends a '-Wl,' prefix to every elements of '$LDFLAGS' that don't already start with this string. This is correct except for the '-L' option, as it prevents the libgcc_s library to be located in $BLIB/common/lib. To fix this problem, after the configure phase, we reset the '-L' option where it has been modified.
cd native |
2.14 - Compiling the xml2 library (2.7.2)
Source : http://xmlsoft.org/
./configure --prefix=$BLIB/xml2 \ |
2.15 - Compiling the pcre library (7.8)
Source : http://www.pcre.org/
./configure --prefix=$BLIB/pcre --disable-cpp $CF_OPTS |
2.16 - Compiling mod_evasive (1.10.1)
Source : http://www.zdziarski.com/projects/mod_evasive/
$BAP/bin/apxs -c -i -A mod_evasive20.c |
In this configuration, mod_evasive is inactive. To activate it,
uncomment the corresponding LoadModule line in httpd.conf.
2.17 - Compiling mod_auth_cas (1.0.8)
Web site : http://www.ja-sig.org/wiki/display/CASC/mod_auth_cas
Source : https://www.ja-sig.org/svn/cas-clients/mod_auth_cas/tags/mod_auth_cas-1.0.8/src/
mod_auth_cas allows to authenticate against a CAS (Central Authentication Service) server. This module is not the only way for an application to authenticate users against a CAS server, but it is probably one of the easiest to use, as it transparently redirects the requests, silently validates tickets, and automatically provides an authenticated '$REMOTE_USER' to the application.
From the source directory given above, download the mod_auth_cas.c and mod_auth_cas.h files.
Then, compile it through apxs :
$BAP/bin/apxs -c -i -A mod_auth_cas.c |
In this configuration, mod_auth_cas is inactive. To activate it,
uncomment the corresponding LoadModule line in httpd.conf.
2.18 - Compiling the xslt library (1.1.24)
Source : http://xmlsoft.org/XSLT/
./configure --prefix=$BLIB/xslt \ |
2.19 - Compiling the png library (1.2.33)
Source : http://sourceforge.net/project/showfiles.php?group_id=5624
Web site : http://www.libpng.org/pub/png/
./configure --prefix=$BLIB/png $CF_OPTS |
2.20 - Compiling the jpeg library (v6b)
Source : http://www.ijg.org/files/jpegsrc.v6b.tar.gz
Web site : http://www.ijg.org
The 'make install' process is unable to create the
directories where the files must be installed. So, we create them by ourselves
before installing.
./configure --prefix=$BLIB/jpeg $CF_OPTS |
2.21 - Compiling the freetype library (2.3.7)
Source : http://www.freetype.org/index2.html
The freetype compile process wrongly states that gcc needs a '-ansi' option to compile in ansi mode. This option is not needed, and it even causes the compilation to fail in several environments (at least HP-UX 11.00 and AIX). So, we remove this option from the compile string.
#-- Build process
needs GNU make (and a GNUMAKE variable) |
2.22 - Compiling the SSH2 library (1.0)
Source : http://sourceforge.net/projects/libssh2/
./configure --prefix=$BLIB/ssh2 \ |
2.23 - Compiling the Curl library (7.19.2)
Source : http://curl.haxx.se/download.html
Web site : http://curl.haxx.se/
Our CURL client will support the following protocols and options : http, https, tftp, ftp, ftps, telnet, dict, ldap, ldaps, file, and gzip compression. It is also able to connect through a proxy.
CPPFLAGS="$CPPFLAGS -I
$BLIB/ldap/include" \ |
When curl needs to validate a certificate, it will use the content of the $BLIB/curl/share/ca-bundle.crt file. By default, the file does not exist, and the certificate chain is considered as empty. This file can be created and filled with the CA certificates you want curl to consider as trusted (in PEM format).
#-- Fait pointer le CA bundle de curl vers les
certificats RATP |
2.24 - Compiling modsecurity (2.5.7)
Source : https://bsn.breach.com/downloads/
Web site : http://www.modsecurity.org/
You need to register (free) to access the download area of the Breach
security labs site. Once you get there, the source package you need is
named modsecurity-apache_x.x.x.tar.gz. You don't need to dowload the
'modsecurity-core-rules' file, as the rules are already included in the
source package.
cd apache2 |
Now, we install the default rules and update the apache configuration :
#-- Install default configuration |
In this configuration, modsecurity is inactive. To activate it, uncomment the
'LoadModule security2...' line.
2.25 - Compiling the ncurses library (5.7)
Source : http://www.gnu.org/software/ncurses/
We force the Makefiles to link through gcc, instead of calling
ld directly, because we want our LDFLAGS to be used and it may
contain options which are not supported by ld (as the options starting with
-Wl).
./configure
--prefix=$BLIB/ncurses\ |
2.26 - Compiling gettext (0.17)
Source : ftp://ftp.gnu.org/gnu/gettext/
Web site : http://www.gnu.org/software/gettext/gettext.html
The '-with-included-gettext' configure option forces to build and use the included libintl library, even if one is present in the system libraries. This removes a dependency to the system libraries and ensures that we use the same libintl code across all platforms.
Note that, even if we try to disable NLS localization everywhere it is
possible, some software don't allow it to be disabled. That's why we still need
to embed a libintl library.
./configure
--prefix=$BLIB/gettext $CF_OPTS \ |
2.27 - Compiling the Subversion modules (1.5.4)
Source : http://subversion.tigris.org/downloads/subversion-1.5.4.tar.gz
Web site : http://subversion.tigris.org/
The Apache modules we build here allow to use Apache as a gateway to access a Subversion repository. You will find more information about configuring Apache as a Subversion gateway in this document.
Subversion requires the apr-util Apache library to be compiled with
the Berkeley DB.
We need to tell configure how to find the required libraries at link time (by initializing the LIBS variable). If we don't, the configure phase fails when the libintl (gettext) library is not installed in /usr/lib. This is probably a bug in the configure script. Because of this problem, we also need to add '-lintl' to the list of libraries we link with.
LIBS="$LDFLAGS" \ |
2.28 - Compiling the readline library (6.0)
Web site : http://tiswww.case.edu/php/chet/readline/rltop.html
The default Makefile renames the object files with a '.so' suffix instead of the usual '.o'. Some OS (like AIX) cannot link files ending with '.so'. So, we modify the Makefile in shlib to keep the '.o' suffix.
We also need to force the commands used to link the shared libraries, as the Makefile uses ld by default, and we can have some gcc-specific options in CPPFLAGS/LDFLAGS. So, we force it to link using 'gcc -shared'.
cd
shlib |
2.29 - Compiling libgpg-error (1.6)
Source : http://gnupg.org/download/index.en.html
./configure --prefix=$BLIB/gpg-error \ |
2.30 - Compiling the libgcrypt library (1.4.4)
Web site : http://www.gnu.org/software/libgcrypt/
./configure --prefix=$BLIB/gcrypt \ |
2.31 - Compiling the GnuTLS library (2.6.4)
Web site : http://www.gnu.org/software/gnutls/
We don't compile the C++ library as we don't need it and it
creates an unnecessary dependency on the libstdc++ library.
The installation fails (on AIX) with an 'Arg list too long' message when trying to install in the 'doc' subdirectory. As we don't need to build nor install the documentation, the easiest solution is to remove the 'doc' subdirectory from the list of subdirectories in the Makefile :
cp Makefile.in Makefile.in.orig |
./configure --prefix=$BLIB/gnutls \ |
Once the library is built and installed, we can run the tests :
[ -z "$NO_TEST" ] && $SMK check |
2.32 - Compiling the GnuTLS Apache module (0.4.3)
Web site : http://www.outoforder.cc/projects/apache/mod_gnutls/
The GnuTLS module is an alternative to mod_ssl. In addition to the features provided by mod_ssl, it provides several interesting additions like :
- Support for SSL 3.0, TLS 1.0 and TLS 1.1
- Support for RFC 5081 (OpenPGP certificate authentication)
- Support for RFC 5054 (SRP authentication)
- Support for Server Name Indication (allows several HTTPS virtual hosts on the same IP, which is impossible with mod_ssl)
- Distributed SSL Session Cache via Memcached
Note that mod_gnutls and mod_ssl can both be loaded on an Apache server
together but cannot be activated in the same virtual host.
./configure \ |
At this point, the gnutls module is inactive. To activate it,
add the following line to $BASE/apache/conf/httpd.conf :
LoadModule gnutls_module modules/mod_gnutls.so |
For more information on GnuTLS :
2.33 - Compiling the IMAP library (2007d)
Source : ftp://ftp.cac.washington.edu/imap/imap.tar.gz
Web site : http://www.imap.org
The IMAP distribution does not provide a way to build a shared client library.
So, we do it our way : we build the static library first, with the '-fPIC'
compile flag to generate relocatable objects, and, then, we build the shared
library from these objects.
We need a libc-client.a file in
$BLIB/imap/lib because the PHP configure process specifically tests for the
presence of this file. But we don't really need the static library as we'll only use
the dynamic one. So, we create $BLIB/imap/lib/libc-client.a as a symbolic link
to the dynamic library.
#-- Modify the Makefiles for SSL location |
2.34 - Compiling the MySQL client library (5.0.67)
Source : http://www.mysql.com/
CXX=gcc \ |
2.35 - Compiling the PostgreSQL client library (8.3.5)
Source : http://www.postgresql.org/ftp/source/
Web site : http://www.postgresql.org/
The configure process does not use CPPFLAGS and LDFLAGS correctly (the problem only appears when the libraries are not installed in the usual locations). As a workaround, we feed it with modified values for some other environment variables.
LDFLAGS_SL="$LDFLAGS" \ |
2.36 - Compiling mm (1.4.2)
Source : http://www.ossp.org/pkg/lib/mm/
mm's Makefile does not use the LDFLAGS variable, but we need this flag
to be set in the link command, to specify an hardware library search path. Bug
reported as Feature
request #122, supposed to be fixed in version 1.4.2 but the fix doesn't work
as it assumes that libtool automatically includes the content of the $LDFLAGS
variable, which is not the case. So, we still need to patch the Makefile.in file
manually before compiling.
#-- Insert '$(LDFLAGS)' in the link command |
2.37 - Compiling m4 (1.4.12)
Source : http://ftp.gnu.org/gnu/m4/
./configure --prefix=$BLIB/m4 $CF_OPTS |
2.38 - Compiling GNU awk (3.1.6)
Web site : http://www.gnu.org/software/gawk/
GNU awk is needed on HP-UX because, on this system, the default awk command does not support more than 3,000 bytes per line. It may seem much but, during its compile phase, bison needs more ! So, we need to replace awk with gawk which has no limitation on the line length.
This is really needed on HP-UX only but, in order to remain consistent on the different OS we are building on, we use gawk on every OS.
./configure --prefix=$BLIB/gawk $CF_OPTS \ |
2.39 - Compiling bison (2.4.1)
Web site : http://www.gnu.org/software/bison/
./configure --prefix=$BLIB/bison \ |
2.40 - Compiling the mcrypt library (2.5.8)
Web site : http://mcrypt.sourceforge.net/
Source : http://sourceforge.net/project/showfiles.php?group_id=87941
Download the Libmcrypt package, not Mcrypt, as we just need the library.
We also need to define two replacement malloc()/realloc() functions. If we don't define them, the resulting libraries cannot be loaded on environments (like AIX) which don't provide 'GNU compatible' allocation functions. Actually, the configure tests for these functions to be 'GNU compatible'. When they are determined not to be compatible, every call to malloc()/realloc() is replaced by a call to rpl_malloc()/rpl_realloc() and the package is supposed to define these two functions. Unfortunately, mcrypt does not provide these functions. So, on systems lacking 'GNU compatible' allocation routines, when you try to load the mcrypt shared library, the load fails with an 'unresolved symbol' error.
To work around this issue, we define both 'GNU compatible' functions at the end of one of the mcrypt source files, so that they are compiled and included in the library.
The 'GNU compatibility' of allocation functions is defined by
the fact that they return a valid pointer, even when given null input arguments.
So, we wrap these features around the usual allocation routines :
cat >>lib/xmemory.c <<EOF |
Then, we build the usual way.
We disable dynamic loading of
mcrypt modules because, every time I tried to enable it, the configure command
failed.
./configure
--prefix=$BLIB/mcrypt --disable-dynamic-loading $CF_OPTS |
2.41 - Compiling PHP 4 (4.4.9)
Source : www.php.net
During installation, PHP inserts a 'LoadModule' line in httpd.conf. As
we cannot have both PHP modules loaded at the same time, we decide that the
default PHP module will be PHP 5. So, we comment out the PHP 4 LoadModule
directive in the httpd.conf configuration file.
We modify the 'phpize'
script so that it uses the embedded autoconf and m4. We also force the shell to
be a korn-compatible shell (on some OS, /bin/sh is a Bourne-only shell, which
does not work with phpize).
export PBASE=$BASE/php4 |
2.42 - Compiling PHP 5 (5.2.6)
Source : www.php.net
As with PHP 4, we modify the 'phpize' script so that it uses the
embedded autoconf and m4. We also force the shell to be a korn-compatible shell
(on some OS, /bin/sh is a Bourne-only shell, which does not work with phpize).
First, we set the Oracle-related configure options :
- PHP 5 does not support Oracle below version 9. So, if the Oracle library we have in $ORACLE_HOME is version 8, we cannot compile the Oracle-related extensions. Note that, on HP-UX 11.00, Oracle does not provide a version greater than 8i.
- we detect if the Oracle client library is an instantclient and set the the configure options accordingly.
#-- Set Oracle configure options |
Then, we configure and build :
export PBASE=$BASE/php5 |
2.43 - Compiling autoconf (2.63)
Source : http://ftp.gnu.org/gnu/autoconf/
As $BLIB/common/bin is first in path, configure always uses our embedded
version of m4.
./configure --prefix=$BLIB/autoconf $CF_OPTS |
2.44 - Compiling the ming library and PHP extension (0.4.2)
Web site : http://www.libming.org/
Source : http://sourceforge.net/project/showfiles.php?group_id=18365
Ming is a library for generating Adobe/Macromedia Flash files (.swf). It allows PHP to generate Flash animations and interactions dynamically.
First, we compile and install the library :
./configure --prefix=$BLIB/ming
$CF_OPTS \ |
The ming extensions contained in the PHP 4 and 5 source distributions don't work with libming version 0.4.x. So, we build the PHP extensions provided in the ming distribution.
But, first, we need to fix a small problem in config.m4 (wrong lib subdirectory name) :
cd php_ext |
Then we compile and install the PHP 4 & 5 extensions :
for _v in 4 5
#-- PHP 4 first, then 5 |
2.45 - Compiling the SSH2 PHP extension (0.11.0)
Source : http://pecl.php.net/package/ssh2
We compile the extension for PHP 4 and 5.
for _v in 4 5
#-- PHP 4 first, then 5 |
2.46 - Compiling the APC PHP extension (3.0.19)
Source : http://pecl.php.net/package/APC
APC stands for 'Alternative PHP Cache'. It is a free, open, and robust framework for caching and optimizing PHP intermediate code. Depending on the application, it can provide really dramatic improvements in terms of response time and CPU/memory usage.
APC provides a basic administration
interface. Here, we install it in the 'lib/php' subdirectory of both PHP trees.
Here are the steps to activate it on a target machine :
- Considering that PHP and the APC extension are active,
- Copy the apc.php file from the 'lib/php' subdirectory to a directory accessible by a web browser.
- Edit apc.php and modify the line starting with 'defaults('ADMIN_PASSWORD',' to set a password of your choice (mandatory to access protected features).
- Open apc.php through your browser.
We also pre-configure the php.ini file with a basic set of APC parameters.
If you are interested in PHP performance improvement, you may also have a look at a number of other software like XCache, eAccelerator, memcache, PHK, Automap... All these PHP extensions can be compiled and installed in a similar way as what we show here.
for _v in 4 5
#-- PHP 4 first, then 5 |
3 - Cleanup
Now that the compilation phase is over, we can remove the tools we don't need in the runtime environment :
/bin/rm -rf \ |
Note that we keep autoconf and m4, to be able to compile and install
additional PECL extensions.
4 - Configuring
Here, we give only a minimal configuration, which allows to start Apache and to run a simple test. When the package is installed on a target machine, it must be configured in a much more serious way. This aspect is beyond the scope of this document but you can find a lot of resources on the Internet.
![]() |
Warning : Running this package with the default configuration in a
production environment can lead to serious security problems !! |
4.1 - System
- Check that a www user exists in /etc/passwd. If not, create it with passwd='*' and login shell = /bin/false.
- Add a www group in /etc/group if it does not already exist.
4.2 - Apache
Edit $BAP/conf/httpd.conf :
- Change the line starting with 'User' to 'User www'
- Change the line containing 'Group #-1' to 'Group www'.
- Add this line anywhere in the file :
AddType application/x-httpd-php .php |
Add the following line at the end of $BAP/bin/envvars :
unset LD_LIBRARY_PATH LIBPATH SHLIB_PATH |
4.3 - Oracle client
Edit the file '$BAP/bin/envvars' and add the environment variables needed by the Oracle client :
ORACLE_HOME=<$BASE>/libs/oracle_home |
4.4 - PHP
For each PHP version, edit $BASE/php{4,5}/php.ini :
extension_dir = "<$BASE>/php<4|5>/lib/php/extensions" |
5 - Checking
5.1 - Starting Apache/PHP
Now, start Apache with :
<$BASE>/apache/bin/apachectl
start |
This should not display any message.
5.2 - Checking the PHP modules
Here, we just check that the PHP shared modules can be loaded without error.
It can be useful to run this test when you install your package to a new host, as it allows to check that every shared lib dependencies are satisfied.
The syntax we use here must be compatible with
PHP versions 4 & 5. That's why we cannot use scandir().
By default, you will be testing PHP 5, as it is the one we chose to activate in the Apache configuration. In order to test PHP 4, comment out the PHP5 line in $BAP/conf/httpd.conf, uncomment the PHP4 line, restart Apache, and reload the page from your browser.
Create a new file named $BAP/htdocs/test.php with the following content :
<?php |
Point your browser to http://<your_server>/test.php
It should display the configuration of every PHP modules, static and dynamic. If there are some errors when trying to load a module, it will also display them.
6 - Packaging
First, remove the Oracle and Java links, as we don't want them to be included in the package :
/bin/rm -f $BLIB/oracle_home $BLIB/java_home |
6.1 - RPM
RPM is the native package format in RedHat's RHEL.
In order to build an RPM package, you just need to install the rpm-build package.
6.1.1 - Creating the package
Note that we build a binary RPM, not a source RPM.
We need a specfile. Here is a sample content for this file :
Name: http170 |
What does it mean ?
- The first lines contain information about the packages's name, requirements, packager (you), and a description.
- the pre-install script ensures that the www user & group exist. If it is not the case, they are created.
- The pre-uninstall script stops Apache and remove the log files.
- Then, we give the list of the files, with some of them being tagged as configuration files (see the rpm documentation for more information on the %config tag).
Now, build your package with this command :
rpmbuild -bb <specfile-path> |
This will create a file named http170-1.7-0.i386.rpm in the 'RPMS/i386' subdirectory of your RPM install base directory (/usr/src/redhat on RHEL). This is your RPM package file.
6.1.2 - Installing the package
This package can be installed, as any other RPM packages, using the rpm command (man rpm for more).
6.2 - Tar/gzip
A tar package just contains every files under $BASE.
6.2.1 - Creating the package
The commands to build a tar/gz package are :
cd $BASE |
This creates a '.tgz' package file in /tmp.
6.2.2 - Installing the package
To install the package :
- Download the package file on the target host
- Create the $BASE directory
- Ensure the file system containing the $BASE directory has enough free space
- Untar/uncompress the package file in $BASE.
6.3 - Configuring the package
Once the package is installed, you can create the symbolic links to the Oracle and Java installation directories as $BLIB/oracle_home and $BLIB/java_home.
You can also run the test above to check that the PHP modules can be loaded correctly.
7 - The end
Enjoy !