Quelle est la bonne façon de gérer les types/fonctions publiques facultatifs pour une bibliothèque utilisant automake ?

StackOverflow https://stackoverflow.com/questions/9440779

Question

Dans une bibliothèque que je gère, il y a quelques fonctions qui dépendent des pthreads.Le projet utilise automake.Je souhaite créer une option de configuration pour désactiver la dépendance sur pthreads, qui ne devrait tout simplement pas compiler ces fonctions.(La raison est liée à certaines cibles de compilation croisée et intégrées.)

Éviter de compiler le fichier contenant ces fonctions fonctionne bien jusqu'à présent, mais j'ai maintenant réalisé que ces fonctions et une structure qu'elles utilisent sont définies dans les en-têtes publics.

  1. Quelle est la bonne approche ici, du point de vue de la maintenance de la bibliothèque ?
  2. Quelle est la bonne façon de rendre les types ou les fonctions facultatifs dans les en-têtes publics ?

Au départ, je pensais que je devrais transformer les en-têtes en fichiers d'entrée autoconf (.in) et générer les en-têtes avec ces fonctions et types éventuellement supprimés.

Mais alors, qu’en est-il des systèmes sur lesquels différentes versions de la bibliothèque peuvent être installées simultanément ?Normalement, ceux-ci devraient pouvoir partager des en-têtes.

Dois-je faire en sorte que les en-têtes utilisent un préprocesseur conditionnel pour éviter ces fonctions, et utiliser pkg-config le spécifier comme option de ligne de commande ?

Une autre idée est de déplacer ces fonctions et types dans leur propre en-tête et d'éviter d'installer cet en-tête lorsque les pthreads sont désactivés.Cela signifierait perturber légèrement l’organisation des en-têtes, mais c’est peut-être la meilleure idée.Je veux cependant votre avis, quelle est la meilleure façon de gérer les fonctionnalités facultatives dans les en-têtes publics d'une bibliothèque ?

Était-ce utile?

La solution

Une autre idée est de déplacer ces fonctions et types dans leur propre en-tête et d'éviter d'installer cet en-tête lorsque les pthreads sont désactivés.

Ce serait le choix le plus propre.Lorsque vous activez l'option via AC_ARG_ENABLE vous pouvez bien sûr contourner toutes les configurations de pthreads.Avec cette option, les packages qui dépendent de votre bibliothèque pourront le savoir facilement (via AC_TRY_COMPILE) que les fonctions pthread-optionnelles ne sont pas là au lieu de AC_TRY_RUN pour voir si ces fonctions fonctionnent au moment de l'exécution.

Autres conseils

Un moyen est d'avoir vos fonctions de filetage pour continuer à exister sur la plate-forme intégrée, mais de retourner un code d'erreur au cas où ils seront invoqués.De cette façon, l'API reste la même chose entre les plates-formes, qui est très souhaitable pour le code à l'aide de votre bibliothèque ("Programme"), puisque le programme n'a pas besoin de tests de type Autoconf pour la présence de fonctions dans votre bibliothèque, mais peut simplement les utiliseret utiliser le niveau de code source IFS pour déterminer leurs fonctionnalités.

int mylib_thread_frenzy(void)
{
#ifdef HAVE_PTHREAD_CREATE
       int ret = pthread_create(...);
       if (ret < 0)
               return -errno;
       return 0;
#else
       return -ENOSYS;
#endif
}

.

/* Program */
int ret = mylib_thread_frenzy();
if (ret == -ENOSYS) {
    /* Hm, castrated platform. Try something else... */
    printf("Or just tell the user the platform is too weak.\n");
} else {
    printf("World domination acquired\n");
}

Dans tous les cas, n'essayez pas de #include "config.h" dans mylib.h et ne pas expédier cette configuration non plus, car les définis définies dans votre configuration peuvent heurter avec ceux d'une autre bibliothèqueet / ou programme.

Si vous voulez absolument supprimer les fonctions de Mylib.h, je suppose que cela me vient à l'esprit:

/* mylib.h.in */
#if 0@HAVE_PTHREAD_CREATE@
extern int mylib_pthread_frenzy(void);
#endif

/* configure.ac */
AC_SEARCH_LIBS([pthread_create], [pthread],
  [HAVE_PTHREAD_CREATE=1
   AC_SUBST([HAVE_PTHREAD_CREATE])
  ])
AC_CONFIG_FILES([mylib.h.in])
AC_OUTPUT

I Cependant, je n'aime pas la deuxième approche car cela signifie que la configuration doit être réorganisée chaque fois que MyLib.h.in change.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top