3

我有一个用 C++ 编写的 PHP 模块,它依赖于安装的 C++ 库(Boost Date_Time)。

目前,在我的 config.m4 文件中,我正在检查库,如下所示:

  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
  ])

现在,这适用于我当前的环境,但我痛苦地意识到这可能会在不同版本的库或编译器上中断。

如何让 automake 理解未损坏的 C++ 符号?

编辑:

我意识到检查损坏的名称是可怕的,但是没有某种方法可以检查“nm -C”返回的符号名称(例如 boost::gregorian::bad_month 等)。

我发现了一些对 automake 命令 AC_LANG_CPLUSPLUS() 的参考,但我不确定如何使用它以及它是否适用于这里。

4

4 回答 4

2

您可以检查AC_TRY_COMPILE类似的东西:

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])
])

这避免了使用未损坏的符号。

于 2009-05-13T20:49:15.583 回答
0

在特定 C++ 编译器的环境之外,没有“未损坏的 C++ 符号” - 损坏的目的是为外部工具(例如链接器和库管理器)提供唯一的名称。

于 2009-04-28T15:23:10.090 回答
0

您需要为您希望调用的 Boost api 函数提供一组 C++ 包装器。这些包装器需要用 声明extern "C",如:

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

您的 PHP 代码应该使用这些包装器,而不是尝试直接调用 C++ 方法。

编辑:由于您假设 的可用性automake,您可能计划编译 Boost 库作为安装的一部分。这使您可以选择探测名称修改的结果。尝试按照这些思路创建一个测试 C++ 程序。请注意,这只需要编译;它不需要产生有效的结果。

#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;
}

在您的自动制作中,您需要编译它,然后通过运行输出

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

根据您的需要和挑剔,您可能希望进一步细化grep命令以查找字符串“ typeinfo for boost::gregorian::bad_month”(请注意,这会进一步增加您对特定编译器实现的依赖。)

于 2009-04-28T15:28:38.690 回答
0

这是一个糟糕的主意——公开损坏的符号。你为什么首先需要这个?

看到您的更新后,我不得不问,为什么不使用自定义规则来调用nm和获取此信息并使此规则作为要求传递?autoconf如果要提供直接命令来检查目标文件中的符号,我会感到非常惊讶。

于 2009-04-28T15:29:21.590 回答