Link to home
Start Free TrialLog in
Avatar of street9009
street9009Flag for United States of America

asked on

Compiling PHP for Windows - Linking Error

I am trying to compile PHP on my own and have gotten all the way down to the nmake step and am getting the errors below. I am enabling the mssql extension so that it outputs the DLL so that's where this hangup is occuring.

php_mssql.obj : error LNK2019: unresolved external symbol _compiler_globals referenced in function _php_mssql_message_handler
php_mssql.obj : error LNK2019: unresolved external symbol _executor_globals referenced in function __close_mssql_link
php_mssql.obj : error LNK2019: unresolved external symbol _le_index_ptr referenced in function _php_mssql_do_connect
php_mssql.obj : error LNK2019: unresolved external symbol _zval_used_for_init referenced in function __mssql_fetch_batch
php_mssql.obj : error LNK2019: unresolved external symbol _zend_standard_class_def referenced in function _zif_mssql_fetch_object
Release\php_mssql.dll : fatal error LNK1120: 5 unresolved externals NMAKE : fatal error U1077: '"c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\Bin\cl.exe"' : return code '0x2'

Open in new window

How do you resolve errors like those?
Avatar of Dave Baldwin
Dave Baldwin
Flag of United States of America image

I think you should click on "Request Attention" and get the Visual C zone added to your question.  Those are VC errors, not PHP errors.
Avatar of street9009


Thanks Dave. I've done exactly that.
unresolved externals means that the linker doen't find code for those symbols.

in visual studio project settings you need to go to linker settings and then use input tab. here you could add the library or object module which resolves the externals. note, those properties are dependent on the configuration. the above errors are for release configuration. if it worked in debug configuration you may look for the linker input libraries there and then choose appropriate release libraries.

if the above symbols are from your own code (look for names 'compiler_globals', 'executor_globals' ... in your code), the problem could be that your code didn't compile (in release mode). then the object file was not built and hence you get the unresolved externals.

The problem is I'm not compiling in Visual Studio. When compiling PHP, there's a command line environment that's used. For reference, I'm following the procedure here:

When I call nmake, that's where I get these errors.
The article refers to Microsoft’s Visual C++ Express and Visual Studio 6.  The version of Visual Studio needs to match the version used to compile Apache.
The version should match. I ran into a problem when I first started this process where it didn't and it was throwing errors. When I followed the instruction on that article on a fresh setup, the version problems went away.

I'm not sure what you mean when you're referencing Apache though since this is Windows. I may be missing something.
the nmake would execute a generated makefile which most likely calls cl to build the dll from sources.  

can you post the makefile such that we could see which sources and libraries were used?

generally, 5 unresolved externals is not so much. the names sound to be global variables rather than functions. if that is right, it is more likely a source file was missing (which would provide the missing global variables) rather than a library.

if you have the visual studio ide installed, you could use it to search for source files (*.cpp;*.c) which contain the missing variables (note, don't search for the prefix underline character cause it was added by the compiler).

Apache runs on Windows quite nicely.  I have it running on 3 different Windows machines in 3 different versions.  If you are using it with PHP on Windows, the compiler versions need to match or they will have trouble talking to each other.
Yep, that's exactly what's happening. I've attached the Makefile.
And Dave- I might try that sometime. I use IIS without any real trouble and I've never really fooled with Apache too much (not sure how to properly administer it, etc.) but I'll give it a look. Does Apache still use the Windows DLLs or the Linux ones?
Apache on Windows can use the TS Thread Safe versions of PHP, IIS needs the NTS Non-Thread Safe versions of PHP.
i looked at the makefile. it contains

MSSQL_GLOBAL_OBJS= $(BUILD_DIR)\ext\mssql\php_mssql.obj

Open in new window

which probably is the link to the missing globals.

you might look whether the file php_mssql.obj exists and has an up-to-date timestamp.

the object file should have been compiled by the following statement.

@$(CC) $(CFLAGS_MSSQL_OBJ) $(CFLAGS) $(CFLAGS_BD_EXT_MSSQL) /c ext\mssql\php_mssql.c /Fo$(BUILD_DIR)\ext\mssql\php_mssql.obj

Open in new window

here the compiler (CC) should compile php_mssql.c and create php_mssql.obj.

i would assume that php_mssql.c contains the missing symbols (you may open the source and look for those names). if so you have to find out why those symbols only were declared and not defined. it is much likely that any of CFLAGS_MSSQL_OBJ or CFLAGS_BD_EXT_MSSQL is responsible for that.

I traced the problem but I'm not sure how to fix.

php_mssql.c includes php_globals.h. php_globals.h includes zend_globals.h. Inside zend_globals.h are these lines:

/* Define ZTS if you want a thread-safe Zend */
#undef ZTS

#ifdef ZTS

ZEND_API extern int compiler_globals_id;
ZEND_API extern int executor_globals_id;


Open in new window

The #undef ZTS was commented. I'm compiling non-threadsafe PHP so I uncommented it hoping it would fix my compiler errors but it didn't.

Does that appear to be the issue?
Avatar of sarabande
Flag of Luxembourg image

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
It looks like they're defined in zend.c.

#ifdef ZTS
ZEND_API int compiler_globals_id;
ZEND_API int executor_globals_id;
static HashTable *global_function_table = NULL;
static HashTable *global_class_table = NULL;
static HashTable *global_constants_table = NULL;
static HashTable *global_auto_globals_table = NULL;
static HashTable *global_persistent_list = NULL;

Open in new window

But even when I moved the definitions outside of that if, it is still outputting the errors.
Also, I'm looking at the two functions that are referenced and I have no idea what it considers the unresolved external symbol.

/* {{{ _close_mssql_link
static void _close_mssql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
	mssql_link *mssql_ptr = (mssql_link *)rsrc->ptr;

	mssql_ptr->valid = 0;
	zend_hash_apply(&EG(regular_list),(apply_func_t) _clean_invalid_results TSRMLS_CC);
/* }}} */

/* {{{ php_mssql_message_handler
/* message handler */
static int php_mssql_message_handler(DBPROCESS *dbproc, DBINT msgno,int msgstate, int severity,char *msgtext,char *srvname, char *procname,DBUSMALLINT line)

	if (severity >= MS_SQL_G(min_message_severity)) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "message: %s (severity %d)", msgtext, severity);
	if (MS_SQL_G(server_message)) {
		MS_SQL_G(server_message) = NULL;
	MS_SQL_G(server_message) = estrdup(msgtext);
	return 0;
/* }}} */

Open in new window

I got it. There were more .h files in the top of php_mssql.c that weren't being referenced in their proper location. Once I got those pointed in the right place the build succeeded.

Thank you everyone for all your help!

Sara- I accepted your answer and awarded you the points.

Dave- you've been such a help to me over the past few questions I've posted- is it against the rules to create a bogus question so I can accept your answer as a thank you for the help?