[Xapian-devel] Problems building PHP extension for Xapian bindings on Windows

Charlie Hull charlie at juggler.net
Fri Sep 29 15:10:13 BST 2006


Hi all,

I've been attempting to build the PHP bindings on Windows using Visual 
C++ and have run into some serious problems. I thought I'd let everyone 
know in case someone can suggest a solution. I'm using the Visual C++ 
2003 toolkit, the Platform SDK, PHP 4.4.3 sources and the PHP 4.4.3 
Windows binaries, and the attached make file.

Xapian bindings are to be built as a PHP extension, necessitating 
linking with the PHP libraries (PHP4TS.LIB or PHP5TS.LIB) supplied with 
the binary version of PHP. However PHP extensions must be built to use a 
'shared DLL' version of the Windows runtime libraries, using the /MD or 
/MDd compiler options, as this is how PHP itself is built.

However attempting to build the SWIG-generated bindings (xapian_wrap.cc 
etc.) using Visual C++ using /MD causes various problems:

1. Errors are produced while compiling around line 1110 of xapian_wrap.cc:
#include <string>
   which leads inside the Microsoft header <ostream>, at line 921:
error C2491: 'std::endl' : definition of dllimport function not allowed
   Moving this #include to the beginning of the file fixes this error 
for now.

2. Linking (to a version of the Xapian core also built with /MD, which 
causes other problems but we'll gloss over those for now) causes many 
errors of the form:

liblanguages.lib(api.obj) : error LNK2001: unresolved external symbol 
"__declspec(dllimport) public: __thiscall std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> 
 >::basic_string<char,struct std::char_traits<char>,class 
std::allocator<char> >(char const *)" (__imp_??0?$basic_string at DU?$char
_traits at D@std@@V?$allocator at D@2@@std@@QAE at PBD@Z)

3. After some research I found various information suggesting that it's 
difficult to export bits of the STL in a DLL, although Microsoft 
suggests it's possible in a very messy way:
http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b168958
Someone else said 'The STL is a way to share code, so is a DLL - but 
they don't play nice together'.

I'm unfortunately going to have to leave this now as I'm off to 
Australia for a month soon, but I thought it worth posting in case 
anyone else is attempting something similar, or can think of any clever 
workarounds.

Cheers

Charlie
Lemur
-------------- next part --------------
# Makefile for Microsoft Visual C++ 7.0 (or compatible)
# By Charlie Hull, Lemur Consulting Ltd.
# www.lemurconsulting.com
# 25th September 2006

# Will build the PHP bindings for PHP 4.4.3
# You will need to install 4.4.3 to the folder specified below, and copy zend_config.w32.h to zend_config.h
# Uses the Windows prebuilt binaries for testing 

!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE 
NULL=nul
!ENDIF 

# Change this to match your environment
XAPIAN_DIR=\xapian\xapian-core-0.9.6
OUTLIBDIR=$(XAPIAN_DIR)\win32\Release\libs
SWIG=\swigwin-1.3.29\swig.exe

!INCLUDE $(XAPIAN_DIR)\win32\config.mak

XAPIAN_DEPENDENCIES = \
 "$(OUTLIBDIR)\libgetopt.lib"  \
 "$(OUTLIBDIR)\libcommon.lib"  \
 "$(OUTLIBDIR)\libbtreecheck.lib"  \
 "$(OUTLIBDIR)\libtest.lib"  \
 "$(OUTLIBDIR)\libbackend.lib"  \
 "$(OUTLIBDIR)\libquartz.lib" \
 "$(OUTLIBDIR)\libflint.lib" \
 "$(OUTLIBDIR)\libinmemory.lib" \
 "$(OUTLIBDIR)\libmulti.lib" \
 "$(OUTLIBDIR)\libmatcher.lib"  \
 "$(OUTLIBDIR)\liblanguages.lib"  \
 "$(OUTLIBDIR)\libapi.lib"  \
 "$(OUTLIBDIR)\libqueryparser.lib" \
 $(PHP_LIB)

LIB_XAPIAN_OBJS= ".\xapian_wrap.obj" 
PHP_INCLUDE=\php-4.4.3
PHP=\php-4.4.3-win32\php.exe -n -d safe_mode=off -d enable_dl=on -d extension_dir=$(OUTDIR)
PHP_LIB=\php-4.4.3-win32\php4ts.lib 

