Writing PHP extensions for Windows–Building a compile environment.

In this article, we will be concentrating on creating a Microsoft Visual Studio 2010 Project that includes all the necessary PHP includes and libraries. Note, we will be focusing on building a PHP extension that runs on  Windows XP Pro IIS 5.1. From a previous article “Writing PHP extensions for Windows–Installation on our Virtual Box test environment”, we used PHP 5.4.28 as our base, the reason is that versions later than 5.4.28 the support for Windows XP has been discontinued. This article will cover how to make a build environment, the principles and methods for constructing a later version of PHP on a different OS (say Windows 7) are going to be similar.

Create a Visual 2010 Console “DLL” project.

A PHP extension is a DLL Dynamic Link Library. It gets loaded when the PHP parser programs are loaded by the web serve prior to executing a PHP script,  For IIS the PHP parser program is PHP-CGI.EXE.

Let’s call our project phpTestModule.

1

2

Ensure that your runtime library for your Debug Configuration is “Multi-threaded Debug” and for  a Release Configuration it should be “Multi-threaded”. This means that the Microsoft libraries are statically linked into your application. When you do this, your DLL (your extension) is not dependent on the MFC DLL’s. You don’t have to distribute these MFC DLL’s with your extension.

3

Close Visual Studio.

Incorporating the sources and libraries obtained from PHP windows website to your Visual Studio 2010 project.

The files used in the following steps are taken from http://windows.php.net/download/

  1. Unzip the  php-5.4.28-src.zip to a subdirectory called php-5.4.28-src next to your project directory “phpTestModule” .
  2. Create a directory called php-5.4.28-lib next to “phpTestModule”.
  3. From php-5.4.28-nts-Win32-VC9-x86.zip get php5.lib from subdirectory dev and place it inside subdirectory  php-5.4.28-lib.
  4. 5

Open your Visual Studio 2010 project.

Configure “Additional Include Directories” for All Configurations.

6

Configure “Additional Library Directories”

7

Modify “targetver.h” to make it Windows XP compliant.


#define WINVER _WIN32_WINNT_WINXP 
#include <SDKDDKVer.h>

Modify “stdafx.h”

#pragma once
#include "targetver.h"

#define WIN32_LEAN_AND_MEAN 
// Windows Header Files:
#include <windows.h>

#define ZTS 1
#define ZEND_WIN32 1
#define PHP_WIN32 1
#include <php.h>

#pragma comment(lib, "php5.lib")
// note the pragma comment tells Visual Studio 
// that when it does a link to include "php5.lib". 
// I prefer doing it this way rather than placing 
// it in the
// configuration screens

At this point these are the only changes we have made to our source files.

Do a  Compile

You will get an error

Compile error:

zend\zend_config.w32.h(25): fatal error C1083: Cannot open include file: ‘../main/config.w32.h’: No such file or directory

To resolve this:

copy php-5.4.28-src\win32\build\config.w32.h.in to php-5.4.28-src\main\config.w32.h

Compile again

You will get these errors (Note, I truncated a couple of lines) :

stdafx.cpp

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\sys\stat.inl(42): error C2466: cannot allocate an array of constant size 0

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\sys\stat.inl(47): error C2466: cannot allocate an array of constant size 0

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\sys\utime.inl(37): error C2466: cannot allocate an array of constant size 0

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\sys\utime.inl(42): error C2466: cannot allocate an array of constant size 0

1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\time.inl(79): error C2664: ‘_time32’ : cannot convert parameter 1 from ‘time_t *’ to ‘__time32_t *’

1>          Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

1>

1>Build FAILED.

To resolve modify php-5.4.28-src\main\config.w32.h and comment out the following:

#ifndef _WIN64
#define _USE_32BIT_TIME_T 1
#endif
#define HAVE_STDLIB_H 1

Compile successful but link errors

 

1>stdafx.obj : error LNK2005: _getwchar already defined in dllmain.obj

1>stdafx.obj : error LNK2005: _putwchar already defined in dllmain.obj

1>stdafx.obj : error LNK2005: _acosl already defined in dllmain.obj

1>stdafx.obj : error LNK2005: _asinl already defined in dllmain.obj

1>stdafx.obj : error LNK2005: _atanl already defined in dllmain.obj

I have visited a lot of links that point  to several remedies ranging from removing stdafx.cpp, using no default libraries, renaming all your cpp files into c  without giving a clear explanation as to what causes this.

Note, getwchar(), putwhcar() are members of <wchar.h>  the acosl(), sinl() atanl() are members of <math.h>.

This is what happens, in your .cpp program, it includes “stdafx.h” . Note, <php.h> gets included when you incorporate stdafx.h. Somehow the functions in <math.h> and <wchar.h> gets reimplemented in your cpp program from this inclusion. Since you include stdafx.h througout you have multiple copies of these in each cpp source causing the error listed above.

A more elegant resolution would be to modify your stdafx.h to include <math.h> and <wchar.h> prior to <php.h> like this.

#pragma once
#include "targetver.h"

#define WIN32_LEAN_AND_MEAN 
// Windows Header Files:
#include <windows.h>

#define ZTS 1
#define ZEND_WIN32 1
#define PHP_WIN32 1
#include <math.h>
#include <wchar.h>

#include <php.h>

#pragma comment(lib, "php5.lib")
// note the pragma comment tells Visual Studio 
// that when it does a link to include "php5.lib". 
// I prefer doing it this way rather than placing 
// it in the
// configuration screens

Compile and Link Successful.

 

Next, creating our PHP Extension.

Advertisements

6 thoughts on “Writing PHP extensions for Windows–Building a compile environment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s