Building PHP on Windows

by Elizabeth Marie Smith (2008-03-17)
 

Building PHP on Windows doesn't have to be a time intensive mystery. Whether you're building custom extensions, patching something in the PHP core, or want to try a build on a newer compiler, you don't have to be intimidated by warnings and errors. Compiling on Windows is no more difficult than compiling on any other system as long as you have the requirements needed: the php source code, a compile environment that the source code understands, and any library dependencies.

Step 1: PHP Source Code

First a word about PHP4. PHP4 is dead, as in no longer supported except for the case of severe security bugs, and even those will only be released until 8/8/2008, so this won't cover building the PHP4 source since you'd be better off porting that extension to PHP5 anyway. PHP4 also used a completely different build system and was more difficult to customize.

In order to compile PHP you need the source code. There are several ways to get it. You can use an official release from php.net. If you need a more recent version of the source, you can use a source snapshot from PHP snaps. Or if you want to work on the PHP source live, you can use the CVS version using anonymous CVS. On Windows the easiest way to deal with CVS is using TortoiseCVS, which integrates checkouts and updates directly into the Windows shell. Right-click and there are all your commands.

In addition to the “main” PHP source code you may also want additional extensions; most of these can be found in PECL. You can also check out PECL extensions from cvs.php.net; use the pecl module instead of php-src. Uncompress whatever kind of source download you've used, or check it out from CVS, and place it in a location that's easy to remember. I keep all my source code for building in C:\build. It's generally easier to keep the source on your main hard drive and in a path without spaces. Although you can build PHP off a second volume or off a path with spaces, the quoting and escaping required might introduce problems that can be hard to debug. If you place your pecl extensions in a directory named pecl parallel to your PHP source, the Windows build system will automatically find them.

So you should have the PHP source code, in a location that's easy to remember. Step one is now complete.

Step 2: Compile Environment

Setting up a compile environment for PHP is what trips most people up. First of all, you cannot build PHP on Windows with the MinGW compiler. The source currently makes some assumptions that on Windows you are always using Microsoft compilers. If someone wants to take the time to fix those assumptions, a patch would be welcome, but until then a Microsoft compiler is required. The MS compilers are packaged with Microsoft Visual C++, but that's too much to type so it's usually abbreviated to MSVC.

Just like other operating systems, Microsoft continues to upgrade and improve its C runtime libraries. Unfortunately, they've done two very strange things, each new version of Visual Studio that is released has a new version of the runtime, and the runtime must be distributed by individual programs using re-distributable files included with Visual Studio, instead of having the new versions pushed out with Windows Update.

So what does this mean? Let's start with the compiler that the “official” PHP builds use, Visual C++ 6. The original version of the C runtime is called MSVCRT.dll and is included on every Windows computer; it's always present. This is the runtime that Visual C++ 6 links against, which is why many people have not upgraded compilers, they don't have to worry since the DLL is always present. However, this compiler and runtime is very old, in fact Microsoft doesn't even distribute the compiler anymore and getting a copy usually involves something very expensive or very illegal.

Chances are if you don't already own a copy of Visual Studio 6 you aren't going to be able to find one. In addition, you need to have the service packs installed, and if you want IPV6 support in PHP, you also need to get the last version of the Platform SDK that supports Visual Studio 6. You need to use the include files and libraries from the SDK, but NOT the compiler and linker; use the older ones included with Visual Studio. And the original nmake might have some issues when compiling—I usually rename it to nmake.exe.bak and copy the working nmake.exe from the platform SDK over to the same directory as the old nmake. Remember, you need to use the old cl.exe (compiler) and link.exe (linker) not the ones included in the SDK!

