PHP-ссылка на общую библиотеку в расширении


Я работаю над собственным расширением 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 из 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. И команды libtool и cc, которые выполняются с помощью Makefile, не включают опцию -lotherlibrary. А затем, когда я пытаюсь выполнить PHP-скрипт, который использует мое расширение, я получаю:

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. Это ничего не исправляет, и нет документации о том, что должен делать этот аргумент или какие значения он требует. Так что на самом деле это всего лишь предположение.

Итак, как я могу настроить расширение для сборки с требуемой опцией компоновщика -lotherlibrary?

Author: ironchicken, 2015-04-13

3 answers

Вам нужно использовать PHP_ARG_WITH вместо PHP_ARG_ENABLE + плюс несколько других изменений. Вот пример, который работает для меня. Замените libxyz именем вашей внешней библиотеки:

конфигурация.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
Author: hek2mgl, 2015-04-13 22:04:22

Моя рабочая версия теперь выглядит так:

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.

 1
Author: ironchicken, 2015-04-13 22:05:35

Простите мое невежество, но это может быть хакерским решением, так как я не слишком хорош в m4.

Это работает для меня с php-7.0

if test "$PHP_MYMOD" != "no";
then
    LIBNAME=my_dank_lib
    LIBSYMBOL=my_dank_lib_function_name
    PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
    [
        PHP_ADD_LIBRARY($LIBNAME, 1, EXTRA_CFLAGS)
        PHP_SUBST(EXTRA_CFLAGS)
        AC_DEFINE([MYMOD],1 ,[whether to enable mymod support])
        AC_HEADER_STDC
    ],[
        AC_MSG_ERROR([Uh oh, library $LIBNAME was not found with the function $LIBSYMBOL in it.])
    ])



    PHP_NEW_EXTENSION(mymod,
          mymod.c,
          $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
fi

Я пришел к этому выводу после того, как увидел в файле makefile, что EXTRA_CFLAGS определяется по умолчанию. И содержимое EXTRA_CFLAGS добавлялось в инструкцию сборки mymod.lo.

Таким образом, используя PHP_SUBST(EXTRA_CFLAGS), он проникает туда. После запуска ./configure перейдите в свой файл makefile и убедитесь сами!

 0
Author: Sanchke Dellowar, 2017-08-12 00:36:57