Compile PHP on Windows

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 zlib.h.

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!

Compiling PHP

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.

After 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.

Finally, run nmake to kick off the compile.

cd C:PHP-Devphp5.4
buildconf
configure
nmake
nmake test

If either configure or 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 Release_TS folder. 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.

Compiling Extensions

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

The --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 --enable-aop.

When 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 php_aop.dll.

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.

Summary

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!

Image via Fotolia

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • ali

    Hi timothy, I love you php. and you.
    have a good day.

  • Alex Gervasio

    It may sound a bit flattering, but IMO this is definitively one of the most detailed -yet clear guides on how to compile PHP binaries according to custom needs. Straight to the point and concise, which saves the interested reader of the burdens of scanning the net looking for the tools required to get the job done. Not to mention I learned a lot of brand new stuff. Great work, Tim :)

  • KoenDG

    Hello there.
    First of all, thanks for the tutorial. First real clear tutorial I’ve found on building PHP on Windows.

    Sadly, I keep bumping in to the same error.
    I’ve set up a VM for this job, Win7 SP1 x64.
    Installed VS2010(still have the MSDNAA installer from back when I attended college) and Win7 SDK, as linked.

    All goes fine, until the very end. I’ve taken a screenshot to make things easier to view: http://i.imgur.com/TCNub.png
    That’s the error message.

    I’ve done some googling, but all I’ve found are either assessments of what’s wrong, or suggestions to simply go and “try deleting bits of the C source code until it compiles”.

    I’m posting this here in the hopes that someone who has solved it notices this. Some more info which might be useful:
    1) http://i.imgur.com/uqkAl.png
    2) http://i.imgur.com/dhHJB.png

    • http://zaemis.blogspot.com Timothy Boronczyk

      You’re welcome!

      What does your configure command look like (what extensions are you compiling, etc.)?

      • KoenDG

        Hello, thanks for the reply.
        I checked the screenshot again and noticed I did indeed enter some arguments. At that point, I was just trying different things out. I fired up the VM just now and did it again, and it worked just fine. Just the “configure” command with no extra parameters.

        Honestly, I haven’t really looked at it in these past weeks. I can’t remember what I was trying to compile, but I do remember that extra slur of arguments was inspired by some other site I stumbled upon.

        I deleted everything, downloaded everything again(well, not the Windows SDK, just the PHP stuff). Went off without a hitch. Made a DLL of the latest Imagick PECL. No errors but no DLL either. But you mentioned that in the article.

        Thanks for you time and sorry for any trouble.

  • Anand

    Really very good indeed, i was looking it since long time.

  • Alan Rew

    WRT your comments about official apache binaries needing VC6, you can get alternative apache binaries compiled with VC10 from http://www.apachelounge.com/ (or, with VC9, from http://www.apachelounge.com/download/additional/). I’ve used the VC9 version on Win XP with PHP 5.3 and it works fine. HTH.

  • http://www.richardsuggs.com Rick

    In case anyone is interested in compiling PHP with the MS Visual C++ 9.0 (2008) compilers, be sure to use the VC++ Redistributable SP1 available http://www.microsoft.com/en-us/download/details.aspx?id=14597, to avoid some C library linkage errors such as fatal error C1900: [] mismatch between ‘P1′ version ’200801116′ and ‘P2′ version ’20070207′ (described in https://wiki.php.net/internals/windows/stepbystepbuild

  • Igor

    thank you for tutorial :) helped me

  • http://www.webresourcesource.com Asa Carter

    I’m sure I’ve not missed anything but I get as far as typing buildconf and I get message that buildconf is not recognised.
    Everything before that works fine.

  • abed

    tnx very good

  • biagiopas

    hello,
    thanks for the guide, I’m trying to compile a pecl in my environment wamp2.2×86
    But still I could not

    I would like to ask
    1) how to configure Windows SDK Command Prompt to compile with MSVC9 (Visual C + + 2008) and not with MSVC10 (Visual C + + 2010).
    In my computer are both installed, MSVC9 and MSVC10.

    2) this command to generate the .dll ,
    configure-enable-shared=aop
    maybe that missing command to compile the .dll?
    nmake php_aop.dll

  • http://www.letsgozik.org/ Olivier

    Thanks for this tutorial !
    I already had VS2008 and SDK 6.1 installed on my computer for others projects, so I tried your instructions and it worked flawlessly :)