Journal Clang arrive avec le C++, et ça va faire mal

Posté par (page perso) .
Tags : aucun
12
10
jan.
2010
Bonjour,

Vous savez qu'outre KDE, un autre projet libre que j'aime particulièrement est Clang/LLVM, comme j'ai eu l'occasion de le montrer dans mes précédant journaux Clang-C++ a mangé du lion ! et LLVM dans un gestionnaire de paquets ?

LLVM est un projet important visant à mettre en commun la «partie basse» des compilateurs. Il utilise un langage abstrait (appelé bytecode) et génère un véritable binaire pour chaque architecture supportée. Il permet également d'excellentes optimisations, ainsi qu'une compilation juste-à-temps si nécessaire.

Clang est un compilation C, C++, Objective-C et Objective-C++ qui utilise LLVM comme couche basse. Il ne s'occupe ainsi que de la gestion du langage (et le fait bien), et permet à LLVM de faire les optimisations qu'il veut.

Le soucis de Clang a toujours été le C++. En effet, le langage C est très simple, et il n'est pas trop difficile de créer un compilateur pour lui (on en trouve même des petits comme exercices dans les livres de programmation, le SDK MS en contient un il me semble, et on en trouve énormément en libre).

Par contre, le C++ est largement plus complexe, surtout dans son utilisation avancée. Les classes, les fonctions virtuelles, les templates, le polymorphismes sont très complexes à gérer pour le compilateur.

Aujourd'hui, j'ai récupéré la version SVN de Clang et l'ai compilée. Je m'en suis alors servi pour compiler quelques petits programmes en C++, et compte encore le faire.

Tout d'abord, un simple fichier .cpp. La compilation se passe sans problèmes, pas de warnings. Par contre, la liaison échoue lamentablement pour une raison étrange, sans doutes une bibliothèque que Clang ne connaît pas.

J'essaie ensuite avec un programme C++ un peu plus complexe. Le cobaye de cette expérience est Setup, mon gestionnaire de paquets.

