C的编译、链接、安装过程
autoconf基本语法
config.m4中的PHP_XX系列宏(在aclocal.m4中)
具体例子:
以使用taglib(https://github.com/taglib/taglib)编写一个操作mp3的id3标签的PHP扩展为例,按照默认编译安装taglib,头文件在 /usr/local/include/taglib/tag_c.h,共享库文件在/usr/local/lib/libtag_c.so
我用到了taglib这个库的c语言版,安装后taglib-config –libs命令得到的是它的c++版的库,所以要在config.m4里自己写。
config.m4的关键代码:
PHP_ARG_WITH(taglib, for taglib support, [ --with-taglib Include taglib support])
if test "$PHP_TAGLIB" != "no"; then
SEARCH_PATH="/usr/local /usr"
SEARCH_FOR="/include/taglib/tag_c.h"
if test -r $PHP_TAGLIB/$SEARCH_FOR; then # path given as parameter
TAGLIB_DIR=$PHP_TAGLIB
else # search default path list
AC_MSG_CHECKING([for taglib files in default path])
for i in $SEARCH_PATH ; do
if test -r $i/$SEARCH_FOR; then
TAGLIB_DIR=$i
AC_MSG_RESULT(found in $i)
fi
done
fi
if test -z "$TAGLIB_DIR"; then
AC_MSG_RESULT([not found])
AC_MSG_ERROR([Please reinstall the taglib distribution])
fi
PHP_ADD_INCLUDE($TAGLIB_DIR/include)
dnl #库文件 libtag_c.so
LIBNAME=tag_c
dnl #库函数
LIBSYMBOL=taglib_file_tag
dnl 第三个参数要设置成EXTRA_LDFLAGS时,链接的时候才会加上 -ltag_c 参数...这个PHP_ADD_LIBRARY_WITH_PATH的原型还没看明白...
dnl 貌似还有好几种解决方案,PHP_EVAL_LIBLINE?
PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $TAGLIB_DIR/lib, EXTRA_LDFLAGS)
PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
[
AC_DEFINE(HAVE_TAGLIB,1,[ ])
],[
AC_MSG_ERROR([wrong taglib lib version or lib not found])
],[
-L$TAGLIB_DIR/lib -lm
])
PHP_NEW_EXTENSION(php_taglib, php_taglib.c, $ext_shared)
PHP_SUBST(TAGLIB_SHARED_LIBADD)
fi
接下来是
configure [--with-taglib[=/path]]
make
make install
顺利的话可以到php.ini里面加载扩展。
期间可能会出现tag_c.h文件找不到的问题,注意下头文件的路径是由 config.m4 文件里的 PHP_ADD_INCLUDE($TAGLIB_DIR/include) 加上 扩展源码里 #include “taglib/tag_c.h” 组成的。
然后,即使扩展编译安装成功,php_info()里看到加载成功,但是cli执行php 扩展测试代码的时候出现 symbol lookup error的话,应该是扩展链接的时候没有找到libtag_c.so, 注意下PHP_ADD_LIBRARY_WITH_PATH() 的第三个参数即可。