将PHP扩展编译为非线程安全的

时间:2012-04-10 07:06:18

标签: php windows compilation

我正在尝试编译imagemagick(imagick)扩展,以便在Windows上的非线程安全环境中使用。

我正在使用PHP 5.3.10并将Visual C ++ express设置为我的编译环境。 问题是我在Apache 2.2中使用非线程安全的PHP版本作为FCGI模块。

因此,我的PHP提供了php5.lib而不是php5ts.lib。我相信这就是我收到这些错误的原因:

imagick.obj : error LNK2019: unresolved external symbol __imp__tsrm_mutex_alloc referenced in function _zm_startup_imagick

我只在linux上构建和编译过东西,所以我不太清楚如何在Windows环境下执行此操作。

如何编译扩展名以使其不是线程安全的?


我下载了PHP 5.3.10的threadsafe二进制文件来获取php5ts.lib的副本。然后我就可以编译扩展名了。

我猜测将ZTS预处理程序指令设置为10将导致扩展编译为线程安全或非线程安全。 (对此不太确定,如果有人能告诉我这是否正确,那将非常感激。:))

然后我设置了运行Windows 7的虚拟机并安装了最新版本的WAMP。原因是它使用了PHP的线程安全版本。

我将dll放在PHP安装的ext文件夹中,并在php.ini中启用它。但是,即使在WAMP中尝试了ts和nts版本之后,我也会得到:

PHP Warning:  PHP Startup: Unable to load dynamic library 'c:/wamp/bin/php/php5.3.10/ext/imagick.dll' - The specified module could not be found.
 in Unknown on line 0

但问题是c:/wamp/bin/php/php5.3.10/ext/imagick.dll'确实存在,是的,我已经检查了很多次。

然后我将ImageMagick降级为6.6.2-10-Q16,但仍然看到同样的问题。

在Apache 2.2上运行nts版本的PHP 5.3.10的dev机器上也出现了同样的问题(全部手动安装)。


看起来我对ZTS预处理器错了。如果我设置ZTS=0并编译,在编译后的dll上使用依赖walker仍然表明它需要php5ts.dll,它只出现在PHP的线程安全版本上。


我做了更多修补依赖性walker,发现我必须统计链接到msvc100d.dll。然后我在预处理器定义中删除了ZTS,并且能够使用php5.lib而不是php5ts.dll进行编译。我认为这应该让我得到一个非ts dll。

然而,在加载扩展程序时,我仍然得到:

PHP Warning:  PHP Startup: Invalid library (maybe not a PHP library) 'imagick.dll' in Unknown on line 0

来自依赖者沃克的错误:

Error: At least one module has an unresolved import due to a missing export function in an implicitly dependent module.
Error: Modules with different CPU types were found.
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

安装了visual c ++ express 2008并使用platform toolkit v90编译,但仍面临同样的问题。

任何提示赞赏:)


找到解决方案!看我的答案。

2 个答案:

答案 0 :(得分:6)

知道了!我希望这可以帮助那些将来在windows上编译php扩展的人。我所做的是基于:https://wiki.php.net/internals/windows/stepbystepbuild

注意:我在本网站上读到一个答案,说不支持在Windows上自行编译PHP扩展。根据我昨天的实验,它似乎也有很多工作,所以我使用PHP构建过程。

最好的方法是使用PHP构建过程。

  1. 安装Visual C ++ Express 2008(任何版本都可以,但是express是免费的)和Windows SDK 6.1(请注意,我们希望6.1版本不是更旧或更新版本。)

  2. 如果您尚未安装,请安装SVN client tools并重新启动,以使PATH变量生效。

  3. 获取PHP SDK binary tools并将其解压缩为C:\php-sdk

  4. 在开始菜单中的CMD Shell下启动Microsoft Windows SDK v6.1并运行cd C:\php-sdk

  5. 运行setenv /x86 /xp /release这会创建一个32位版本。您可以使用/x64构建一个64位版本(我没有尝试过这个)。

  6. 运行bin\phpsdk_setvars.bat

  7. 运行bin\phpsdk_buildtree.bat php53dev

  8. 下载PHP source code并将其解压缩至C:\php-sdk\php53dev\vc9\x86,以便最终得到C:\php-sdk\php53dev\vc9\x86\php5.3-xyz

  9. 下载最新的deps并将所有内容解压缩到C:\php-sdk\php53dev\vc9\x86。系统可能会提示您覆盖任何现有文件夹,因此请按“是”。

  10. 运行cd C:\php-sdk\php53dev\vc9\x86

  11. 从svn存储库中查看最新版本的扩展程序:svn co http://svn.php.net/repository/pecl/imagick/trunk pecl/imagick我在这里查看了想象力。

  12. 安装所有依赖项。在我的情况下,我需要安装ImageMagick,所以我下载了最新推荐的windows binary。您需要在安装后重新启动才能更新PATH变量,但您可以在编译后执行此操作。确保安装C / C ++标头并包含。

  13. includes目录的内容从ImageMagick安装目录复制到C:\php-sdk\php53dev\vc9\x86\deps\include

  14. lib目录的内容从ImageMagick安装目录复制到C:\php-sdk\php53dev\vc9\x86\deps\lib

  15. 现在,让我们构建:运行cd C:\php-sdk\php53dev\vc9\x86\php5.3-xyz然后buildconf然后configure --help。正确看待帮助。它将显示所有配置标志和启用的任何可用扩展。就我而言,由于我添加了imagick,我有一个名为--with-imagick

  16. 的选项
  17. 运行config:configure --enable-cli --with-imagick=shared --disable-zts如果要构建非线程安全的二进制文件,请使用--disable-zts,否则删除该配置标志。我不确定原因,但有时扩展使用--with-myextension标记,有时使用--enable-myextension,因此请检查configure --help以查看要使用的标记。如果在扩展标志之后添加=shared,它将被编译为单独的DLL,这就是我们想要的。

  18. 编译:运行nmake然后nmake snap

  19. 完成:)检查C:\php-sdk\php53dev\vc9\x86\php-5.3.10\Release(非线程安全)或C:\php-sdk\php53dev\vc9\x86\php-5.3.10\Release_TS(线程安全)。你编译的二进制文件应该在那里。已编译的扩展(pecl)应该在与pecl-5.3.10-nts-Win32-VC9-x86.zip类似的ZIP文件中。打开此文件并将extensio DLL解压缩到PHP安装中的ext文件夹。

  20. 启用PHP扩展并重新启动您的网络服务器。运行phpinfo()并检查扩展程序是否已启用。

  21. 如果扩展程序无法正常运行,请确保重新启动以更新PATH变量。就我而言,我需要在PATH变量中安装imagemagick安装目录。

  22. ???

  23. 利润!

答案 1 :(得分:0)

你需要编译吗?为什么不下载?它通常在Windows上更简单/更快。

VC6:http://www.sk89q.com/2010/03/vc6-windows-binaries-for-imagick-2-3-0/

VC9:http://valokuva.org/builds/