[PHP] Compile an extension on Windows
I recently wrote a PHP extension and while the documentation is very clear on how to build it on Linux, there is not so much information on how to compile an extension on Windows.
This article explains how to build a PHP extension with Visual Studio.
Requirements
This guide assumes that you wrote a “Hello World” PHP extension as described here and that you compiled it successfully on Linux.
To build your extension on Windows, you’ll need:
- Visual Studio (I tested with Visual Studio 2013 Update 4)
- The PHP source code (I tested with PHP 5.5.20)
In the rest of this article, I assume that:
- The PHP source code is located in
C:\php-src
- Your “Hello World” extension source code is located in
C:\MyPhpExtensions\hello
The build process on Linux
You should already familiar with the process, but here is a reminder:
- Install
php-devel
package - Run
phpize
to generate theconfigure
script fromconfig.m4
. - Run
./configure --enable-hello
to generate theMakefile
- Run
make
to build the extension
From config.m4
to config.w32
On Windows, config.m4
is replaced by config.w32
which has a different format.
Migrating from config.m4
to config.w32
is really straighforward, you just need to translate the automake syntax to JavaScript.
Here is a minimalist example:
ARG_ENABLE("hello", "Hello World support", "no");
if (PHP_HELLO != "no") {
EXTENSION("hello", "php_hello.c", true);
}
Don’t forget the true
as the third argument of the EXTENSION
function, it means that we want a DLL instead of a static library.
If you need more information on the syntax, look at the existing config.w32
in the PHP source code.
From phpize
to buildconf.bat
On Windows, you don’t call phpize
but instead you call buildconf.bat
.
Open a Visual Studio developer command prompt (either 64 or 32 bit), and run
cd C:\php-src
buildconf.bat --add-modules-dir=C:\MyPhpExtensions
buildconf.bat
will scan each subfolder of C:\MyPhpExtensions
looking for config.w32
files.
It will then generate a configure.bat
.
From ./configure
to configure.bat
The configure
script that you used on Linux did exactly what you wanted: it just built the extension.
But on Windows it’s different because the script is designed to build PHP itself.
You need to add command line options to configure.bat
to build the minimum number of stuff, so as to make sure that you wont have to solve dependencies to external libraries
cd C:\php-src
configure.bat --disable-all --enable-cli --enable-hello
--disable-all
is a shortcut for all the --disable-xxx
and --without-xxx
flags, --enable-cli
enables back the PHP command line interface (ie php.exe
) and --enable-hello
enables your “Hello World” extension.
By default, this will create a “Thread Safe” build.
If you want a non thread safe build, just add --disable-zts
to the command line.
From Make
to NMake
configure.bat
generated a Makefile
for the Microsoft version of Make
.
To start the build, just run:
nmake
This will build your PHP extension, as well as php.exe
.
This is handy because you’ll need a php.exe
that matches the configuration of your extension.
Indeed, in order to be loaded in PHP, your extension must match the PHP build in term of:
- word size (32 or 64 bits)
- thread safety (TS build or NTS build)
- compiler version (VS9, VS11 etc.)
If you really don’t need to build php.exe
, you can use this command line:
nmake php_hello.dll
Thousands of warnings
During the compilation of PHP, the compiler issues a lot of warnings.
If you want to prevent this, just add the following file to c:\php-src\win32\build\config.w32
:
ADD_FLAG('CFLAGS', ' /wd4005 /wd4267 /wd4244 ');
ADD_FLAG('CFLAGS_BD_ZEND', ' /wd4018 /wd4101 /wd4090 /wd4273 ');
ADD_FLAG('CFLAGS_BD_MAIN', ' /wd4018 /wd4090 ');
ADD_FLAG('CFLAGS_BD_MAIN_STREAMS', ' /wd4013 ');
DEFINE('RC', '$(RC) /nologo /d _USING_V110_SDK71_');
Also, add the following line to C:\php-src\ext\standard\config.w32
:
ADD_FLAG('CFLAGS_BD_EXT_STANDARD', ' /wd4047 /wd4018 ');
And finally, add this line to C:\php-src\sapi\cli\config.w32
:
ADD_FLAG('CFLAGS_BD_SAPI_CLI', ' /wd4018 ');
Bonus: best resources on PHP extension development
- Extension Writing Part I: Introduction to PHP and Zend
- Extension Writing Part II: Parameters, Arrays, and ZVALs
- Extension Writing Part II: Parameters, Arrays, and ZVALs [continued]
- Extension Writing Part III: Resources
- Wrapping C++ Classes in a PHP Extension
- PHP Extension Writing
- PHP Extensions Made Eldrich: Working with the API ÔÇô the PHP C API
- PHP Extensions Made Eldrich: Classes
- Build your own PHP on Windows
- PHP Internals Book
- Zend API: Hacking the Core of PHP