介绍

  • gcc or some other compiler suite.
  • libc-dev, which provides the C standard library, including headers.
  • make, which is the build-management tool PHP uses.
  • autoconf (2.59 or higher), which is used to generate the configure script.
  • automake (1.4 or higher), which generates Makefile.in files.
  • libtool, which helps manage shared libraries.
  • bison (2.4 or higher), which is used to generate the PHP parser.
  • (optional) re2c, which is used to generate the PHP lexer. As the git repository already contains a generated lexer you will only need re2c if you wish to make changes to it.
~/php-src> ./buildconf     # only necessary if building from git
~/php-src> ./configure
~/php-src> make -jN

For a fast build, replace N with the number of CPU cores you have available (see grep "cpu cores" /proc/cpuinfo).php

~/php-src> ./configure --prefix=$HOME/myphp
~/php-src> make -jN
~/php-src> make install

 

The ./buildconf script

This script does little more than invoking the build/build.mk makefile, which in turn calls build/build2.mk.linux

The main job of these makefiles is to run autoconf to generate the ./configure script and autoheader to generate the main/php_config.h.in template. The latter file will be used by configure to generate the final configuration header file main/php_config.h.git

The ./buildconf script only has two options: --debug will disable warning suppression when calling autoconf and autoheader. Unless you want to work on the buildsystem, this option will be of little interest to you.sql

The second option is --force, which will allow running ./buildconf in release packages (e.g. if you downloaded the packaged source code and want to generate a new ./configure) and additionally clear the configuration caches config.cache and autom4te.cache/.api

If you update your git repository using git pull (or some other command) and get weird errors during the make step, this usually means that something in the build configuration changed and you need to run ./buildconf --force.bash

 

The ./configure script

~/php-src> ./configure --disable-cgi --disable-tokenizer --without-sqlite3 \
                       --enable-opcache --with-gmp
~/php-src> ./configure --disable-all && make -jN
~/php-src> sapi/cli/php -m
[PHP Modules]
Core
date
pcre
Reflection
SPL
standard

 

For the smallest possible build you can additionally specify the --disable-cgi switch, so only the CLI binary is generated.less

--enable-debug enables debug mode, Furthermore debug mode defines the ZEND_DEBUG macro,ide

--enable-maintainer-zts enables thread-safety. This switch will define the ZTS macro, which in turn will enable the whole TSRM (thread-safe resource manager) machinery used by PHP.ui

Due to the ABI incompatibility make install (and PECL install) will put shared extensions in different directories depending on these options:this

  • $PREFIX/lib/php/extensions/no-debug-non-zts-API_NO for release builds without ZTS
  • $PREFIX/lib/php/extensions/debug-non-zts-API_NO for debug builds without ZTS
  • $PREFIX/lib/php/extensions/no-debug-zts-API_NO for release builds with ZTS
  • $PREFIX/lib/php/extensions/debug-zts-API_NO for debug builds with ZTS

The API_NO placeholder above refers to the ZEND_MODULE_API_NO and is just a date like 20100525, which is used for internal API versioning.

Some of the more important ones are documented at the end of the configure help output (./configure --help | tail -25).

 

For example you can use CC to use a different compiler and CFLAGS to change the used compilation flags:

~/php-src> ./configure --disable-all CC=clang CFLAGS="-O3 -march=native"

 

make and make install

~/php-src> make -jN    # where N is the number of cores

The main result of this operation will be PHP binaries for the enabled SAPIs (by default sapi/cli/php and sapi/cgi/php-cgi), as well as shared extensions in the modules/ directory.

Now you can run make install to install PHP into /usr/local (default) or whatever directory you specified using the --prefix configure switch.

make install will do little more than copy a number of files to the new location. Unless you specified --without-pear during configuration, it will also download and install PEAR. Here is the resulting tree of a default PHP build:

> tree -L 3 -F ~/myphp