Le lance la compilation, ça compile deux trois fichiers (assez rapidement d'ailleurs), puis ça échoue sur l'un d'eux. Je regarde l'erreur, voit qu'il y a un problème dans les en-têtes de Qt, corrige (hackish : suppression de la ligne foireuse :-° ), et recommence.

La compilation se passe sans problèmes, même le moc, même ce qui utilise des templates, fonctions virtuelles, etc. Un beau fichier liblpackages.so est généré, la liaison ayant marché.

Ensuite, je passe au front-end Setup lui-même. Là aussi, je compile, ça me sort trois warnings que je corrige, puis j'essaie de lier. Là par contre, ça marche un peu moins bien : il manque plein de symboles, dont plein de trucs venant de Qt ! Pourtant, je me lie bien à QtCore, tout est ok. C'est donc soit un bug dans Clang, soit dans Qt.

Pour finir, je n'ai pas su voir si le programme se lance, mais c'est déjà une avancée magnifique par rapport à ce que j'ai testé il y a quelques mois (la compilation ne marchait pas). Dans quelques mois, il se pourrait qu'on aie un bon remplaçant à GCC. Il faut juste que j'arrive à compiler un truc pour voir si le code est plus lent ou plus rapide que ce que GCC génère.

Pourquoi j'ai mis «ça va faire mal» dans le titre ? Parce que Clang est vraiment super strict. En compilant en -Wall, il y a énormément de warnings très intéressants (ceci est plus rapidement fait comme cela, cela est boiteux, etc). Je compile Setup en -Wall -Werror, donc je dois corriger tous les warnings, pour que ça marche. Je les ai tous corrigés. Il y a aussi le fait que Clang n'accepte pas ce que GCC peut accepter. Il y aura donc plein de programmes qui seront cassés, mais une fois corrigés, ils seront bien plus propres.

En tous cas, bravo aux développeurs de Clang ! C'est un beau bébé qui commence à bien marcher.
  • # Compiler un gros projet, voire le noyau...

    Posté par . Évalué à 7.

    Il me semble qu'il restera beaucoup de travail avant de pouvoir compiler un gros projet libre écrit pour gcc. Les projets exigeants exploitent les dernières fonctionnalités de chaque version du compilateur. Il faudra que Clang suive à la trace les nouveautés de gcc, soit modifier le code.

    Tu peux voir le projet linuxDNA : il y a besoin d'un patch (13 ko en ce moment) pour compiler le noyau linux avec ICC. Et encore, on parle de C pur, alors imagine en C++.

    http://www.linuxdna.com/
    • [^] # Re: Compiler un gros projet, voire le noyau...

      Posté par . Évalué à 4.

      Même si je ne doute pas que clang ait encore beaucoup de chemin à faire, je ne pense pas que la compilation du noyau soit représentative de l'ensemble des projets "exigeants": c'est de la programmation système, et en tant que telle, a des besoins particuliers.

      Pour de l'applicatif, il me semble au contraire que s'appuyer sur les spécificités d'un compilateur est plutôt mal vu.

      Après, le standard C++ est tellement complexe qu'il est peut-être plus prudent de calquer le comportement d'un compilateur existant.
    • [^] # Re: Compiler un gros projet, voire le noyau...

      Posté par . Évalué à 5.

      Et encore, on parle de C pur, alors imagine en C++.

      Euh, certes si tu consideres du C pur les tonnes de macros (dont certaines sont assez speciales...) bourrees d'extensions GCC.

      Apres Intel a implemente beaucoup d'extensions non standard de GCC, sinon ca serait meme pas la peine d'essayer de compiler le kernel avec.
    • [^] # Re: Compiler un gros projet, voire le noyau...

      Posté par . Évalué à 2.

      Je croyais que Intel avait abandonné ce projet (compiler linux avec leur icc) ? Et qu'ils avaient déclarés préférer participer à l'amélioration de gcc.
  • # CLang builds LLVM

    Posté par (page perso) . Évalué à 5.

    À noter qu'un cas de test intéressant écrit en C++ est ... Clang lui-même. Et visiblement, les développeurs ne sont pas loin d'arriver à le compiler correctement :

    http://blog.llvm.org/2009/12/clang-builds-llvm.html

    (en gros, pour l'instant, clang compile clang+llvm, mais le résultat n'est pas fonctionnel)
  • # Pourquoi serait-ce un bug dans Qt ?

    Posté par . Évalué à 2.

    "C'est donc soit un bug dans Clang, soit dans Qt."
    En testant la compilation avec GCC (ou tout autre compilateur C++ dont on est sûr du fonctionnement), tu devrais vite savoir si c'est ton code qui a un bug ou si c'est Clang qui n'est pas prêt, non ?
    • [^] # Re: Pourquoi serait-ce un bug dans Qt ?

      Posté par (page perso) . Évalué à 9.

      Non car son code ou celui de Qt peut contenir des choses qui passent avec GCC, alors que ça ne devrait pas passer.

      Envoyé depuis mon lapin.

    • [^] # Re: Pourquoi serait-ce un bug dans Qt ?

      Posté par (page perso) . Évalué à 1.

      Ça passe impeccablement sous GCC 4.4, en -Wall -Werror. Pour infos, voici un extrait des erreurs :


      /usr/include/QtCore/qlist.h:113: undefined reference to `shared_null'
      cache.o: In function `QList::at(int) const':
      /usr/include/QtCore/qlist.h:439: undefined reference to `qt_assert_x'
      cache.o: In function `QByteArray::~QByteArray()':
      /usr/include/QtCore/qbytearray.h:382: undefined reference to `qFree'
      cache.o: In function `QString::QString()':
      /usr/include/QtCore/qstring.h:868: undefined reference to `shared_null'
      cache.o: In function `QList<Logram::Depend*>::at(int) const':
      /usr/include/QtCore/qlist.h:439: undefined reference to `qt_assert_x'
      cache.o: In function `QList<Logram::ChangeLogEntry*>::detach_helper()':
      /usr/include/QtCore/qlist.h:608: undefined reference to `qFree'
      cache.o: In function `QList<Logram::ChangeLogEntry*>::free(QListData::Data*)':
      /usr/include/QtCore/qlist.h:649: undefined reference to `qFree'
      cache.o: In function `QList<Logram::Package*>::detach_helper()':
      /usr/include/QtCore/qlist.h:608: undefined reference to `qFree'
      cache.o: In function `QList<Logram::Package*>::free(QListData::Data*)':
      /usr/include/QtCore/qlist.h:649: undefined reference to `qFree'
      cache.o: In function `QList<Logram::Depend*>::free(QListData::Data*)':
      /usr/include/QtCore/qlist.h:649: undefined reference to `qFree'
      cache.o:/usr/include/QtCore/qlist.h:608: more undefined references to `qFree' follow
      cache.o: In function `QString::QString(QString const&)':
      /usr/include/QtCore/qstring.h:715: undefined reference to `qt_assert'
      cache.o: In function `QList::free(QListData::Data*)':
      /usr/include/QtCore/qlist.h:649: undefined reference to `qFree'


      C'est donc LD qui génère ça, et ça ne se produit pas avec GCC. La liste est un peu plus longue mais ne contient pas tous les symboles de Qt, de plus, voici la ligne de commande :


      clang++ -o setup cache.o main.o app.o package.o communication.o string.o source.o repoma.o moc_app.o -L/usr/lib -llgrpkg -lQtCore -L/usr/lib -lz -lm -pthread -lgthread-2.0 -lrt -lglib-2.0 -ldl -lpthread


      C'est un bug de clang, ou alors QMake qui ne génère pas ce qu'il faut, ou alors la libQt qui est cassée quand elle n'est pas utilisée par GCC.
      • [^] # Re: Pourquoi serait-ce un bug dans Qt ?

        Posté par (page perso) . Évalué à 10.

        Un truc c'est que en C++, une bibliothèque compilée avec un compilo n'est pas nécessairement compatible avec un programme compilé avec un autre compilo.
        La norme C++ ne spécifie pas d'ABI standard.

        Or ici j'imagine que Qt à été compiler avec gcc et pas avec clang. ce peut être la raison pour laquelle la liaison des lien échoue si le mangling des noms de GCC n'est pas le même que celui de clang.

        Le mangling c'est ce qui transforme le nom d'une fonction en C++ (Foo::Bar(int)) en un nom de symbole (_Z3Foo3BarEi avec gcc)
        Si c'est pas les même, forcément le linkeur ne trouvera pas.

        (Maintenant ce que je dis est juste une supposition.)
  • # qmake et clang

    Posté par . Évalué à 7.

    Un des posteur du planet kde vient d'ajouter une entrée où il explique avoir réussi a compilé un projet qt avec clang.

    C'est ici : http://www.freehackers.org/thomas/2010/01/10/playing-with-cl(...)
    • [^] # Re: qmake et clang

      Posté par . Évalué à 2.

      Non, je ne pense pas qu'il puisse compiler un projet Qt avec clang (car il dit clairement qu'on ne peut pas compiler Qt avec clang et comme indiqué plus haut dans ce journal, on ne peut pas linker des objets clang avec des librairies GCC).

      Il dit juste qu'il a réussi à faire que qmake appelle clang pour de la compilation de code C++ (mais il ne dit absolument pas ce qu'il a réussi à compiler avec clang).

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.