2

C/C++ プロジェクトでライブラリの依存関係を自動検出する最良の方法は何ですか?

マシンにすべての依存関係があるプロジェクトがあります。ビルドして実行します。今、私は autotools ビルドシステムをまとめたいと思っています。使用されるヘッダー ファイルやリンクに必要なライブラリなど、必要なすべての依存関係を自動検出する良い方法を探しています。

ライブラリビットは、私が理解するのが最も難しいようです。リストなどのすべての関数に対して AC_CHECK_LIB コマンドを生成できるようにしたいと思います。おそらく Perl でこれを行うことができますが、既に他の場所に存在することを想像する必要があります。

私が知っているのは、objdump と nm でシンボルを表示できること、関数が属するライブラリをこれらのユーティリティで見つけることができること、そして configure.ac に手動で AC_CHECK_LIB コマンドを入力してチェックできることです。この時点で、自動化は素晴らしいものになるでしょう。

ありがとう、チェンツ

4

3 に答える 3

1

この種の徹底的なテスト(つまり、すべての機能)は不要です。言うまでもなく、メンテナンスが難しく、実行に時間がかかります。

テストが必要であることがわかっている機能をテストします。ライブラリの存在をテストするだけの場合は、テストで使用する一般的に使用される関数を選択してください。新しいバージョンでのみ利用できる機能があることを確認したい場合は、それらの新しいバージョンでのみ見られる機能を使用してテストしてください。

于 2009-10-22T21:12:29.427 に答える
1

私は今、同様の課題を抱えていました。autoconf は C++ のトリックにはそれほど便利ではありませんが、その上に機能を構築するための基本的なブリックがあります。あちこち見た後の私の提案:

  • この記事を読むと、新鮮なアイデアが得られます
  • ac-archiveで autoconf マクロのソースを参照してください(Debian に含まれているため、そのまま使用できます)。
  • 私は個人的に単純なヘルパーを作成しました。これはAC_CHECK_LIBandからコピーされてい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
于 2010-06-10T08:45:21.837 に答える
0

Windowsでは、そのようなものにDependency Walkerを使用しました。その出力は詳細ですが、通常、実行可能ファイルに必要なすべてのライブラリが表示されます。

Linux や Mac でそのようなことは知りませんが、何かが存在するに違いないと確信しています。

于 2009-10-20T19:06:30.247 に答える