Windows 下最详细的源码编译 PHP 以及 PHP 扩展
概述
我平常开发php扩展是在linux系统上,而扩展都是采用编译安装方式添加扩展,
但是由于开发php-opencv扩展的的时候有扩展的使用者问我能不能提供window的扩展dll引用文件。
所以最近在考虑支持window平台,总结一下window下开发php扩展和编译成dll的经验,
官方文档
其实php官方是有提供扩展编译成window的dll的官方文档,
当时没细看官方文档,自己白捣鼓了几天。
1.环境准备
这里要细说一下环境,在官方文档中说到的环境要求,Visual Studio环境可以直接用Visual Studio ide进行安装,
之前一直以为是指Visual C++ ,所以运行phpsdk-vc15-x64
会出现Could not deternine 'vc15' directory
的错误,
php编译成dll的环境可以使用这个ide进行安装
1.1安装Visual Studio(IDE)
到官网下载Visual Studio Install
1.2 添加编译环境
在Visual Studio Professional 2017
下选择修改后,选在对应的环境安装
这样需要的环境就已经准备好了
2.编译前准备,设置构建目录
2.1 php-sdk-binary-tools
php-sdk-binary-tools是有官方提供的工具,
1.下载php-sdk-binary-tools
git clone https://github.com/Microsoft/php-sdk-binary-tools
cd php-sdk-binary-tools
2.调用启动脚本,例如我这里是php7.2,对应Visual Studio 2017 64位版本,调用phpsdk-vc15-x64.bat,
运行会发现cmd窗口开头会变成$
符号。
3.运行phpsdk_buildtree批处理脚本,该脚本将创建所需的目录结构:
phpsdk_buildtree phpdev
会发现运行后在php-sdk-binary-tools
中多出一个phpdev
的目录
phpsdk_buildtree脚本将根据当前使用的VC ++版本创建路径,并切换到新创建的目录
4.将PHP源代码解压缩到,其中:F:\www\php-sdk-binary-tools\phpdev\vc##\x##
,
在解压缩PHP源的同一目录中,有一个deps目录。
vc##
是您正在使用的编译器版本(eq vc15)x##
是你的构建的系统位数(x86或x64)- 例如我这里是:
F:\www\php-sdk-binary-tools\phpdev\vc15\x64\php-7.2.12-src
5.进入解压的php源码目录,运行phpsdk_deps -u
或phpsdk_deps --update --branch master
,php会自动下载 需要的依赖包(php7以前需要手动下载php-dsp文件)
3.编译php
3.1 构建配置的环境
上面已经将编译前的构建准备环境好了,编译前在php-sdk-binary-tools中调用starter脚本以自动设置所需构建配置的环境phpsdk-vc15-x64.bat
,
3.2 执行buildconf
切换到php源码根目录
,然后执行buildconf
命令。
如果提示输入错误: 没有文件扩展“.js”的脚本引擎。
这里主要原因是:系统安装IDE(Dreamwear、UltraEdit、EditPlus,我之前安装phpstorm修改了)后后修改了.js文件的默认打开方式。
当想直接执行js脚本时就会出现此错误。
快捷键win + r
,然后输入regedit
,打开注册表编辑器,定位[HKEY_CLASSES_ROOT.js]这一项,双击默认值将其改为“JSFile”即可。如图所示:
然后就可以执行成功了
3.3 编译配置
执行以下命令进行编译php配置:
configure --disable-all --enable-cli
注意:可以自己适当调整,参数可以使用configure --help
查看,如
configure --disable-all --enable-cli --enable-debug --with-all-shared
执行成功后会提示执行nmake
执行这一步会在main
目录下生成config.w32.h
文件,编译php扩展
会需要用到这个文件,
所以如果是编译php扩展则执行下一步nmake
,如果是只是php编译扩展可以不执行`nmake
3.4 执行nmake编译
然后执行nmake
开始编译
等待数分钟后,在php-src 目录应该够找到能够多了一个编译位数的目录
(x32或x64),在目录下有 Release_TS (或者 Release_NTS 或者 Debug_TS ) 这样的目录
如果编译正常的话 这下面会有 php.exe 文件 证明编译php文件成功.
运行编译好的 php.exe -v
查看是否正常运行
4.编译php扩展
4.1 创建php扩展
如果我们只是编译某些已经开放好的扩展源码,可以不用运行这一步,这里创建一个demo扩展进行编译。
使用git bash
进入到源码的地址\ext
目录,执行:
php.exe ext_skel_win32.php --extension=my_function
注:这里为什么要使用git bash工具,是因为git bash自带模拟linux环境,my_function
为我这里需要创建的扩展,具体可以根据自己更改
执行工具创建时不是提示'sh' is not recognized as an internal or external command,
git bash
执行结果:
可以看到在源码ext目录下多了一个my_function
的目录,这个就是我们刚刚使用使用ext_skel_win32.php
命令出创建的初始扩展代码
4.2 修改源码
1.我们编辑my_function
下的my_function.c
文件。
添加一个方法my_function_test方法,代码如下:
PHP_FUNCTION(my_function_test) {
php_printf("This is my function PHP extension! \n");
}
2.然后将PHP_FE(my_function_test, NULL)
添加到const zend_function_entry my_function_functions[]
中,但要放在PHP_FE_END
前:
4.3 编译扩展
切换回window的cmd
1.进入php-sdk-binary-tools
目录使用phpsdk-vc15-x64.bat
2.切换到php源码目录,运行buildconf
3.在执行完buildconf
后如果执行configure
命令,会提示类似以下错误:
打开提示的文件,找到对应的行数,发现结尾多出多余的注释符号。这里可能是工具的问题,
解决方法:打开扩展源码的config.w32
,找到// Otherwise, use ARG_ENABLE
这句注释删除,重新运行buildconf
就可以了。
注意:
- 删除的注释是你需要编译参数的上面的注释,这里看
ARG_WITH
还是ARG_ENABLE
,只要删除对应上面的注释即可 ARG_WITH
和ARG_ENABLE
不可同时开启
运行configure --help
会发现多出--enable-my_function
选项:
4.运行configure --disable-all --enable-cli --enable-my_function=shared
进行编译配置:
发现报错提示:
F:\www\php-sdk-binary-tools\phpdev\vc15\x64\php-7.2.12-src\configure.js(5490, 2) Microsoft JScript 运行时错误: 'PHP_EXTNAME_SHARED' 未定义
解决办法:重新打开扩展的config.w32
文件,将下图, PHP_EXTNAME_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
删除
重新开始buildconf
->运行编译配置命令
,可以看到编译配置成功提示Enable extensions:
多出我们的扩展:
5.运行nmake
命令进行编译,等待几分钟到十几分钟后,终端如果出现类似下面编译成功自己即表示编译成功
并且在源码目录下发现多了一个x64
的目录,如果编译的事32位则是x86
,
里面有一个Release_TS
(release表示非debug,相对应为debug,TS为线性安全,相对应为NTS),
里面的文件就是我们所编译的出来的php文件,并且发现有php_my_function.dll
文件就是我们编译出来的扩展文件。
6.配置php.ini引用编译的扩展
进入编译好的目录,运行php.exe -v
测试是否编译正常
运行php.exe --ini
命令,会发现没有配置文件,并且运行php.exe -m
会发现没有PHP Modules
中没有我们创建的my_function
扩展模块
复制源码中的php.ini-development
到编译好的目录中,修改名字为php.ini
,然后修改php.ini
文件
原来:
; On windows:
; extension_dir = "ext"
改为:
; On windows:
extension_dir = "./"
并且:
再次运行php -m
测试
7.测试
添加一个测试文件test.php
<?php
my_function_test();
然后运行编译生成的php目录\php.exe test.php
到这里window下编译php和编译php扩展就已经成功了。
迭代
- 2018年11月17日 15:45 初稿
- 2018年11月20日 22:26 添加最后编译php步骤
- 2019年01月13日 14:30 编译后配置和测试
参考
本作品采用《CC 协议》,转载必须注明作者和本文链接
TS = Thread Safe = 线程安全
另外,Visual Studio 就是 Visual Studio,猜测你说的
Visual Studio C++
应该是老版本的Visual C++
。再其次,建议安装 Community 版本,免费。
@Wi1dcard 谢谢指正,环境名称是
Visual C++
,我把它和ide的名称搞混淆了。蛮复杂的,另外Linux下的php-opencv扩展有地址吗
@lovecn github地址:https://github.com/hihozhou/php-opencv
这有遇到过得吗?求指教 visual studio 2019 / 2017都试过了
大佬