I'm working on a native PHP extension which includes symbols from a shared library, but I can't get the config.m4
file to generate a build procedure that includes the necessary linker options to correctly link to the share library. This is what I have in my config.m4
file so far:
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
The libotherlibrary
library is in a standard system location. When I phpize
with this configuration and then execute the generated configure
script with the --enable-myextension
argument it successfully generates a Makefile
etc. and I can see it doing the test for otherlib_some_function
from libotherlibrary
which passes. But calling ldd
on my resulting myextension.so gives just:
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)
so no mention of libotherlibrary
. And the libtool
and cc
commands which are executed by the Makefile
don't include the -lotherlibrary
option. And then when I try and execute a PHP script which uses my extension I get:
php: symbol lookup error: /path/to/modules/myext.so: undefined symbol: otherlib_some_function
In place of PHP_EVAL_INCLINE
and PHP_EVAL_LIBLINE
I've also tried the PHP_ADD_LIBRARY
macro:
PHP_ADD_LIBRARY($LIBNAME,,OTHERLIB_SHARED_LIBADD)
(I don't understand what the third argument to this macro is for.)
I've also tried (in combination with both of the above), including the fifth argument to PHP_CHECK_LIBRARY
called extra-libs
passing in the value of my $LIBOTHERLIB_LIBS
variable. Doing so doesn't fix anything, and there's no documentation of what this argument is supposed to do or what values it requires. So this is just a guess really.
So how can I get my extension to build with the required -lotherlibrary
linker option?
My working version now looks like this:
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
This technique uses pkg-config
to find the shared library so perhaps it may not be as portable as @hek2mgl's explicit searching.
The main addition is the use of the PHP_SUBST
macro which "Adds variable with it's value into Makefile" (according to the aclocal.m4
that phpize
created). It seems that the macro PHP_ADD_LIBRARY
, documented as "add a library to the link line", doesn't actually add anything to your Makefile
. Instead, you supply a variable name as its third argument (documented as "shared-libadd") and later call PHP_SUBST
to update that variable in the Makefile
.