【问题标题】:What is the best way to auto detect library dependencies in a C/C++ project?在 C/C++ 项目中自动检测库依赖关系的最佳方法是什么?
【发布时间】:2010-12-08 11:12:21
【问题描述】:

在 C/C++ 项目中自动检测库依赖关系的最佳方法是什么?

我有一个项目,我拥有机器上的所有依赖项。它构建并运行。现在我想组合一个自动工具构建系统。我正在寻找一种自动检测所需的所有依赖项的好方法,例如使用的头文件和链接所需的库。

图书馆位似乎是我最难弄清楚的。我想说,为列表或其他东西中的每个函数生成 AC_CHECK_LIB 命令。我可能可以在 Perl 中做到这一点,但我必须想象它已经存在于其他地方。

我知道我可以使用 objdump 和 nm 查看符号,我可以使用这些实用程序找到函数所属的库,然后我可以在 configure.ac 中手动输入 AC_CHECK_LIB 命令来检查它。在这一点上,自动化会很棒。

谢谢, 陈兹

【问题讨论】:

    标签: autotools autoconf automake


    【解决方案1】:

    在 Windows 上,我使用 Dependency Walker 来处理类似的事情。它的输出很详细,但通常会显示可执行文件所需的每个库。

    我不知道 linux 或 mac 有什么类似的东西,但我确信一定存在一些东西。

    【讨论】:

      【解决方案2】:

      这种详尽的测试(即每个功能)是不必要的。更不用说它很难维护并且需要一段时间才能运行。

      测试您知道需要测试的功能。如果您只是测试库的存在,请选择一个常用函数在测试中使用。如果您想确保某些功能仅在较新版本中可用,请使用仅在这些较新版本中提供的功能进行测试。

      【讨论】:

        【解决方案3】:

        我现在也遇到了类似的挑战。 autoconf 对于 C++ 技巧来说真的不是那么方便,但它有基本的砖块来构建顶部的功能。我在这里和那里看了之后的建议:

        • 阅读this article,它会给你带来新鲜的想法
        • ac-archive 上查看 autoconf 宏的源代码(它包含在 Debian 中,因此您可以按原样使用它)
        • 我个人写过simple helper,抄自AC_CHECK_LIBAX_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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          • 2010-09-21
          • 1970-01-01
          • 1970-01-01
          • 2016-06-19
          相关资源
          最近更新 更多