Since Visual Studio 6 there have been four more versions of Visual Studio released (yes, that's how OLD it is). Visual Studio 2002 .NET (MSVC 7) uses msvcr70.dll for its runtime, Visual Studio 2003 .NET (also known as MSVC7.1) uses msvcr71.dll for its runtime, Visual Studio 2005—which is currently the “gold standard” for C applications on Windows (also known as MSVC8) uses msvcr80.dll, and the new kid on the block, Visual Studio 2008 (also known as MSVC9) uses msvcr90.dll. The newer versions create smaller, faster binaries and the newer runtimes have fixed bugs and security holes, but there's a good reason PHP still uses the old compiler involving maintaining compatibility with Apache (hopefully not for long).

Starting with MSVC8, Microsoft began releasing a free, “light” version of their Visual Studio environments, called Visual Studio Express. Their compiler tools, usable via command line, cl.exe, nmake.exe, link.exe, and others have always been bundled with their free Microsoft SDK downloads. So it's not difficult to get a Microsoft compiler for free, however remember that mixing runtimes can be a very bad thing, I'll discuss that more later.

So you have a compile environment set up, and you have the Microsoft SDK (which is a separate installer option or download with the Visual Studio Express versions—follow the directions exactly, and be sure that you update the LIB and INCLUDE variables in the command line batch files provided for building with Visual Studio, not just the IDE environment variables). Microsoft has some excellent documentation on how to install these programs and make sure they are set up properly and can compile.

One more thing—Windows Platform SDK contains a file named WinResrc.h usually in Include folder inside the SDK's installation directory. This needs to be copied and renamed to winres.h, the name PHP uses for the file.

Step 3: Library Dependencies

This is probably the most confusing and annoying step for people trying to compile on Windows. Like most C programs, PHP relies on some external libraries to function properly. The “basics” are included with Windows, but there are some additional libraries needed. First PHP uses a custom version of bindlib for resolving host addresses. This custom version is included at cvs.php.net in the bindlib_w32 module if you want to build it from scratch. The regular build of PHP on Windows also requires a few additional open source libraries: libiconv, libxml2 and possibly libicu (if you're building PHP6). You also need Apache libraries if you're building the Apache PHP modules. PHP also uses several tools from the Unix world, flex and bison, which are available from php.net or are packaged with the prebuilt libraries available.

These libraries and tools, prebuilt and ready to go, and many many more—enough to build all the extensions currently available on Windows, are available from Edin Kadribasic in an enormous file called zip.zip (yes, original I know). These are all created with MSVC6 and are used for the “official” PHP build. (If the site is down, you can find a mirror at http://perisama.net but always use Edin's if available.)

Take this enormous pack of libraries and unzip them—you'll get a dev directory with php_build and template directories inside. Drop these two directories parallel to your PHP source.

If you are building PHP6 or PHP5.3, it now uses re2c instead of flex. However this requires an additional tool that is NOT currently included in zip.zip. You can find Windows builds of re2c at Sourceforge. You'll want the Windows binary.exe just drop it into your php_build/bin directory next to flex.exe and bison.exe.

This is what mine looks like:

C:/build C:/build/php5 : PHP5 source C:/build/pecl : pecl extensions C:/build/php_build : libraries C:/build/template : stuff to package a release

There, now you have all the tools needed to compile PHP on Windows! Let's give it a try.

Step 4: Compiling PHP on Windows

The compile system for PHP5 on Windows uses the Windows Script Host and Jscript files and the command line to imitate the configure system available with the autotools chain on *nix systems. If you've never used the command line on Windows, this might be very strange.

First of all, you'll need to open up the batch file included with Visual Studio that sets up your compile environment. A shortcut to the command prompt should be found in your start menu if you're using any compiler but MSVC6 (you'll need to run your vcvars32.bat in a cmd.exe window or write a batch file to set it up for you with MSVC6).

Next you need to set an environment variable so bison is happy:

  1. SET BISON_SIMPLE=C:\build\tools\bison.simple

Replace the path above to the path where your bison.simple file is located, if you use Edin's libraries this will be in php_build/bin. I keep bison, flex, and some other Unix tools I use often in c:/build/tools and add it to my PATH variable, you don't have to do this if you keep the tools in php_build/bin, the build system will find it automatically.

CD to the location where your php source is:

  1. cd c:/build/php5

Now we need to create our configuration file. Type buildconf and hit return. You should see a message about how to view options for your newly generated configuration file.

Next we need to configure PHP, you can view the options available to you by typing:

  1. cscript /nologo configure.js --help

To configure PHP use:

  1. cscript /nologo configure.js

and follow it with the configure options you'd like. The most useful options are –enable-debug for a debug version of PHP, –enable-debug-pack (don't use this with enable-debug) for creating debug symbol files with a release version, –disable-zts for creating a non-thread safe build of PHP (thread safety is on by default in Windows) and –enable-snapshot-build which will attempt to build every extension available, and not bail out if an extension fails.

If your configuration ran correctly and you have no errors about missing libraries or headers (except for extensions you don't care about building) then you're ready to actually compile. Type nmake (or nmake snap if you used –enable-snapshot-build) and watch the compile scroll by.

Your newly created PHP will be available in the PHP source directory, builds using –enable-debug and –disable-zts will be in Debug, builds using only –enable-debug will be in Debug_TS, builds using –disable-zts will be in Release, normal builds will be in Release_TS, see the pattern?

Now for the promised lecture on runtime mixing. You can use libraries and binaries built with an older runtime with a newer compiler, but you cannot use libraries and binaries built with a new runtime in and old compiler. That means you can use MSVC8 Express to build PHP, even though the libraries available were compiled with Visual Studio 6, but you cannot use libraries compiled with MSVC8 and build with MSVC6. However, this “mixing of runtimes”—where some libraries you link against use one runtime and other use a different runtime, can have some bad consequences, such as unintended bugs , memory corruption, and crashes; Microsoft has a nice article about it if you're interested in the “why?” For now, there's not much you can do about the issue. There is a work in progress to get the libraries from Edin's pack built on newer Microsoft compilers, but there's a “Catch-22”—PHP on Apache must be built with MSVC6 until Apache moves to the newer compiler for its Windows builds. But Apache can't move to the newer compiler until PHP and the other modules that make it so popular move to the newer compiler, and all its dependencies are available on the newer compiler. Which is why the “official” PHP builds are still done with MSVC6.

If you're a little more cutting edge and want to help with getting PHP built and tested for MSVC8 you can find some builds of required dependencies at http://perisama.net/downloads/Libraries/—but the list is not complete. If you'd like to help get all the dependencies available on the newer compilers so PHP can start releasing test versions built with MSVC8, feel free to volunteer for the “The Great Compile Project”. You can find Apache builds on newer compilers at The Apache Lounge.

Elizabeth M. Smith has been using PHP since time immemorial (PHP 4.0beta), but has used PHP 5 for so long now she’s forgotten how she ever got by without SPL and a real object model. Elizabeth is a certifiable (yes, we mean men in white coats coming to put on strait jackets) Windows geek, if it can be compiled on Windows, she’ll compile it, if not… she’ll fix it so it does. She enjoys doing very perverse things to Windows using PHP as well—all this in between caring for her 4 kids and husband.

She recently joined the crew at OmniTI and hopes to learn something from the masters. She went to college for an English degree and instead wound up with several children and a career in computers… Her first foray into PHP was running an anime/manga fan site. She liked creating applications and websites so much, it became her “day job”.
File under: art  compiling  fastcgi  homepage  php  windows 
 

Comments

Re: Building PHP on Windows by benh57 (2008-04-07 15:25:10 (America/Toronto))
Your step 2 is very confusing and not helpful. Also, that's the hardest part!

 Perhaps you could include a set of steps containing exactly what someone needs to download, install, what files they need to edit, etc..  Assume the user has a raw XP install...

thanks--
Re: Building PHP on Windows by auroraeosrose (2008-05-09 22:13:40 (America/Toronto))
The short version

If you're just developing for fun and don't care if what you compile is exactly the same as the "stock" PHP build, head over to microsoft and get the 2008 Express version of C++, make sure you tell it you want the win32api / windows sdk stuff.  Then copy the one file mentioned- the winresrc.h (a search all files will help you find it) and rename it to winres.h and you should be ready to go.

If you'd like the compiler we hope to ship with PHP 5.3, get the 2005 version of Express C++, and then install the windows win32api sdk and follow the instructions Microsoft provides for integrating the two items.  The SDK I keep referencing is just a collection of headers and libraries provided by microsoft.  The 2008 C++ express edition can install and integrate it for you, but the 2005 version you have to do it by hand.  Make sure you integrate it with both your IDE environment, and the cmd.exe environment (which is set up with a .bat file you can edit).  The reason you need both is because PHP uses a command line environment to do windows builds.

Thanks!
Elizabeth
Visit the forum