Compiling PHP from source code is more commonly done on Unix-type systems. Those working in a Windows environment are more likely to download and install PHP from precompiled packages. And while I don’t disagree it’s easier to use a precompiled solution, even on Unix systems, there are some advantages that can come with compiling a binary from source. In general:
- You have the ability to fine tune the final product when you compile. Maybe you want to have a particular extension compiled directly into the binary instead of loading it as an external library. Or, perhaps you want to turn off a particular feature which would normally be available by default.
- You can make tweaks to the compilation process if you’re so inclined which may enhance performance for your particular environment (of course this assumes you already know what you’re doing in which case you wouldn’t be reading this article).
- Compiling might be the only way to get things to work if the precompiled binaries were built against older versions of supporting software and libraries than you are running on your system.
But be forewarned: compiling can be a frustrating task, especially on Windows! You must ensure your build environment is set up correctly, learn how to use the compiler and other build tools properly, and satisfy any library dependencies. Hopefully this article is your first step in overcoming many of these obstacles.
Setting Up the Build Environment
PHP is written in C and so a C compiler is necessary if you’re going to build PHP from source. C++ is a super set of C, so a good C++ compiler should be able to compile C code as well, though sometimes this isn’t always the case. For Windows, Microsoft’s Visual C++ Express (to which I’ll refer to as VC++ from here after) should suffice and is freely available from Microsoft’s website. I’m using the 2010 edition for this write up.
When choosing your compiler version, you should keep in mind how you will be running PHP. If you’ll be running mod_php with an officially precompiled Apache binary then you’ll want to compile PHP using Visual Studio 6 since that’s the version used to compile Apache. The module needs to target the same runtime library as Apache, in this case
msvcrt.dll. If you’re building Apache from source as well, or if you’re going to run PHP as CLI or FastCGI, then this isn’t an issue and 2010 will work just fine.
You’ll also need to install the Windows Software Development Kit (here after SDK) as well. The SDK supplies us with important header files for the Windows platform which we’ll need for a successful compile. It too is available for free; I’m using version 7.1.
Install the compiler first and then the SDK. I won’t discuss the installation since both have a graphical installation wizard to guide you through the process.
Once you have a working compiler set up, download the binary tools and deps packages from windows.php.net/downloads/php-sdk. The binary tools package (I’m using the 20110915 archive) contains development tools like re2c, bison, and some additional commands you’ll need to build PHP. The deps package (I’m using the 5.4 archive since that matches the version of PHP I’ll be compiling) contains the minimum header and library dependencies needed, such as
It probably goes without saying that you’ll want to download the PHP source as well from windows.php.net/download. At the time of this writing, the current version of PHP is 5.4.6 so that’s the version number you’ll see in my examples.
It’s a good idea to create a workspace to which you can unpack the source code to and compile in without mucking up the rest of your system. Create the folder
C:PHP-Dev which will serve as the working directory, and then unpack the binary tools archive into it.
Next, extract the contents of the PHP source archive to
C:PHP-Dev so you have the
php5.4 source folder there, and then extract the deps archive into a sibling
deps folder. Your directory structure should look similar to this:
Open the Windows SDK Command Prompt that was installed with the SDK (Start > Microsoft Windows SDK > Windows SDK Command Prompt) and execute these commands:
setenv /release /xp /x86 cd C:PHP-Dev binphpsdk_setvars.bat
Using the SDK Command Prompt console is desirable over the ordinary
cmd.exe console as it sets many environment variables specific for compiling source code. The compile commands later should also be executed in this console.
The flags to
setenv set some build properties for the environment; In this case I’ve set the environment to target a Windows XP 32-bit release build. You can try and build with
/x64 if you’re feeling adventurous, but there are still some issues with it. Specifying different versions of Windows such as
/vista will most likely yield problems because of some odd defines in the build scripts (PHP still aims to be XP-compatible). Unless you really know what you are doing, it’s probably safest to stick with the recommended values that I used above.
phpsdk_setvars.bat script then goes on to set some additional environment variables so the build process can find the binary tools.
Keep in mind that all this variable setting is only temporarily for your console’s session. If you close out of the prompt and go back to compile later, you’ll need to run the commands again. If you don’t, you’ll receive errors like the following when you run configure later in the process and be unable to proceed:
Checking for bison.exe ... <not found> ERROR: bison is required
Making sure you have the correct build environment, the required sources, and any dependencies is the hardest part of the process. So now that your environment is set up and the source code and dependencies are in their proper place, it’s time to compile!
In the SDK Command Prompt, navigate to the PHP source folder and run
buildconf. The command is responsible for generating a configuration file which will create a Makefile to drive the compilation process.
buildconf completes (it should only take a second), run
configure --help and examine what functionality you wish to enable/disable, and then re-run
configure with any desired options. It’s a good idea to inspect the output before moving on since it will warn you if any of the necessary dependencies are not available. If that happens, you can either install the dependencies and re-run
configure again or adjust the invocation to disable the extensions that require them.
nmake to kick off the compile.
cd C:PHP-Devphp5.4 buildconf configure nmake nmake test
nmake fails, there’s a good chance the problem is one of two things: 1) your environment is not set up correctly, or 2) you’ve enabled a feature which depends on an external library and the library is not installed on your system. Double check that you’ve set up the environment according to the instructions above and that any extra libraries which may be necessary based on your configure options have been installed.
When the first
nmake compile process has completed you’ll find your shiny new PHP binaries in the
nmake test runs the new binaries through a battery of bug tests to make sure things are working as they should be. The results of
nmake test are forwarded to the QA team which depends on them to improve PHP, so even though it may take a few minutes to run, it’s the responsible thing to do.
At this point you can also take the extra step of running
nmake snap which will create ZIP archives with the binaries which you can copy around.
There are two ways to compile PHP extensions: statically and dynamically. A statically-compiled extension is compiled into the PHP binary itself, while a dynamically-compiled one is a separate DLL which can be loaded later through the
php.ini file. Extensions are typically compiled as DLLs, although there are some advantages to static compilation as well; it ultimately it depends on your needs.
To compile PHP extensions on Windows, extract the extension’s source code folder into the
ext folder of your PHP source directory. Then, rebuild the configure script by running
buildconf --force and re-compile PHP using the appropriate flags to enable the extension.
As an example, let’s compile the AOP extension statically. Download the source code from PECL, and extract it’s folder into
ext. Then execute the following:
cd C:PHP-Devphp5.4 buildconf --force configure --enable-aop nmake
--force option to
buildconf forces it to rebuild the configuration scripts. Afterwards, run
configure --help and you should see the option to include the new extension in the output. In this case, it’s
nmake finishes, you’ll have a newly built PHP binary with the AOP extension baked right in.
If you want an extension to be available as a DLL and not baked into PHP, you can follow the same steps as above but specify “shared” as a value to configure’s enable option.
buildconf --force configure --enable-aop=shared
The resulting DLL will be in the
Release_TS folder alongside the PHP binary once compilation has finished, in this case named
Compiling on Windows is still a bit tricky, especially when it comes to extensions. The windows version of
phpize seems to be broken and I have yet been able to compile a DLL after-the-fact, much like how PECL does. There have been tremendous strides made by the PHP team in the past five years or so towards making PHP just as awesome on Windows as it is on Unix, so hopefully the snags and wrinkles will be ironed out in time. In the meantime, I recommend compiling PHP and your shared DLLs at the same time.
The ability to compile source code is a good skill to have, especially if you later want modify PHP. Perhaps you want to add new functionality, link against a new library, or just be the next great PHP core developer (they can always use the help!). And now that you know how, feel free to hack and build away!