2009-10-20 6 views
2

Quel est le meilleur moyen de détecter automatiquement les dépendances de bibliothèque dans un projet C/C++?Quel est le meilleur moyen de détecter automatiquement les dépendances de bibliothèque dans un projet C/C++?

J'ai un projet où j'ai toutes les dépendances sur la machine. Il construit et fonctionne. Maintenant, je veux mettre en place un système de construction autotools. Je cherche un bon moyen de détecter automatiquement toutes les dépendances nécessaires telles que les fichiers d'en-tête utilisés et les bibliothèques nécessaires pour la liaison.

Le bit de bibliothèque semble être le plus difficile à comprendre. J'aimerais pouvoir dire, générer des commandes AC_CHECK_LIB pour chaque fonction dans une liste ou quelque chose. Je pourrais probablement le faire en Perl, mais je dois imaginer qu'il existe déjà ailleurs. Ce que je sais c'est que je peux voir les symboles avec objdump et nm, je peux trouver à quelle bibliothèque appartient une fonction avec ces utilitaires, puis je peux entrer manuellement une commande AC_CHECK_LIB dans mon configure.ac pour la vérifier. L'automatisation serait géniale à ce stade.

Merci, Chenz

Répondre

1

Ce type de test exhaustif (c'est-à-dire, chaque fonction) est inutile. Sans compter que ce serait difficile à maintenir et prendre un certain temps à courir.

Test pour les fonctions que vous savez justifier un test. Si vous testez simplement l'existence d'une bibliothèque, choisissez une fonction couramment utilisée pour votre test. Si vous voulez vous assurer que certaines fonctionnalités ne sont disponibles que dans les vesions les plus récentes, testez en utilisant une fonction uniquement disponible dans ces versions plus récentes.

0

Sous Windows que j'ai utilisé Dependency Walker pour des trucs comme ça. Sa sortie est verbeuse, mais elle vous montrera généralement toutes les bibliothèques requises par l'exécutable.

Je ne connais rien de tel pour Linux ou mac, mais je suis sûr que quelque chose doit exister.

1

J'ai eu un défi similaire maintenant. autoconf n'est vraiment pas très pratique pour les astuces C++, mais il a des briques de base pour construire la fonctionnalité sur le dessus. Mes suggestions après avoir regardé ici et là:

  • Lire this article, il vous apportera des idées nouvelles
  • regarder les sources pour les macros autoconf à ac-archive (il est inclus dans Debian, vous pouvez l'utiliser tel quel)
  • J'ai personnellement écrit simple assistant, qui est copié de AC_CHECK_LIB et AX_CXX_CHECK_LIB. Oui, vous devez écrire un mini-test-programme, mais cela vous permet de tester les types, les classes (sizeof pourrait fonctionner, mais qu'en est-il des constructeurs?), Les fonctions inline (ceci ne peut pas être fait avec linker) et externes fonctions (vous ne pouvez pas le faire avec nm).

De 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 

Maintenant en 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 
Questions connexes