PHP链接到扩展中的共享库

时间:2015-04-13 15:39:07

标签: php dynamic-linking php-extension

我正在使用包含来自共享库的符号的本机PHP扩展,但我无法获取config.m4文件来生成包含必要链接器选项以正确链接到共享的构建过程图书馆。这是我到目前为止config.m4文件中的内容:

PHP_ARG_ENABLE(myextension, whether to enable MyExtension support, [ --enable-myextension   Enable MyExtension support])

if test "$PHP_MYEXTENSION" = "yes"; then

  LIBNAME=otherlibrary
  LIBSYMBOL=otherlib_some_function
  LIBOTHERLIB_LIBS=`pkg-config --libs otherlibrary`
  LIBOTHERLIB_INC=`pkg-config --cflags otherlibrary`

  PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
  [
    PHP_EVAL_INCLINE($LIBOTHERLIB_INC)
    PHP_EVAL_LIBLINE($LIBOTHERLIB_LIBS)
    AC_DEFINE(HAVE_MYEXTENSION, 1, [Whether you have MyExtension])
  ],[
    AC_MSG_ERROR([wrong lib$LIBNAME version or library not found])
  ])

  PHP_NEW_EXTENSION(myextension, myextension.c, $ext_shared)
fi

libotherlibrary库位于标准系统位置。当我phpize使用此配置然后使用configure参数执行生成的--enable-myextension脚本时,它会成功生成Makefile等等,我可以看到它正在为{进行测试来自otherlib_some_function的{​​1}}但是在我生成的myextension.so上调用libotherlibrary只会给出:

ldd

所以没有提及linux-vdso.so.1 (0x00007ffd11fce000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f741e653000) /lib64/ld-linux-x86-64.so.2 (0x00007f741ec26000) libotherlibrary执行的libtoolcc命令不包含Makefile选项。然后,当我尝试执行使用我的扩展的PHP脚本时,我得到:

-lotherlibrary

代替php: symbol lookup error: /path/to/modules/myext.so: undefined symbol: otherlib_some_function PHP_EVAL_INCLINE我也尝试了PHP_EVAL_LIBLINE宏:

PHP_ADD_LIBRARY

(我不明白这个宏的第三个参数是什么。)

我也尝试过(结合上述两种情况),包括传递PHP_ADD_LIBRARY($LIBNAME,,OTHERLIB_SHARED_LIBADD) 变量值PHP_CHECK_LIBRARY extra-libs的第五个参数。这样做并没有解决任何问题,也没有关于这个参数应该做什么或它需要什么值的文档。所以这只是猜测。

那么如何使用所需的$LIBOTHERLIB_LIBS链接器选项来构建我的扩展?

2 个答案:

答案 0 :(得分:1)

您需要使用PHP_ARG_WITH代替PHP_ARG_ENABLE +以及其他一些更改。这是一个适合我的例子。将libxyz替换为外部库的名称:

的config.m4

dnl If your extension references something external, use with:

PHP_ARG_WITH(libxyz, for libxyz support,
Make sure that the comment is aligned:
[  --with-libxyz             Include libxyz support])

dnl Otherwise use enable:

dnl PHP_ARG_ENABLE(libxyz, whether to enable libxyz support,
dnl Make sure that the comment is aligned:
dnl [  --enable-libxyz           Enable libxyz support])

if test "$PHP_LIBXYZ" != "no"; then
  dnl Write more examples of tests here...

  dnl # --with-libxyz -> check with-path
  SEARCH_PATH="/usr/local /usr"
  SEARCH_FOR="/include/libxyz.h"
  if test -r $PHP_LIBXYZ/$SEARCH_FOR; then # path given as parameter
    LIBXYZ_DIR=$PHP_LIBXYZ
  else # search default path list
    AC_MSG_CHECKING([for libxyz files in default path])
    for i in $SEARCH_PATH ; do
      if test -r $i/$SEARCH_FOR; then
        LIBXYZ_DIR=$i
        AC_MSG_RESULT(found in $i)
      fi
    done
  fi
  dnl
  if test -z "$LIBXYZ_DIR"; then
    AC_MSG_RESULT([not found])
    AC_MSG_ERROR([Please reinstall the libxyz distribution])
  fi

  dnl # --with-libxyz -> add include path
  PHP_ADD_INCLUDE($LIBXYZ_DIR/include)

  dnl # --with-libxyz -> check for lib and symbol presence
  LIBNAME=libxyz
  LIBSYMBOL=libxyz_lib_version

  PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
  [
    PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBXYZ_DIR/lib, LIBXYZ_SHARED_LIBADD)
    AC_DEFINE(HAVE_LIBXYZLIB,1,[ ])
  ],[
    AC_MSG_ERROR([wrong libxyz lib version or lib not found])
  ],[
    -L$LIBXYZ_DIR/lib -lm
  ])

  PHP_SUBST(LIBXYZ_SHARED_LIBADD)

  PHP_NEW_EXTENSION(libxyz, libxyz.c, $ext_shared)
fi

请检查:http://php.net/manual/de/internals2.buildsys.configunix.php

答案 1 :(得分:1)

我的工作版现在看起来像这样:

PHP_ARG_ENABLE(myextension, whether to enable MyExtension support, [ --enable-myextension   Enable MyExtension support])

if test "$PHP_MYEXTENSION" = "yes"; then

  LIBNAME=otherlibrary
  LIBSYMBOL=otherlib_some_function
  LIBOTHERLIB_LIBS=`pkg-config --libs otherlibrary`
  LIBOTHERLIB_INC=`pkg-config --cflags otherlibrary`

  PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
  [
    PHP_ADD_LIBRARY($LIBNAME,1,OTHERLIBRARY_SHARED_LIBADD)
    PHP_SUBST(OTHERLIBRARY_SHARED_LIBADD)
    AC_DEFINE(HAVE_MYEXTENSION, 1, [Whether you have MyExtension])
  ],[
    AC_MSG_ERROR([wrong lib$LIBNAME version or library not found])
  ])

  PHP_NEW_EXTENSION(myextension, myextension.c, $ext_shared)
fi

此技术使用pkg-config来查找共享库,因此它可能不像@ hek2mgl的显式搜索那样可移植。

主要的补充是使用PHP_SUBST宏“将变量及其值添加到Makefile中”(根据aclocal.m4创建的phpize)。宏PHP_ADD_LIBRARY(记录为“向链接行添加库”)似乎实际上并未向Makefile添加任何内容。相反,您提供变量名称作为其第三个参数(记录为“shared-libadd”),然后调用PHP_SUBST来更新Makefile中的变量。