# 5.2 编译我们的扩展
我们已经在上一节准备好了需要编译的源文件,接下来需要的便是把它们编译成目标文件了。因为在*nix平台和win平台下的编译步骤有些差异,所以这个地方需要分成两块介绍,很不幸,win部分还没有整理,请随时关注本项目。
### 在*nix下编译
第一步:我们需要根据config.m4文件生成一个configure脚本、Makefile等文件,这一步有phpize来帮我们做:
````c
$ phpize
PHP Api Version: 20041225
Zend Module Api No: 20050617
Zend Extension Api No: 220050617
````
The extra 2 at the start of Zend Extension Api No isn't a typo; it corresponds to the Zend Engine 2 version and is meant to keep this API number greater than its ZE1 counterpart.
现在查看一下我们扩展所在的目录,会发现多了许多文件。phpize程序根据config.m4里的信息生成了许多编译php扩展必须的文件,比如生成makefiles等,这为我们省了很多的麻烦。 接下来我们运行./configure脚本,这里我们并不需要再注明enable-maintainer-zts、enable-debug等参数,phpize程序会自动的去已经编译完成的php核心里获取这几个参数的值。 接下来就像我们安装其它程序一样执行make; make test;即可,如果没有错误,那么在module文件夹下面便会生成我们的目标文件 —— walu.so。
### 在windows平台下编译
The config.m4 file you created earlier was actually specific to the *nix build. In order to make your extension compile under Windows, you'll need to create a separatebut similarconfiguration file for it.
Add config.w32 with the following contents to your ext/sample directory:
````c
ARG_ENABLE("sample", "enable sample extension", "no");
if (PHP_SAMPLE != "no") {
EXTENSION("sample", "sample.c");
}
````
As you can see, this file bears a resemblance on a high level to config.m4. The option is declared, tested, and conditionally used to enable the build of your extension.
Now you'll repeat a few of the steps you performed in Chapter 4, "Setting Up a Build Environment," when you built the PHP core. Start by opening up a build window from the Start menu by selecting All Programs, Microsoft Platform SDK for Windows Server 2003 SP1, Open Build Environment Window, Windows 2000 Build Environment, Set Windows 2000 Build Environment (Debug), and running the C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat batch file.
Remember, your installation might require you to select a different build target or run a slightly different batch file. Refer to the notes in the corresponding section of Chapter 4 to refresh your memory.
Again, you'll want to go to the root of your build directory and rebuild the configure script.
````c
C:\Program Files\Microsoft Platform SDK> cd \PHPDEV\php-5.1.0
C:\PHPDEV\php-5.1.0> buildconf.bat
Rebuilding configure.js
Now run 'cscript /nologo configure.js help'
````
This time, you'll run the configure script with an abridged set of options. Because you'll be focusing on just your extension and not the whole of PHP, you can leave out options pertaining to other extensions; however, unlike the Unix build, you do need to include the enable-debug switch explicitly even though the core build already has it.
The only crucial switch you'll need hereapart from debug of courseis enable-sample=shared. The shared option is required here because configure.js doesn't know that you're planning to build sample as a loadable extension. Your configure line should therefore look something like this:
````c
C:\PHPDEV\php-5.1.0> cscript /nologo configure.js \
enable-debug enable-sample=shared
````
Recall that enable-maintainer-zts is not required here as all Win32 builds assume that ZTS must be enabled. Options relating to SAPIssuch as embedare also not required here as the SAPI layer is independent from the extension layer.
Lastly, you're ready to build the extension. Because this build is based from the coreunlike the Unix extension build, which was based from the extensionyou'll need to specify the target name in your build line.
````c
C:\PHPDEV\php-5.1.0> nmake php_sample.dll
````
Once compilation is complete, you should have a working php_sample.dll binary ready to be used in the next step. Remember, because this book focuses on *nix development, the extension will be referred to as sample.so rather than php_sample.dll in all following text.
Loading an Extension Built as a Shared Module
### 加载扩展
为了使PHP能够找到需要的扩展文件,我们需要把编译好的so文件或者dll文件复制到PHP的扩展目录下,它的地址我们可以通过phpinfo()输出的信息找到,也可以在php.ini文件里进行配置找到并配置,名称为:extension_dir的值。默认情况下,php.ini文件位于/usr/local/lib/php.ini或者C:\windows\php.ini(现在由于fastcgi模式居多,在win平台上php.ini越来越多的直接存在于php-cgi.exe程序所在目录下)。如果找不到,我们可以通过php -i 命令或者<?php phpinfo();来查看当前加载的php.ini文件位置。
一旦我们设置了extension_dir,便可以在我们的web文件中引用我们的扩展了,我们可以通过dl命令来将我们的扩展加载到内存中来。
````php
<?php
dl('sample.so');
var_dump(get_loaded_extensions());
?>
````
如果在输出中我们没有找到walu.so,那肯定是哪里出问题了。这时候我们需要根据程序的输出信息去查找错误。
上面这样每次使用扩展都需要先dl一下真是太麻烦了,其实我们有更好的办法让php运行时自动加载我们的扩展。那就是在php.ini里这样配置:
````c
extension_dir=/usr/local/lib/php/modules/
extension=walu.so
````
这样只要我们把walu.so这个文件放置在extension_dir配置的目录下,php就会在每次启动的时候自动加载了。这样我们就可以像我们平时使用curl、Mysql扩展一样直接使用,而不用麻烦的调用dl函数了。
备注: 以下的章节我们都默认使用上面的这种方式来加载我们的扩展,而不是调用dl函数。
## links
* 5.1 [一个扩展的基本结构](<5.1.md>)
* 5.3 [静态编译](<5.3.md>)
- about
- 开始阅读
- 目录
- 1 PHP的生命周期
- 1.让我们从SAPI开始
- 2.PHP的启动与终止
- 3.PHP的生命周期
- 4.线程安全
- 5.小结
- 2 PHP变量在内核中的实现
- 1. 变量的类型
- 2. 变量的值
- 3. 创建PHP变量
- 4. 变量的存储方式
- 5. 变量的检索
- 6. 类型转换
- 7. 小结
- 3 内存管理
- 1. 内存管理
- 2. 引用计数
- 3. 总结
- 4 动手编译PHP
- 1. 编译前的准备
- 2. PHP编译前的config配置
- 3. Unix/Linux平台下的编译
- 4. 在Win32平台上编译PHP
- 5. 小结
- 5 Your First Extension
- 1. 一个扩展的基本结构
- 2. 编译我们的扩展
- 3. 静态编译
- 4. 编写函数
- 5. 小结
- 6 函数返回值
- 1. 一个特殊的参数:return_value
- 2. 引用与函数的执行结果
- 3. 小结
- 7 函数的参数
- 1. zend_parse_parameters
- 2. Arg Info 与类型绑定
- 3. 小结
- 8 使用HashTable与{数组}
- 1. 数组(C中的)与链表
- 2. 操作HashTable的API
- 3. 在内核中操作PHP语言中数组
- 4. 小结
- 9 PHP中的资源类型
- 1. 复合类型的数据——{资源}
- 2. Persistent Resources
- 3. {资源}自有的引用计数
- 4. 小结
- 10 PHP中的面向对象(一)
- 1. zend_class_entry
- 2. 定义一个类
- 3. 定义一个接口
- 4. 类的继承与接口的实现
- 5. 小结
- 11 PHP中的面向对象(二)
- 1. 生成对象的实例与调用方法
- 2. 读写对象的属性
- 3. 小结
- 12 启动与终止的那点事
- 2. 小结
- 1. 关于生命周期
- 2. MINFO与phpinfo
- 3. 常量
- 4. PHP扩展中的全局变量
- 5. PHP语言中的超级全局变量
- 6. 小结
- 13 INI设置
- 1. 声明和访问ini设置
- 2. 小结
- 2. 小结
- 14 流式访问
- 1. 概览
- 2. 打开流
- 3. 访问流
- 4. 静态资源操作
- 5. 小结
- 15 流的实现
- 1. php流的表象之下
- 2. 包装器操作
- 3. 实现一个包装器
- 4. 操纵
- 5. 检查
- 6. 小结
- 16 有趣的流
- 1. 上下文
- 2. 过滤器
- 3. 小结
- 17 配置和链接
- 1. autoconf
- 2. 库的查找
- 3. 强制模块依赖
- 4. Windows方言
- 5. 小结
- 18 扩展生成
- 1. ext_skel
- 2. PECL_Gen
- 3. 小结
- 19 设置宿主环境
- 1. 嵌入式SAPI
- 2. 构建并编译一个宿主应用
- 3. 通过嵌入包装重新创建cli
- 4. 老技术新用
- 5. 小结
- 20 高级嵌入式
- 1. 回调到php中
- 2. 错误处理
- 3. 初始化php
- 4. 覆写INI_SYSTEM和INI_PERDIR选项
- 5. 捕获输出
- 6. 同时扩展和嵌入
- 7. 小结
- 约定