URL: https://linuxfr.org/users/steckdenis/journaux/clang-est-pr%C3%AAt Title: Clang++ est prêt Authors: steckdenis Date: 2010年05月24日T12:41:54+02:00 Tags: objective-c Score: 32 Bonjour, Ce week-end, alors qu'il m'était impossible de réactualiser frénétiquement la page d'accueil de Linuxfr pour voir s'il n'y avait rien d'intéressant, je suis allé sur le site de [LLVM](http://llvm.org/). Tout d'abord, la page d'accueil de ce site est un peu plus peuplée, et liste tous les projets intéressantes de LLVM : * **LLVM** lui-même, architecture modulaire permettant de créer des compilateurs pour plein de langages, mais aussi des interpréteurs, etc * **Clang**, le compilateur C, C++, Objective-C et Objective-C++ se basant sur LLVM pour la génération de code. * **llvm-gcc** et **DragonEgg**, deux projets visant à intégrer LLVM dans GCC, donc de se servir des _front-ends_ de GCC et de LLVM pour générer le code. llvm-gcc est un fork de GCC 4.2, DragonEgg est un plugin pour GCC 4.5. * **libc++**, projet jeune et très intéressant, conciste à une réécriture de la libstdc++, sous licence LLVM. Le projet est complet à 80% (en comptant les nouveautés du C++0x). Cette réécriture est en particulier demandée par l'arrivée de cette nouvelle version du C++, qui oblige des changements de fond dans les bibliothèques C++. Au lieu de hacker la libstdc++ de GCC, les développeurs de LLVM préfèrent en recréer une nouvelle, tirant parti des découvertes et inventions faites dans le domaine depuis les dernières années. * **compiler-rt**, équivalent LLVM de la libgcc. Cette petite bibliothèque contient des fonctions souvent appelées dans le code, permettant d'émuler des opérations qu'un certain _target_ ne supporte pas. Par exemple, il est difficile pour certains processeurs de convertir un nombre flottant sur 32 bits (float) en un double (64 bits). * **vmkit**, essai visant à émuler une machine virtuelle Java ou .NET au-dessus de LLVM. La machine virtuelle Java fonctionne déjà plus ou moins et sait lancer Eclipse, Tomcat, etc. * **Klee** est un genre d'analyseur de code. On compile son code, on le lance dans Klee, et il nous dit toutes les valeurs que peuvent prendre les variables. Ça permet de voir s'il n'y a pas de pointeurs NULL qui se baladent, pas de code inutilisé, combien de fois une boucle est utilisée, etc. Mais ce qui m'intéresse ici est [Clang](http://clang.llvm.org), le compilateur pour les langages de la famille du C. Comme je l'avais dit dans mes précédant journaux, Clang essaie de supporter le C++, ce qui est difficile étant donné la complexité atroce de ce langage pour le compilateur. Hier, je me balade donc sur le site de Clang. Je clique sur la page [Statut du C++](http://clang.llvm.org/cxx_status.html), et voit qu'elle est quasiment vide. Auparavant, elle contenait une centaine (voire plus) de lignes dans un tableau, une pour chaque test du standard C++ 2003. Au fur et à mesure que le temps passait, des tests passaient en vert, ou du rouge vers l'orange quand ils étaient implémentés. Ce tableau n'existe plus pour le C++ standard, il n'en reste qu'un petit morceau pour le futur C++-0x. Je lis donc attentivement l'introduction de cette page et découvre ceci : > Clang currently implements all of the ISO C++ 1998 standard (including the defects addressed in the ISO C++ 2003 standard) except for 'export' (which has been removed from the C++'0x draft). However, the implementation of Clang C++ is still somewhat immature, with remaining bugs that may cause compiler crashes, erroneous errors and warnings, or miscompiled code. The LLVM bug tracker contains a Clang C++ component that tracks known Clang C++ bugs.> / Ou pour les anglophobes : > Clang implémente pour le moment tout le standard ISO C++ 1998 (incluant les défauts corrigés dans le standard ISO C++ 2003), sauf 'export' (qui a été retiré du brouillon du C++-0x). Cependant, l'implémentation du C++ de Clang est encore un peu immature, avec des bugs qui peuvent causer des crashs du compilateur, de fausses erreurs et warnings, ou un code mal compilé. Le bug tracker de LLVM contient un composant Clang C++ permettant de traquer les bugs connus du C++ de Clang> / (désolé pour la traduction pourrie, c'est du fait-main et je ne traduis pas souvent). Il s'avère donc que Clang supporte tout le C++, sauf quelques extensions (listées sur une page spéciale). Je m'arme donc d'un programme de test en C++, j'ai nommé Setup, le gestionnaire de paquets que je développe. Il est composé de 15k SLOC C++, utilisant Qt, des templates, toute forme d'héritage, le préprocesseur, les bindings C (extern "C"), la surcharge des opérateurs, etc. Une bonne partie du C++ (mais pas les exceptions). Je lance donc Clang dessus, avec un simple «cmake -DCMAKE_CXX_COMPILER="clang++"». Je lance make, ça marche. Out-of-the-box en plus ! Rien à faire ! C'est un succès total. Clang me génère même des warnings que GCC ne me trouvait pas. Je les ai corrigés. Setup se lance, fait tout ce que je lui demande, et bien. Clang a vaincu un programme complexe, architecture bibliothèque-clients, utilisant Qt. Je regarde un peu le [blog de LLVM](http://blog.llvm.org) et vois que Clang compile impeccablement la bibliothèque C++ Boost, réputée pour sa complexité. Son support du C++ est donc devenu excellent. **Benchmarks** Maintenant, place aux benchs. Tout d'abord, j'ai consulté [cette page](http://llvm.org/docs/CompilerDriver.html), une page pour les hardcore hackers (oui oui), qui décrit comment créer un plugin pour LLVMC. LLVMC est comme GCC, c'est à dire un directeur de compilation (compiler driver). C'est lui qui parse les options qu'on lui donne, et décide quels programmes appeler. Par exemple, on peut générer des fichiers objets à partir de fichiers en C, mais on peut aussi lier les fichiers objets en un exécutable. LLVMC fonctionnait déjà avant mon intervention, mais pas comme je voulais. Il se comportait trop comme GCC, compilant le code en dur, le liant en utilisant LD, etc. Pour mes tests, je l'ai modifié pour utiliser 100% LLVM. Les fichiers C sont compilés en fichiers bitcode LLVM, sortis sous forme de .o (mais qui ne sont pas des .o normaux). Le lieur n'est pas LD, mais llvm-link. Le but du machin est du tirer au maximum parti de LLVM et de Clang. Voici théoriquement comment se déroule la compilation : * Clang compile les fichiers .c, .cpp, .m et .mxx en fichiers .o, contenant du bitcode LLVM non-optimisé. Les options -Ox sont ignorées ici. * llvm-link lie ces fichiers .o en un gros fichier .o, toujours non-optimisé. * Si on a précisé une option -Ox, alors opt (l'optimiseur de LLVM) est appelé sur ce fichier .o, et génère un fichier .o optimisé. Le but de la manoeuvre est d'optimiser une seule fois (plus rapide), et surtout sur un seul fichier. On a ainsi gratuitement une Link Time Optimization, beaucoup plus efficace et agressive qu'une optimisation après chaque compilation. * La sortie de opt, ou de llvm-link si on n'optimise pas, est fournie à llvm-ld. Ce programme sort un script shell, lançant l'interpréteur LLVM sur un fichier .bc, contenant le bitcode complet du programme. Il est également possible de passer l'option "-native" à LLVMC, qui la passera à llvm-ld, qui sortira alors un beau fichier ELF comme on a l'habitude. Chaîne de compilation relativement classique, et plus simple que celle de GCC (qui appelle tout un tas de lieurs, assembleurs, collect2, etc). Les chiffres maintenant. Comme toujours, je me sers de [Cream](http://cream-browser.net/), un navigateur web léger développé par une connaissance (oui je fais de la pub, mais j'aime bien ce navigateur). C'est du C, pas du C++, mais il utilise GTK et Webkit. Il est donc intéressant. Les tests sont faits sur un Packard Bell DOT/MA.FR-30, c'est à dire un Netbook avec un disque dur 5200tpm de 160Gio, 1Gio de RAM DDR2 660Mhz, un processeur AMD Athlon 64 L110 à ... 1,2Ghz, 512Kio de cache, carte graphique ATI Radeon X1270 (RS690G). Bref, une bouze niveau rapidité, mais il a un magnifique écran 1366x768 (troll: et KDE 4.4 tourne comme un charme dessus, et se lance en quelques secondes) [/mavie]. * Compilé avec **gcc**, en -g -O2 (options standard des autotools), la compilation prend 16,715 secondes. * Compilé avec **gcc -flto**, toujours en -O2, sans le -g (incompatible avec -flto), la compilation crashe après 17,670 secondes. * Compilé avec **llvmc** (Clang donc, relisez ce que je met plus haut pour comprendre), toujours en -g -O2, la compilation prend 10,295 secondes. Simplement, j'ai alors un fichier bitcode, pas un exécutable. * Compilé avec **llvmc -native**, en -g -O2, la compilation prend 12,166 secondes, et j'ai un fichier ELF fonctionnant parfaitement. Niveau vitesse de compilation, il n'y a pas photo. GCC prend près de 17 secondes, Clang en prend 12, alors qu'il utilise des optimisations plus agressives, faites au moment de la liaison finale. Dans les deux cas, Cream est parfaitement fluide et affiche sans problème n'importe quel site web. Je referai bientôt des tests plus poussés du C++, en compilant Blender par exemple, pour voir ce que ça donne. Je dois d'abord corriger quelques problèmes, en particulier le fait que les outils que j'utilise (CMake, les autotools) ne sont pas habitués à avoir du bitcode LLVM à la place du ELF. Il y a plein de _strip_ partout, les fichiers compilés sont lancés, etc. Voilà. Journal un peu long, mais j'ai dit tout ce que j'avais à dire.

AltStyle によって変換されたページ (->オリジナル) /