views:

207

answers:

4

I have a PHP module written in C++, which relies on a C++ library (Boost Date_Time) being installed.

Currently, in my config.m4 file I'm checking for the library as follows:

  LIBNAME=boost_date_time
  LIBSYMBOL=_ZN5boost9gregorian9bad_monthD0Ev

  PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,,
  [
    AC_MSG_ERROR([lib $LIBNAME not found.  Try: sudo apt-get install libboost-dev])
  ],[
    -lstdc++ -ldl
  ])

Now, this works in my current environment, but I'm painfully aware this will probably break on a different version of the library or compiler.

How can I get automake to understand the non-mangled C++ symbol?

Edit:

I realise that checking on the mangled name is horrible, but is there not some way of checking for the symbol name as returned by "nm -C" (eg boost::gregorian::bad_month etc).

I found some refence to the automake command AC_LANG_CPLUSPLUS(), but I'm not sure how to use it and whether it's applicable here.

A: 

Outside of the environment of a particular C++ compiler, there is no "non-mangled C++ symbol" - the mangling is done precisely to provide a unique name to external tools, such as linkers and librarians.

anon
A: 

You need to provide a set of C++ wrappers for the Boost api functions that you wish to invoke. These wrappers need to be declared with extern "C", as in:

extern "C" 
void foo(int bar) 
{
...
}

Your PHP code should use these wrappers, rather than trying to directly call C++ methods.

EDIT: Since you're assuming the availability of automake, you're probably planning to compile the Boost library as part of the install. This gives you the option of probing the result of the name mangling. Try creating a test C++ program along these lines. Note that this only needs to compile; it doesn't need to produce a valid result.

#include "boost/date_time/gregorian/greg_month.hpp"
int main( int argc, const char* argv[] )
{
   boost::gregorian::bad_month* xxxjunk = new boost::gregorian::bad_month;
   return 0;
}

In your automake, you'd want to compile this, then run the output through

nm -C | grep "boost::gregorian::bad_month"

Depending on your needs and pickiness, you might want to further refine the grep command to look for the string "typeinfo for boost::gregorian::bad_month" (note that this further increases your dependency on the specific compiler implementation.)

Dan Breslau
Re-read the question - that is not what he is asking about.
anon
A: 

This is a terrible idea -- to have mangled symbols out in the open. Why'd you need this in the first place?

Having seen your update, I'd have to ask, why not use a custom rule to invoke nm and get this information and make this rule to be passed as a requirement? I would be very surprised if autoconf was to provide a direct command to check object files for symbols.

dirkgently
I can understand his motivation - the mangled name will be in the library or not, if not there it is an error. He isn't actually trying to call a mangled (or unmangled, in this context) function.
anon
Adding a custom rule isn't a bad idea. Note that the `PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,,` etc part of the command is exactly that - a PHP specific macro to check object files for symbols. But for C symbols only, of course.
therefromhere
+1  A: 

You can check AC_TRY_COMPILE with something like that:

LIBNAME=boost_date_time
AC_MSG_CHECKING([for BOOST])
AC_TRY_COMPILE(
[
#include "boost/date_time/gregorian/greg_month.hpp"
],
[
boost::gregorian::bad_month* bm = new boost::gregorian::bad_month;
],
[
AC_MSG_RESULT(yes)
],
[
AC_MSG_ERROR([lib $LIBNAME not found.  Try: sudo apt-get install libboost-dev])
])

This avoid the use of unmangled symbol.

eric espie