/home/myuser/myphp
|-- bin
|   |-- pear*
|   |-- peardev*
|   |-- pecl*
|   |-- phar -> /home/myuser/myphp/bin/phar.phar*
|   |-- phar.phar*
|   |-- php*
|   |-- php-cgi*
|   |-- php-config*
|   `-- phpize*
|-- etc
|   `-- pear.conf
|-- include
|   `-- php
|       |-- ext/
|       |-- include/
|       |-- main/
|       |-- sapi/
|       |-- TSRM/
|       `-- Zend/
|-- lib
|   `-- php
|       |-- Archive/
|       |-- build/
|       |-- Console/
|       |-- data/
|       |-- doc/
|       |-- OS/
|       |-- PEAR/
|       |-- PEAR5.php
|       |-- pearcmd.php
|       |-- PEAR.php
|       |-- peclcmd.php
|       |-- Structures/
|       |-- System.php
|       |-- test/
|       `-- XML/
`-- php
    `-- man
        `-- man1/
  • bin/ contains the SAPI binaries (php and php-cgi), as well as the phpize and php-config scripts. It is also home to the various PEAR/PECL scripts.
  • etc/ contains configuration. Note that the default php.ini directory is not here.
  • include/php contains header files, which are needed to build additional extensions or embed PHP in custom software.
  • lib/php contains PEAR files. The lib/php/build directory includes files necessary for building extensions, e.g. the acinclude.m4 file containing PHP’s M4 macros. If we had compiled any shared extensions those files would live in a subdirectory of lib/php/extensions.
  • php/man obviously contains man pages for the php command.
~/myphp/bin> ./php --ini
Configuration File (php.ini) Path: /home/myuser/myphp/lib
Loaded Configuration File:         (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

As you can see the default php.ini directory is $PREFIX/lib (libdir) rather than $PREFIX/etc (sysconfdir). You can adjust the default php.ini location using the --with-config-file-path=PATH configure option.

~/myphp/bin> cp ~/php-src/php.ini-development ~/myphp/lib/php.ini
~/myphp/bin> ./php --ini
Configuration File (php.ini) Path: /home/myuser/myphp/lib
Loaded Configuration File:         /home/myuser/myphp/lib/php.ini
Scan for additional .ini files in: (none)
Additional .ini files parsed:      (none)

Apart from the PHP binaries the bin/ directory also contains two important scripts: phpize and php-config.

phpize is the equivalent of ./buildconf for extensions. It will copy various files from lib/php/build and invoke autoconf/autoheader.

php-config provides information about the configuration of the PHP build. Try it out:

~/myphp/bin> ./php-config
Usage: ./php-config [OPTION]
Options:
  --prefix            [/home/myuser/myphp]
  --includes          [-I/home/myuser/myphp/include/php -I/home/myuser/myphp/include/php/main -I/home/myuser/myphp/include/php/TSRM -I/home/myuser/myphp/include/php/Zend -I/home/myuser/myphp/include/php/ext -I/home/myuser/myphp/include/php/ext/date/lib]
  --ldflags           [ -L/usr/lib/i386-linux-gnu]
  --libs              [-lcrypt   -lresolv -lcrypt -lrt -lrt -lm -ldl -lnsl  -lxml2 -lxml2 -lxml2 -lcrypt -lxml2 -lxml2 -lxml2 -lcrypt ]
  --extension-dir     [/home/myuser/myphp/lib/php/extensions/debug-zts-20100525]
  --include-dir       [/home/myuser/myphp/include/php]
  --man-dir           [/home/myuser/myphp/php/man]
  --php-binary        [/home/myuser/myphp/bin/php]
  --php-sapis         [ cli cgi]
  --configure-options [--prefix=/home/myuser/myphp --enable-debug --enable-maintainer-zts]
  --version           [5.4.16-dev]
  --vernum            [50416]

The script is similar to the pkg-config script used by linux distributions. It is invoked during the extension build process to obtain information about compiler options and paths. You can also use it to quickly get information about your build, e.g. your configure options or the default extension directory. This information is also provided by ./php -i (phpinfo), but php-config provides it in a simpler form (which can be easily used by automated tools).

 

Running the test suite

The make test command is currently not parallel, so specifying the -jN option will not make it faster.

The make test command internally invokes the run-tests.php file using your CLI binary. You can run sapi/cli/php run-tests.php --help to display a list of options this script accepts.

If you manually run run-tests.php you need to specify either the -p or -P option (or an ugly environment variable):

~/php-src> sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php
~/php-src> sapi/cli/php run-tests.php -P

 

Instead of running the whole test suite, you can also limit it to certain directories by passing them as arguments to run-tests.php. E.g. to test only the Zend engine, the reflection extension and the array functions:

~/php-src> sapi/cli/php run-tests.php -P Zend/ ext/reflection/ ext/standard/tests/array/

You don’t need to explicitly use run-tests.php to pass options or limit directories. Instead you can use the TESTS variable to pass additional arguments via make test. E.g. the equivalent of the previous command would be:

~/php-src> make test TESTS="Zend/ ext/reflection/ ext/standard/tests/array/"

 

Fixing compilation problems and make clean

~/php-src> make clean
~/php-src> ./buildconf --force
~/php-src> ./config.nice
~/php-src> make -jN

One last cleaning script that PHP provides is ./vcsclean. This will only work if you checked out the source code from git. It effectively boils down to a call to git clean -X -f -d, which will remove all untracked files and directories that are ignored by git. You should use this with care.