欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

[php扩展和嵌入式] -安装构建环境

程序员文章站 2022-05-05 12:35:52
...
安装构建环境

现在你可能至少已经有一个已安装的php, 并且已经使用它做基于web的应用开发了. 你可能已经从php.net下载了win32构建并运行在iis或windows版的apache上, 或者使用你的*nix(linux, bsd, 或其他遵循POSIX的发行)发行版的包管理系统安装了第三方创建的二进制.

构建php

除非你是下载源码包自己编译, 否则你肯定会错过一些知识点.

*nix工具

C开发者工具集中必不可少的第一个工具是C的编译器. 你的发行版中可能会默认包含一个, 如果幸运, 它就是gcc(GNU编译器集合). 你可以通过执行gcc version或cc version检查是否安装了编译器, 如果已经安装, 它会响应已安装的编译器版本信息.

如果你还没有安装编译器, 可以按照你使用的发行版官方指定的方式下载并安装gcc. 通常这就意味着要下载一个.rpm或.deb文件, 并执行一个命令去安装它. 这依赖于你使用的发行版版本, 你可以简单的使用下面命令去尝试安装: urpmi gcc, apt-get install gcc, pkg-add -r gcc, emerge gcc.

除了编译器, 你还需要下面的程序和工具: make, autoconf, automake, libtool. 这些工具同样可以用你所使用的发行版的包管理系统去安装, 和安装gcc时一样, 或者直接从gnu.org下载源码包自己编译.

推荐的版本是: libtool 1.4.3, autoconf 2.13, automake 1.4或1.5. 使用这些软件的更新的版本可能也能很好的工作, 但这些版本是经过长期使用验证的.

如果你计划使用CVS检出最新的php开发版代码, 还需要bison和flex去构造语言解释器. 和其他包一样, 这两个包可以使用你的发行版包管理系统安装, 或者从gnu.org下载源码自己编译.

如果你选择了CVS, 你还需要安装cvs客户端. 同样, 它也可能已经在你的发行版上安装, 或者你自己去下载编译. 和其他包不一样的是这个包你需要在cvshome.org下载.

Win32工具

译者不熟悉windows环境, 因此略过.

获取php源代码

下载php的时候, 你有集中选择. 首先, 如果你的发行版支持, 你可以使用apt-get source php5这样的命令去下载. 这种方式的有点在于你使用的发行版可能存在某些问题需要对php源代码进行修改, 从这里下载, 可以肯定这些问题已经被打补丁使得你的构建存在更少的问题.缺点在于大多数的发行版都会比php官方的发布延迟数周.

另外一个选择是首选项, 在www.php.net下载php-x.y.z.tar.gz(x.y.z是当前发布版本).这些php发布版是经过全世界无数的php用户测试的, 并且是最新的.

你还可以从snaps.php.net下载快照包. 这个站点上, php版本库中所有源代码的最新版本会每隔几小时打包一次.php内核开发者的某些提交可能会导致它暂时不可用, 但是如果你在官方发布之前需要最新的php 6.0的特性, 这是最容易得到的地方.

最后, 你可以使用cvs直接获取到php内核开发团队所使用的开发版. 如果你只是要开发扩展和嵌入式程序, 相比使用官方发布包和获取快照,这不会有什么明显的好处. 但是如果你计划发布你的扩展或其他应用到CVS库, 熟悉检出过程还是很有用的.

译注: php目前已经使用git来管理代码库, 关于cvs检出不再赘述, 请访问https://github.com/php/php-src获取最新源码. 如果你想为php贡献代码, 可以查看该项目首页的介绍.

配置用于开发的php

第一章中我们讨论了, 无论你计划开发扩展还是潜入php的其他应用, 在构建开发者友好的php时有两个特殊的./configure开关你需要使用, 这两个开关应该和你构建php时使用的其他开关一起使用.

enable-debug

在php和zend源码树的某些关键函数上开启调试. 首先它启用了每个请求结束后的内存泄露报告.

回顾第三章"内存管理", ZendMM会隐式的释放每个请求分配的, 但在脚本结束之前没有被释放的内存. 通过在新开发的代码上运行一系列的回归测试用例, 泄露点可以很容易的暴露出来, 这样就可以在发布之间修补. 我们来看看下面的代码片段:

[cpp]

void show_value(int n)

