31 mai 2010

Libtool et cygwin : pas si ennemi que ça...

Il y a maintenant plus d'un mois que je ne vous ait pas proposé un article quelconque, et les articles les plus récents sont à faible teneur technique. J'en suis désolé, mais il y a quand même deux bonnes raisons à ça : la première est que ma famille s'est agrandie - et figurez vous que bien que vous me soyez très cher, mon fils me l'est encore plus. J'ose espérer que vous me pardonnerez cet écart.

La seconde raison trouvera son explication d'ici quelques jours - vendredi, si tout va bien. Des indices (pour ne pas dire la réponse) sont disponibles ici.

Mais revenons en à notre sujet d'aujourd'hui.

Il y a quelque chose qui m'échappe dans les projets open source utilisant les GNU autotools que j'utilise à tout bout de champs : s'ils sont prévus pour compiler sous cygwin et qu'ils devraient normalement générer des librairies dynamiques, ils ne le font pas et se réfugient derrière la documentation des GNU autotools, qui nous informent que cygwin ne permet pas la création de librairies partagées (shared librairies).

Ça me chiffonne pour une excellente raison : cygwin est principalement un ensemble de librairies partagées.

Une autre raison m'apparait immédiatement après avoir effectué quelques recherches simples : sous cygwin, libtool supporte parfaitement la création de librairies partagées.

Soient les librairies HDF5. Soit le fichier configure.in de ces librairies. On y trouve le code m4/sh suivant :

dnl Shared libraries are not currently supported under Cygwin.
case "`uname`" in
    CYGWIN*)
        if test "X${enable_shared}" = "Xyes"; then
            echo '    warning: shared libraries are not supported on Cygwin!'
            echo '    disabling shared libraries'
        fi
        enable_shared="no"
        ;;
esac

Ce code ou un équivalent se retrouve dans un nombre non négligeable de fichiers configure.in ou configure.ac. Et pourtant, libtool sait générer des DLL sous l'environnement cygwin : il suffit de lui spécifier les bonnes commandes et de modifier LDFLAGS pour inclure -no-undefined (parce que les DLL Windows ne supportent pas d'avoir des symboles non définis) :

dnl Libtool init (mainly for cygwin)
AC_LIBTOOL_WIN32_DLL
AC_LIBTOOL_DLOPEN
AC_PROG_LIBTOOL
AC_MSG_CHECKING(whether we need -no-undefined on $host) case x"$host" in x) ;; x*linux*) AC_MSG_RESULT([no]) ;; x*cygwin*) AC_MSG_RESULT([yes]) LDFLAGS="$LDFLAGS -no-undefined" ;; esac

Et voilà que vous êtes à même de générer ces DLL qui posent tant de problème. Il faut bien sûr installer le package libtool sur cygwin pour profiter de cette possibilité.

Il serait peut-être temps de remettre un certain nombre de documentation et de projets à jour...

Commentaires

1. Le mardi, juin 1 2010, 19:12 par Emmanuel Deloget

A titre informatif, sachant que vous êtes des perfectionnistes : si vous êtes sous cygwin et que vous utilisez libtool pour générer une librairie partagée, vous êtes peut-être déjà tombé sur un problème un peu étrange : pour peu que votre librairie lie des fichiers objet libtool (extension .lo) et des librairies statiques (extension .a), vous recevez de la part de libtool un message on ne peut plus déplaisant :

*** Warning: Trying to link with static lib archive $deplib.
*** I have the capability to make that library automatically link in when
*** you link to this library.  But I can only do this if you have a
*** shared version of the library, which you do not appear to have
*** because the file extensions .$libext of this argument makes me believe
*** that it is just a static archive that I should not use here.

Votre DLL se tranforme en librairie statique, pour votre plus grand malheur...

Pour corriger ce problème, il vous suffit d'ajouter dans votre fichier configure.in (ou configure.ac), avant la macro AC_PROG_LIBTOOL, la ligne suivante :

lt_cv_deplibs_check_method='pass_all'

Bien évidemment, il est important de faire cela de manière responsable - principalement parce que cette solution n'est pas portable (pass_all peut avoir des effets très pervers selon la plateforme).

Ajouter un commentaire

Les commentaires peuvent être formatés en utilisant une syntaxe wiki simplifiée.

Fil des commentaires de ce billet