在C / C ++项目中自动检测库依赖项的最佳方法是什么?
我有一个项目,我拥有机器上的所有依赖项。它构建和运行。现在我想组建一个autotools构建系统。我正在寻找一种自动检测所需的所有依赖项的好方法,例如使用的头文件和链接所需的库。
库位对我来说似乎是最困难的。我想能够说,为列表中的每个函数生成AC_CHECK_LIB命令。我可以在Perl中做到这一点,但我必须想象它已经存在于别处。
我所知道的是我可以使用objdump和nm查看符号,我可以使用这些实用程序找到函数所属的库,然后我可以在configure.ac中手动输入AC_CHECK_LIB命令来检查它。此时自动化将非常棒。
谢谢, Chenz
答案 0 :(得分:1)
这种详尽的测试(即每个功能)都是不必要的。更不用说它很难维持并且需要一段时间才能运行。
测试您知道需要测试的功能。如果您只是测试库的存在,请选择一个常用的函数用于测试。如果您想确保只有较新版本的某些功能可用,请使用仅在较新版本中找到的功能进行测试。
答案 1 :(得分:1)
我现在遇到了类似的挑战。 autoconf对于C ++技巧来说真的不那么方便,但它有基本的砖块来构建顶层的功能。看完这里后我的建议:
AC_CHECK_LIB
和AX_CXX_CHECK_LIB
复制的。是的,你需要编写一个迷你测试程序,但是这允许你测试类型,类(sizeof
可能有用,但是构造函数呢?),内联函数(这是你无法帮助的链接器)和外部函数(你不能用nm
)。来自aclocal.m4
:
# SYNOPSIS
#
# AX_TRY_LINK(library, includes, function-body [, action-if-true [, action-if-false]])
#
# DESCRIPTION
#
# This function is a wrapper around AC_ARG_WITH, which adds -I"value" to CPPFLAGS.
# "--with-" variable is initialized to default value, if it is passed.
#
AC_DEFUN([AX_TRY_LINK], [
dnl Below logic is a workaround for the limitation, that variables may not allow
dnl symbols like "+" or "-". See AC_CHECK_LIB source comments for more information.
m4_ifval([$4], , [AH_CHECK_LIB([$1])])
AS_LITERAL_IF([$1],
[AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1_$2])],
[AS_VAR_PUSHDEF([ac_Lib], [ac_cv_lib_$1''_$2])])
AC_CACHE_CHECK([for -l$1], [ac_Lib], [
dnl Save the current state
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ax_try_link_save_LIBS=$LIBS
LIBS="-l$1 $LIBS"
AC_TRY_LINK([$2], [$3], [AS_VAR_SET([ac_Lib], [yes])], [AS_VAR_SET([ac_Lib], [no])])
dnl Restore the state to original regardless to the result
LIBS=$ax_try_link_save_LIBS
AC_LANG_RESTORE
])
dnl If the variable is set, we define a constant and push library to LIBS by default or execute $4, otherwise execute $5.
AS_VAR_IF([ac_Lib], [yes],
[m4_default([$4], [
AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_LIB$1))
dnl Do not prepend a library, if it is already in the list:
(echo $LIBS | grep -q -- "-l$1 ") || LIBS="-l$1 $LIBS"
])],
[$5]
)
AS_VAR_POPDEF([ac_Lib])
]) # AX_ARG_WITH
现在在configure.ac
:
AC_INIT([ABC], [1.2.3])
AC_LANG([C++])
AC_PROG_CXX
AC_CXX_HAVE_STL
if test "x${ac_cv_cxx_have_stl}" != "xyes"; then
AC_MSG_ERROR([STL was not found; make sure you have installed libstdc++-dev])
fi
...
dnl openbabel library
sr_openbabel_lib=yes
AC_CHECK_HEADERS([openbabel/mol.h openbabel/obconversion.h openbabel/builder.h], [], [sr_openbabel_lib=no])
AX_TRY_LINK([openbabel], [
#include <openbabel/mol.h>
#include <openbabel/obconversion.h>
#include <openbabel/builder.h>
], [
OpenBabel::OBAtom atom;
OpenBabel::OBMol mol;
OpenBabel::OBConversion conversion;
atom.IsHeteroatom();
atom.IsCarbon();
mol.NumAtoms();
mol.NumBonds();
mol.NumRotors();
mol.GetAtom(0);
conversion.ReadString(&mol, "");
conversion.WriteString(&mol, false);
], [], [sr_openbabel_lib=no])
if test ${sr_openbabel_lib} != yes; then
AC_MSG_ERROR([openbabel headers or library was not found (use --with-openbabel to define custom header location)])
fi
答案 2 :(得分:0)
在Windows上,我曾使用Dependency Walker这样的东西。它的输出很详细,但它通常会显示可执行文件所需的每个库。
对于linux或mac,我不知道类似的东西,但我确信必须存在一些东西。