【问题标题】:Compiling a PHP extension as non-thread-safe将 PHP 扩展编译为非线程安全的
【发布时间】:2012-04-22 11:48:42
【问题描述】:

我正在尝试编译 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 的线程安全二进制文件以获取 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(全部手动安装)。


看起来我对 ZTS 预处理器的看法可能是错误的。如果我设置ZTS=0 并编译,在编译的dll 上使用依赖walker 仍然显示它需要php5ts.dll,这仅存在于PHP 的线程安全版本中。


我对dependency 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并使用平台工具包v90编译,但仍然面临同样的问题。

任何提示表示赞赏:)


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

【问题讨论】:

    标签: php windows compilation


    【解决方案1】:

    知道了!我希望这可以帮助那些将来在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. 在开始菜单中的Microsoft Windows SDK v6.1 下启动CMD Shell,然后运行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 我在这里查看 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. 运行配置:configure --enable-cli --with-imagick=shared --disable-zts 如果要构建非线程安全的二进制文件,请使用 --disable-zts,否则请删除该配置标志。我不知道为什么,但有时扩展使用--with-myextension 标志,有时使用--enable-myextension,因此请检查configure --help 以使用该标志。如果在扩展标志后添加=shared,它将被编译为单独的DLL,这正是我们想要的。

    17. 编译:运行nmake,然后运行nmake snap

    18. 完成 :) 检查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 文件中。打开此文件并将扩展 DLL 解压缩到 PHP 安装中的 ext 文件夹。

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

    20. 如果扩展程序无法正常工作,请确保重新启动以更新您的 PATH 变量。就我而言,我需要将 imagemagick 安装目录放在我的 PATH 变量中。

    21. ???

    22. 利润!

    【讨论】:

    • 感谢您抽出宝贵的时间编写这篇精美的说明。真的很有帮助!
    【解决方案2】:

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

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

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

    【讨论】:

    • 我尝试了来自 Valokuva.org 的构建,但它们在我手动安装的服务器或 WAMP 上不起作用。来自 sk89q.com 的二进制文件也不起作用。这就是为什么我想针对最新版本的 imagemagick 编译 3.1.0b1。
    • 我的意思是 3.1.0rc1 不是 3.1.0b1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2016-03-22
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多