Closed sjayexec closed 14 hours ago
You may also need to declare the symbol, like
By the way, do you have any particular reason for using CMake for your extension, instead of the customary config.m4/config.w32 autotools(-like) builds?
We do use the ZEND_TSRMLS_CACHE_EXTERN()
macro in the php_<extension>.h
header file of our extension to declare it there while it is defined in the <extension>.c
file. All of this works already on Linux.
It is a proprietary extension, so maybe that was the reason to build it outside the PHP build system, I would guess. On Linux, we link only against the PHP headers and let the symbols resolve at runtime when the extension is loaded. But on Windows, this is not possible it seems. So in our CMake configuration, we are linking against the PHP libraries directly and see this error.
We also have a couple more unresolved symbol errors at link-time, I will share more details shortly.
strcasestr()
: I know fileinfo
extension provides some functions for Windows target that are not available natively. But even after enabling fileinfo
extension during PHP build and including the extension's file.h
header file (which declares the function) in our code, the linker fails to find this. I added 'php_fileinfo.lib' as a link library when linking our extension, but no success.
zend_compile_file
: The linker fails to resolve this symbol too on Windows. Not sure if any extra headers need to be included or what compared to linux as it works on that platform.
Update: Ignore this observation - see next comment
You can see here that when we use zend_compile_file
stuff from Zend/zend_compile.h
, the linker fails to link it:
[build] profiler.obj : error LNK2001: unresolved external symbol "void * _tsrm_ls_cache" (?_tsrm_ls_cache@@3PEAXEA) [C:\workspace\abc.vcxproj]
[build] Hint on symbols that are defined and could potentially match:
[build] _tsrm_ls_cache
[build] instana.obj : error LNK2019: unresolved external symbol __imp__zend_compile_file referenced in function zm_startup_instana [C:\workspace\abc.vcxproj]
[build] C:\workspace\abc.dll : fatal error LNK1120: 2 unresolved externals [C:\workspace\abc.vcxproj]
Upon closer look, the linker seems to look for __imp__zend_compile_file
symbol while the php8ts.lib
has __imp_zend_compile_file
symbol - extra underscore (_) before imp
and zend
in the symbol name the linker is searching for.
Please ignore zend_compile_file
related error, we were wrongly declaring _zend_compile_file()
in our extension with prefix underscore. But this is coming from a working linux code, I have to understand why _zend_compile_file()
declaration & usage works on linux but on windows, we need to use only zend_compile_file()
- something to do with the compilers perhaps.
So apart from TSRM symbol error, another issue is with strcasestr()
function symbol not being located. Could you please tell me what is the right way to build PHP with fileinfo
extension and then use strcasestr()
in our extension's code?
We built PHP with fileinfo
extension and in our code, we were including this header file like this:
#ifdef _WIN32
#include <ext/fileinfo/libmagic/file.h>
#endif
and try to link our extension with php_fileinfo.lib But linker fails to find the strcasestr()
symbol.
Please ignore
zend_compile_file
related error
That may have basically the same reason as tsrm_ls_cache
. Both are variables, not functions, so they need __declspec(dllexport)
when building the DLL (or you need to add .def files). I guess that you are not properly including the required headers, or don't have the appriate macros defined. See e.g. https://heap.space/xref/php-src/Zend/zend_config.w32.h?r=79e4ca1e#47.
strcasestr()
is defined in strcasestr.c; maybe you don't link with this file.
Anyhow, this doesn't look like a bug report (nor a feature request), but rather a support question. These should be asked on the available support channels, in this case possibly the Windows Internals List.
The zend_compile_file
error is something wrong on our side. We had _declspec(dllimport) _zend_compile_file
- but the actual name in Zend is zend_compile_file
. We were not trying to forward declare but create a local variable, so using _declspec(dllimport)
is wrong.
But for _tsrm_ls_cache
, we are nowhere using this variable explicitly; we use the TSRM DEFINE, EXTERN, UPDATE macros the usual way most extensions are doing. We enabled PHP_WIN32
, ZEND_WIN32
, ZEND_ENABLE_STATIC_TSRMLS_CACHE
macros and we check for ZTS
before doing #include TSRM.h
.
I will contact the Windows mailing list, thanks for your support!
I've totally overlooked this so far:
[build] file5.obj : error LNK2001: unresolved external symbol "void * _tsrm_ls_cache" (?_tsrm_ls_cache@@3PEAXEA) [C:\workspace\abc.vcxproj]
[build] Hint on symbols that are defined and could potentially match:
[build] _tsrm_ls_cache
There is obviously a name mangling problem.
$ undname ?_tsrm_ls_cache@@3PEAXEA
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?_tsrm_ls_cache@@3PEAXEA"
is :- "void * __ptr64 __ptr64 _tsrm_ls_cache"
Somewhere the compiler doesn't pick up the proper declaration (by (ZEND_)TSRMLS_CACHE_DEFINE()
), and mangles the name.
Description
Description
Building our PHP extension with MSVC (VS Build Tools 2019 + Windows 10 SDK) fails with the linker unable to find
_tsrm_ls_cache
symbol. We are linking against thephp8ts.lib
in our cmake configuration.The PHP runtime is built with ZTS enabled and our extension is also being built with the same compilation flags (
ZTS=1
). We have this flag enabled:ZEND_ENABLE_STATIC_TSRMLS_CACHE=1
which seems to be causing this problem. Removing this TSRM flag makes these linker errors go away. This flag works fine when we compile our extension on Linux with Clang.MSVC linker errors:
PHP SDK & MSVC version
PHP version:
configure
command used to build PHP runtime:We are using these flags on Windows when building our extension:
I looked into the symbols inside
php8ts.lib
library file usingdumpbin /SYMBOLS php8ts.lib
command, there is no_tsrm_ls_cache
symbol in it. But I do find a symbol for it inphp8embed.lib
library. So, I tried disabling embed extension and rebuild PHP but thephp8ts.lib
still does not seem to have_tsrm_ls_cache
.I'm not sure what's going wrong here. We are not doing anything special w.r.t TSRM. We have
ZEND_TSRMLS_CACHE_DEFINE()
if ZTS is enabled in our main extension source code and then inPHP_GINIT_FUNCTION
of our extension, we doZEND_TSRMLS_CACHE_UPDATE()
. This works fine on Linux.To rule out any misconfiguration of my env, I tried this multiple times - with Debug/Release variants, but I see the same result. Could you please help us understand this issue with linking against PHP libraries. Thanks in advance!
PHP Version
PHP 8.3.12-dev
Operating System
Windows 10 SDK (10.0.22631.4460)
Note: Edited the description to keep all observations and printouts from release build to avoid confusion. It happens both for debug & release builds.