subst去掉最后一位php,关于包含第三方库的PHP扩展编译的备注

1.前言

关于php的扩展开发,网上有很多教程,搜一搜有很多.很多的教程已经和实际使用上有了一定的出入了.文本就算是做一个更新吧.

关于第三方库的引用上,我只做一种方法的描述.也许还有更好更简便的方法,希望能和大家有个交流.

现在假设一下我的需求: 有一个复杂的引用了其他第三方静态库的功能库使其能够让php调用.

2.编写扩展

编写之前,我们先大概捋一下,我们有什么,要做些什么.

先说一下主要的功能逻辑都在功能库里封装好了,

php扩展调用就可以了.而功能库又依赖于几个第三方的静态库.(为什么是静态库,不是本文的重点 -_-

). 好了总结下来我们要做如下工作:

1.生成php扩展框架

1.改写php扩展调用功能的.cpp

2.重新编译第三方库 libb1.a libb2.a

libb3.a (为什么要重新编译后面说)

3.重新编译功能库 liba1.a

4.修改扩展框架的Makefile文件

5.再手动编译成完整的扩展库.so

2.1生成框架

生成之前需要写一个以skel后缀的php接口定义文档.把需要的接口都定义出来,以换行分隔.例如:

int test1(string filePath)

bool test2(int maxNum)

void test3(bool isOK)

在php的目录下的ext文件夹下找到ext_skel,把刚才写的skel文件放到该目录下执行:

[root@localhost ext]# ./ext_skel --extname=test

--proto=test.skel

就会在该级目录下生成一个test的文件夹,并提示

Creating directory test

awk: /opt/phpext/php/ext/skeleton/create_stubs:56: 警告:

转义序列“\|”被当作单纯的“|”

NOTICE: lower casing function name 'test1'

NOTICE: lower casing function name 'test2'

Creating basic files: config.m4 config.w32 .gitignore test.c

php_test.h CREDITS EXPERIMENTAL tests/001.phpt test.php [done].

To use your new extension, you will have to execute the

following steps:

1. $ cd ..

2. $ vi ext/test/config.m4

3. $ ./buildconf

4. $ ./configure --[with|enable]-test

5. $ make

6. $ ./sapi/cli/php -f ext/test/test.php

7. $ vi ext/test/test.c

8. $ make

Repeat steps 3-6 until you are satisfied with ext/test/config.m4

and

step 6 confirms that your module is compiled into PHP. Then, start

writing

code and repeat the last two steps as often as necessary.

[root@localhost ext]#

这就说的很明白了,那么我们就按照这提示步骤做吧.

2.2修改config.m4文件

我们把 10-12行的注释去掉

dnl PHP_ARG_WITH(test, for test

support,

dnl Make sure that the comment is

aligned:

dnl [ --with-test Include test support])

变为:

PHP_ARG_WITH(test, for test support,

Make sure that the comment is aligned:

[ --with-test Include test support])

***如果扩展没有再用别的库,那么到这就可以了, 如果还用了一堆其他的库,继续....

在最后一个方法PHP_NEW_EXTENSION(test, test.c,

$ext_shared)前,加上:

PHP_REQUIRE_CXX() //如果用到c++的话

PHP_ADD_LIBRARY(stdc++,"/usr/lib/gcc/x86_64-redhat-linux/4.4.4/",

TEST_SHARED_LIBADD)

//加上我们要用的功能库和功能库使用的第三方库

PHP_ADD_LIBRARY_WITH_PATH(a1, "/opt/phptest/test/libs",

TEST_SHARED_LIBADD)

PHP_ADD_LIBRARY_WITH_PATH(b1, "/opt/phptest/test/libs",

TEST_SHARED_LIBADD)

PHP_ADD_LIBRARY_WITH_PATH(b2, "/opt/phptest/test/libs",

TEST_SHARED_LIBADD)

PHP_ADD_LIBRARY_WITH_PATH(b3, "/opt/phptest/test/libs",

TEST_SHARED_LIBADD)

PHP_SUBST(TEST_SHARED_LIBADD)

如果是c++,还需要将这句中的文件后缀改为cpp,文件也同步改为cpp

PHP_NEW_EXTENSION(test, test.c, $ext_shared)

就此,m4文件就修改完毕了.

2.3写你的方法代码

生成框架后, 会生成以项目名命名的.c文件.会有如下的类似代码

//{{{ proto int test1(string filePath)

PHP_FUNCTION(test1) //这就是我们在skel文件里申明的方法,注释是他的c原型

{

char *filePath = NULL;

int argc = ZEND_NUM_ARGS();

int filePath_len;

//获取php中传来的参数

if (zend_parse_parameters(argc TSRMLS_CC, "s", &filePath,

&filePath_len) == FAILURE) return;

//将下面的错误提示注掉,然后写上自己的代码就可以了, 当然也可以用这种形式做异常信息的抛出

php_error(E_WARNING, "test1: not yet implemented");

}

2.4编译

在和config.m4同级目录下执行phpize,就可以生成出来configure了, 然后make,然后很快就提示Build

complete.了, 现在modules文件夹下面生成了了一个test.so,这就是我们需要的扩展库了,哈哈....等等...大小不对,还没第三库的一半大.合着第三方的静态库都没打进去.

这时有个最简单的方法将你自己的静态库也打进去.

手动执行:

g++ -shared .libs/test.o -o .libs/test.so

-L/opt/phpext/php/ext/test/include -la1 -lb1 -lb2

-lb3

执行后很有可能会报

/usr/bin/ld:

//opt/phpext/php/ext/test/include/liba1.a(xxxxx.cpp.o): relocation

R_X86_64_32 against `.bss' can not be used when making a shared

object; recompile with -fPIC

//opt/phpext/php/ext/test/include/liba1.a: could not read symbols:

Bad value

问题的原因和解决方法说的很明白了, 这下我们去将liba1的编译文件修改一下,将-fPic 的参数加上重新编译.

将这些第三方库全部重新编译后,当然,有些库他自身的编译本身就带有该参数的就不用重新编译了,比方说Freetype库.

至此,我们得到了一个test.so的php扩展, 赶紧放到环境中去测试一下吧.

--------------------------------------------------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值