CPP=cl.exe
RSC=rc.exe

OUTDIR=$(XAPIAN_DIR)\win32\Release\PHP
INTDIR=.\

ALL : "$(OUTDIR)\php_xapian.dll" "$(OUTDIR)\xapian.php" "$(OUTDIR)\smoketest_win32.php"

CLEAN :
	- at erase "$(OUTDIR)\php_xapian.dll"
	- at erase "$(OUTDIR)\php_xapian.exp"
	- at erase "$(OUTDIR)\php_xapian.lib"
	- at erase $(LIB_XAPIAN_OBJS)
	- at erase "$(OUTDIR)\xapian.php"
	- at erase "$(OUTDIR)\smoketest_win32.php"

	
CLEANSWIG :	
	- at erase .\xapian_wrap.cc 
    - at erase .\php_xapian.h 
    - at erase .\xapian.php
	
DOTEST :
	cd "$(OUTDIR)"
	$(PHP) smoketest_win32.php
    
"$(OUTDIR)" :
    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

CPP_PROJ= \
$(CPPFLAGS_EXTRA) \
/W3 /EHsc /GR /MD /O2 \
 /I "$(XAPIAN_DIR)" /I "$(XAPIAN_DIR)\include" /I"." \
 /D "NDEBUG" /D "WIN32" /D "__WIN32__" /D "_WINDOWS" \
 /D "HAVE_VSNPRINTF" /D "HAVE_STRDUP" \
 /Fo"$(INTDIR)\\" /c \
 /I "$(PHP_INCLUDE)\win32" /I "$(PHP_INCLUDE)\zend" /I "$(PHP_INCLUDE)\main" /I "$(PHP_INCLUDE)\tsrm" /I "$(PHP_INCLUDE)" \
 /D PHP_WIN32=1 \
 /D "_MBCS" /D "EXTNAME_EXPORTS"  /D ZEND_DEBUG=0 /D ZTS=1 /D ZEND_WIN32=1 \
 /D ZTS=1 /D COMPILE_DL_EXTNAME  /D HAVE_EXTNAME=1 /D LIBZEND_EXPORTS \
 #/D ZEND_WIN32_FORCE_INLINE
 # /O2
 
  
CPP_OBJS=$(XAPIAN_DIR)\win32\Release\
CPP_SBRS=.

LIB32=link.exe 
LIB32_FLAGS=/nologo  $(LIBFLAGS) \
 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
 advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib \
 wsock32.lib odbccp32.lib /subsystem:console /verbose:lib \
 /nodefaultlib:libc.lib /nodefaultlib:libcp.lib \
 $(XAPIAN_DEPENDENCIES)

.\xapian_wrap.cc .\php_xapian.h .\xapian.php: ..\xapian.i util.i 
	$(SWIG) -I"$(XAPIAN_DIR)" -I"$(XAPIAN_DIR)\include"  -Werror -c++ -php4 -noproxy \
	     -o .\xapian_wrap.cc ..\xapian.i


"$(OUTDIR)\php_xapian.dll" : "$(OUTDIR)" $(DEF_FILE) $(LIB_XAPIAN_OBJS) \
                            $(XAPIAN_DEPENDENCIES)
    $(LIB32) @<<
  $(LIB32_FLAGS) /DLL /out:"$(OUTDIR)\php_xapian.dll" $(DEF_FLAGS) $(LIB_XAPIAN_OBJS)
<<


"$(OUTDIR)\xapian.php" : ".\xapian.php"
	-copy $** "$(OUTDIR)\xapian.php"

"$(OUTDIR)\smoketest_win32.php" : ".\smoketest_win32.php"
	-copy $** "$(OUTDIR)\smoketest_win32.php"

#
# Rules
#

".\xapian_wrap.obj" : ".\xapian_wrap.cc"
     $(CPP) @<<
  $(CPP_PROJ) $**
<<

.c{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $<
<<

.cpp{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cxx{$(CPP_OBJS)}.obj::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.c{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cpp{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<

.cxx{$(CPP_SBRS)}.sbr::
   $(CPP) @<<
   $(CPP_PROJ) $< 
<<


More information about the Xapian-devel mailing list