{

char *message = emalloc(1024);

sprintf(message, "The value of n is %d\n", n);

php_printf("%s", message);

}

如果这段愚蠢的代码在php请求执行过程中被执行, 它将泄露1024字节的内存. 一般情况下ZendMM会在脚本执行结束后释放它.

在enable-debug开启时, 就会为开发者提供定位问题的错误消息:

[cpp]

/cvs/php5/ext/sample/sample.c(33) : Freeing 0x084504B8 (1024 bytes), script=-

=== Total 1 memory leaks detected ===

这个短小但完整的消息告诉你ZendMM在你弄脏了内存后它进行了清理, 并给出了泄露的内存块是在哪里分配的. 使用这个信息, 很容易定位问题, 打开文件, 找到对应的行, 在函数结束前适当的位置增加efree(message).

当然, 内存泄露并不是你会碰到的唯一难以追查的问题. 有时候, 问题是潜在的, 很少显现. 比如你通宵达旦的工作, 修改了很多的代码和源文件, 当所有事情做完后, 你自信的执行了make, 测试了一个简单的脚本, 接着就看到了下面的输出:

[cpp]

$ sapi/cli/php -r 'myext_samplefunc();'

Segmentation Fault

这只是表象, 那问题出在哪里呢? 查看你的myext_samplefunc()实现, 并没有显示出什么明显的线索, 使用gdb运行仅显示出一串未知的符号.

同样, enable-debug会帮到你. 通过在./configure时增加这个开关, 结果的php二进制将包含所有gdb以及其他core文件检查程序所需的调试符号, 这样可以显示出问题出在哪里.

使用这个选项重新构建, 通过gdb触发崩溃, 你现在可以看到下面的输出:

[cpp]

#0 0x1234567 php_myext_find_delimiter(str=0x1234567 "foo@#(FHVN)@\x98\xE0...",

strlen=3, tsrm_ls=0x1234567)

p = strchr(str, ',');

目标就变得清晰了. str字符串并不是NULL终止的, 后面的垃圾可以证明这一点, 而非二进制安全的函数使用了它. strchr()实现尝试从头到尾的扫描传入的str, 但由于没有终止NULL字节, 它到达了不属于它的内存, 这就导致了段错误. 我们可以使用memchr()和strlen参数来修复这个问题防止崩溃.

enable-mantainer-zts

这个选项强制php构建启用线程安全资源管理(TSRM)/Zend线程安全(ZTS)层. 这个开关会增加处理时的复杂度, 但是对于开发者而言, 你会发现这是一件好事情. 关于ZTS的详细介绍以及为什么在开发时要开启这个选项, 请参考第一章.

enable-embed

如果你要开发一个嵌入php的其他应用, 就需要另外一个非常重要的开关. 这个开关打开后就会构建出一个类似开启了with-apxs后构建出的mod_php5.so动态链接库: libphp5.so, 它可以用于将php嵌入到其他应用中.

在Unix上编译

现在你已经有了所有需要的工具, 下载了php源码包, 认识了所有需要的./configure开关, 是时候真正的编译php了.

这里假设你下载的是php-5.1.0.tar.gz, 放在了你的主目录, 你将使用下面的命令序列解包源码包, 并切换到解压出的源码目录:

[cpp]

[/home/sarag]$ tar -zxf php-5.1.0.tar.gz

[/home/sarag]$ cd php-5.1.0

如果你使用的不是gnu的tar, 命令可能需要略作修改:

[cpp]

[/home/sarag]$ gzip -d php-5.1.0.tar.gz | tar -xf -

现在, 用所需的开关和其他你想要开启或禁用的选项, 执行./configure命令:

[cpp]

[/home/sarag/php-5.1.0]$ ./configure enable-debug \

enable-maintainer-zts disable-cgi enable-cli \

disable-pear disable-xml disable-sqlite \

without-mysql enable-embed

在一段时间的处理后, 在你的屏幕上输出了很多的信息, 最终完成了./configure阶段. 接下来你就可以开始编译了:

[cpp]

[/home/sarag]$ make all install

现在, 站起来喝杯咖啡吧. 编译的时间在性能高的机器上可能需要几分钟, 在旧的486上甚至可能需要半个小时. 构建处理完成后, 你就拥有了一个正确配置, 功能完整, 可用于开发的php.