Tableau de bord « tout au vert », un bug à la fois

I. Introduction

Les bibliothèques précompilées pour la version stable de WebRTC (celles utilisées dans Chrome) ont été souvent réclamées dans la mailing list, mais jusqu’à maintenant personne ne s’est attelé à la tâche de les générer. Un des buts de ce blog est de fournir ces bibliothèques afin de réduire la barrière d’entrée pour ceux qui voudraient construire au-dessus de WebRTC.

Comme je préparais les bibliothèques sous Linux, je suis à nouveau tombé sur le test défaillant que j’ai mentionné dans un post précédent:

« La première erreur semble être liée à une mauvaise allocation mémoire. C’est là que vous réalisez que lancer la compilation sur la plus petite instance possible de Linux dans AWS était probablement une mauvaise idée. Ce problème devrait disparaître lorsque je lancerais le build bot de Linux sur une instance plus grosse. La deuxième erreur est plus subtile, et je ne peux pas la comprendre juste à partir des « logs ». Lorsque j’aurais installé une instance de compilation plus puissante pour Linux, je débuggerais directement dessus. »

En ce qui me concerne, avoir ne serait-ce qu’un seul test défaillant n’est pas acceptable. J’ai donc creusé plus profond. Voici la compilation avant les changements.

II. Investigations

Entre-temps, j’ai déplacé le build bot vers une plus grosse instance (c3.2x). Effectivement, la première erreur, qui était bien un problème d’allocation mémoire provoqué par une instance trop petite, a disparu sans que j’ai eu à m’en occuper.

La deuxième erreur était liée aux tests de partage d’écran, ce qui n’est pas une surprise puisque nous travaillons sur une machine virtuelle sans affichage.

Les tests originaux sont lancés par l’intermédiaire d’un contrôleur de tests écrit en Python. Le code de ce contrôleur, qui est séparé de libwebrtc, peut être trouvé ici. Le fichier principal est ici. Là encore, il s’agit d’un code venant de Chrome qui contient tout un tas de choses inutiles pour tester la version autonome de WebRTC (Chrome sandbox…).

Il fait aussi beaucoup de bonnes choses en terme de vérification de ce qui n’a pas été couvert par les tests précédents, dont certains ont pu échouer. Il y a de nombreuses étapes supplémentaires améliorant la stabilité et le robustesse des tests, ce n’est donc pas si mal.

Pour faire simple, pour résoudre le problème de l’absence d’écran sur une machine virtuelle, vous avez seulement à installer Xvfb et openbox :

  1. sudo apt-get install xvfb
  2. sudo apt-get install openbox

puis définir un affichage, le créer, et démarrer le gestionnaire de fenêtres openbox avant de lancer votre test (le code ci-dessous est conçu pour rester au plus proche des conditions de test de Google).

  1. export DISPLAY=:9
  2. Xvbf :9 -screen 0 1024x768x24 -ac -dpi 96&
  3. openbox&

Maintenant tous les tests passent !

III. Conclusion

Garder son tableau de bord « tout au vert » est de la plus haute importance. Si le tableau de bord a des voyants au rouge, ça signifie que vous développez les yeux bandés. Garder son tableau de bord « tout au vert » est un défi quotidien. Cela peut être perçu comme trop fastidieux d’avoir à y porter autant d’attention et d’efforts, mais c’est il s’agit en fait du filet de sécurité pour les développeurs qui vous permet de vous concentrer uniquement sur le développement.

Les avantages apportés par CMake ici sont doubles : d’une part abaisser la barrière d’entrée, et d’autre part fournir un tableau de bord collaboratif.

Encore une fois, certains peuvent estimer que les outils de compilation de Chrome, aussi bons et avancés qu’ils soient, sont une surenchère dans le but de produire seulement la libwebrtc autonome. Je crois que cela ralentit l’adoption et la contribution à WebRTC puisqu’il faut d’abord devenir un développeur Chromium, et pour celà la pente d’apprentissage est très raide.

Dans tous les cas, vous pouvez maintenant télécharger les bibliothèques et les en-têtes testés et précompilés pour Linux, Mac ou Windows depuis la page « Tools« . Si ce que vous désirez est juste de développer une application par-dessus libwebrtc qui fonctionne avec le dernier Chrome stable, vous avez tout ce qu’il vous faut maintenant.

Certaines personnes demandent des fonctionnalités qui ne sont pas, ou pas encore, dans WebRTC. Dans un prochain post, j’expliquerais comment faire pour appliquer sans effort un patch à libwebrtc dans le cadre du processus décrit précédemment.

Faites vous plaisir.

Comment mettre en place des « build bots » pour libwebrtc

I. Introduction

Suite à mon précédent post, j’ai reçu beaucoup d’e-mails concernant l’installation des build bots. Je dois admettre que mon post précédent n’abordait pas ce sujet en détail et que la documentation à ce sujet est peu importante (en quantité) et confuse, tout comme le mode opératoire recommandé a changé dans la communauté cmake au cours des 15 ans des projets (VTK, ITK). Voici donc un post qui décrit, pas à pas, comment installer vos propres bots en quelques heures et comment les gérer à distance avec git sans jamais avoir à vous reconnecter à eux à nouveau (en théorie, en pratique les s#$%^ arrivent et vous pouvez souhaiter vous connecter de temps en temps pour débugguer les problèmes directement).

Garder le build bot séparé du code principal est une bonne politique car ils pourraient contenir des informations sensibles à propos de votre infrastructure. Par exemple, vous pourriez mentionner une clef d’accès pour transférer le résultat de la compilation (paquets de bibliothèques) et il vaut mieux que cette information reste privée. De plus, avec les réglages actuels, n’importe qui réussissant à avoir accès à votre script de compilation sera capable de lancer tout ce qu’il veut en utilisant votre build bot, ce qui est également quelque chose que vous ne voulez pas voir se produire. Dans notre cas, ceci est plus un tutoriel.

II. Écrire un script pour CTest

Jusqu’ci, j’ai présenté deux façons d’utiliser ctest :

  • comme une extension de CMake pour gérer les tests directement à partir des fichiers CMake ;
  • comme un client CDash, pour lancer CMake et automatiquement envoyer les résultats des étapes de la mise à niveau, de la configuration, de la compilation et des tests vers un serveur CDash

Il y a une troisième façon d’utiliser CTest : à partir de scripts. Vous pouvez écrire un fichier en utilisant la syntaxe CMake pour initialiser à l’avance les variables CTEST_<> qui serviront à lancer CTest d’une manière contrôlée. Vous tapez ensuite la commande « ctest-S » avec votre fichier en argument pour lancer CTest en mode script.

Quelques variables très utiles permettent de définir le cache CTEST,  ou des variables d’environnement, ou encore les compilateurs à utiliser et tout programme donné ou variable CMake. Cela permet, par exemple, de lancer des compilations 32 bits et 64 bits, en version debug et release, sur une même machine. Un autre exemple est d’avoir plusieurs versions de compilateurs sur une machine donnée et d’avoir des scripts CTest pour utiliser un compilateur spécifique à la fois. Un des meilleurs scripts que j’ai vu, écrit par Gaëtan Lehmann, gérait différentes versions de MSVC et Java sous Windows. Chapeau bas.

On peut obtenir plus d’informations à propos des capacités de CTest sur la vieille page écrite à une époque où on utilisait encore Purifier (ici, ici et ), et une version plus récente ici.

III. Qu’en est-il de libwebrtc ?

Pour cet exemple, j’ai utilisé la méthode la plus récente développée pour ITK v4. Vous trouverez ici un rapide aperçu. Cette version était centrée sur git et elle met en place quelques astuces pour gérer différentes branches, ce qui facilite la mise en place de bots pour les branches de développement.

1. Un script générique qui fait tous les travaux lourds

L’idée est d’avoir un script très général qui gère la plupart des problèmes pour vous et de laisser seulement quelques variables à définir par l’utilisateur. J’ai porté le script générique de manière à ce qu’il soit utilisable pour libwebrtc : libwebrtc_common.cmake. Sauf si vous êtes un puriste, je recommande de ne pas le modifier, ni même de le consulter. Il vous permet maintenant de définir un ensemble de paramètres, certaines variables CMAKE ou CTEST habituelles, ainsi que quelques nouvelles variables du tableau de bord, pour contrôler votre compilation.

  • dashboard_model = Nightly | Experimental | Continuous
  • dashboard_track = chemin optionnel vers lequel soumettre le tableau de bord
  • dashboard_loop = répéter jusqu’à ce qu’une durée de N secondes se soit écoulée
  • dashboard_root_name = changer le nom du répertoire « My Tests »
  • dashboard_source_name = nom du répertoire contenant les sources (libwebrtc)
  • dashboard_binary_name = nom du répertoire où seront placés les binaires (libwebrtc-build)
  • dashboard_data_name = nom de la zone de stockage des données externes (ExternalData)
  • dashboard_cache = contenu initial du fichier CMakeCache.txt
  • dashboard_do_cache = toujours écrire CMakeCache.txt
  • dashboard_do_coverage = True pour activer la couverture de code (par exemple avec gcov)
  • dashboard_do_memcheck = True pour activer la recherche des fuites mémoire (par exemple avec valgrind)
  • dashboard_no_clean = True pour sauter l’étape d’effacement de l’arborescence de compilation
  • dashboard_no_update = True pour sauter la mise à jour de l’arborescence du code source
  • CTEST_UPDATE_COMMAND = chemin vers le client git ligne de commande
  • CTEST_BUILD_FLAGS = arguments pour l’outil de compilation (par exemple : -j2)
  • CTEST_BUILD_TARGET = indique une cible particulière à compiler (à la place de toutes les cibles)
  • CTEST_DASHBOARD_ROOT = indique où mettre les arborescences du code source et de compilation
  • CTEST_TEST_CTEST = précise s’il faut exécuter ou pas les longs tests CTestTest*
  • CTEST_TEST_TIMEOUT = pour chaque test, précise quelle est la durée du timeout
  • CTEST_COVERAGE_ARGS = arguments pour la commande ctest_coverage
  • CTEST_TEST_ARGS = arguments pour ctest_test (par exemple : PARALLEL_LEVEL 4)
  • CTEST_MEMCHECK_ARGS = arguments pour ctest_memcheck (par défaut CTEST_TEST_ARGS)
  • CMAKE_MAKE_PROGRAM = chemin vers l’outil « make » à utiliser
  • Options pour configurer les compilations du dépôt expérimental de git :
  • dashboard_git_url = définition d’une URL spéciale pour git clone url
  • dashboard_git_branch = définition d’une branche spéciale à suivre
  • dashboard_git_crlf = valeur de la variable core.autocrlf pour le dépôt

Si vous voulez étendre la capacité de ce script principal, quelques hameçons sont fournis afin de conserver les choses proprement et de manière compartimentée.

  • dashboard_hook_init = fin de l’initialisation, juste avant la boucle
  • dashboard_hook_start = début du corps de la boucle, avant ctest_start
  • dashboard_hook started = après ctest_start
  • dashboard_hook_build = avant ctest_build
  • dashboard_hook_test = avant ctest_test
  • dashboard_hook_coverage = avant ctest_coverage
  • dashboard_hook_memcheck = avant ctest_memcheck
  • dashboard_hook_submit = avant ctest_submit
  • dashboard_hook_end = fin du corps de la boucle, après ctest_submit

2. Un fichier très simple pour définir un bot

Finalement, cela permet effectivement d’écrire un script de compilation effectivement très simplement :

  1. set(CTEST_SITE « Bill_._Our_fearless_leader » )
  2. set(CTEST_BUILD_NAME « Ubuntu-12.04-32-Deb » )
  3. set(CTEST_BUILD_FLAGS -j8 )
  4. set(CTEST_DASHBOARD_ROOT « /home/ubuntu/Dashboards » )
  5. set(CTEST_TEST_TIMEOUT 1500 )
  6. set(CTEST_BUILD_CONFIGURATION Debug )
  7. set(CTEST_CMAKE_GENERATOR « Unix Makefiles » )
  8. set(dashboard_model Experimental )
  9. include(libwebrtc_common.cmake)

Et … voilà ! Vous avez un build bot linux prêt ! Remplacez « Debug » par « Release » et votre compilation en version release est prête. Pour passer de 32 à 64 bits, comme nous utilisons ninja, vous devez positionner la bonne variable d’environnement, mais ce n’est pas difficile non plus :

  1. set(CTEST_ENVIRONMENT
  2.     « GYP_DEFINES=’target_arch=x64′ » # ou ia32 pour 32 bits
  3. )

Vous trouverez le fichier correspondant ici.

Une mise en garde tout de même, installer l’environnement de développement pour libwebrtc est difficile. Premièrement, cela ne marchera quasiment que sous Ubuntu ; deuxièmement, les scripts d’installation de l’environnement semblent ne pas fonctionner donc vous devrez au final installer manuellement quelques bibliothèques avant de pouvoir compiler. La bonne nouvelle c’est que vous ne devrez le faire qu’une seule fois.

3. Comment automatiser tout cela ?

Maintenant vous êtes armés de nombreux fichiers pour chaque compilation que vous voulez lancer. Vous pourriez très bien lancer plusieurs compilations sur la même machine, par exemple 32/64, Debug/Release. Pour des machines sous Linux, vous pouvez également souhaiter faire une compilation croisée avec des binaires Android (plus sur les cibles pour les mobiles dans un prochain post).

Toutefois, vous avez toujours besoin d’accéder à la machine et de lancer manuellement

  1. ctest -S My_Build_script.cmake

pour que cela fonctionne.

Une façon de contouner cela consiste à définir un script (shell) qui lance ces commandes pour vous. Cependant, à chaque fois que vous apportez une modification au script, vous devez à nouveau vous connecter à la machine et mettre à jour manuellement le script local avec la nouvelle version, grrrrr.

C’est ici que cron (sur Linux ou Mac) et le planificateur de tâches (sur Windows) sont très pratiques, car ils peuvent lancer une commande à un jour et une heure prédéfinis pour un utilisateur donné. Ici vous avez deux écoles : les premiers utilisateurs de CMake ont tout conçu de telle sorte qu’il soit possible de configurer leurs ordinateurs (qui restent toujours allumés) pour être utilisés pendant les heures de sommeil. Plus récemment, les développeurs ont mis en place soit un build bot dédié, soit un build bot hébergé, et ils réduisent les coûts en éteignant la machine une fois le travail terminé. Je vais illustrer la deuxième solution pour Linux (et Mac) et les fichiers pour Windows seront fournis sur le compte github, pour ceux que ça intéresse. Spécialement pour les build bots Windows, notez qu’il a été démontré qu’il vaut mieux redémarrer la machine une fois par jour dans tous les cas si vous voulez que cela fonctionne…

Démarrer des instances à distance est facile, tous les fournisseurs de cloud proposent une API de ligne de commande, et vous pouvez maintenir un maître (sur la plus petite instance possible) dont le seul travail consiste à réveiller les bots une fois par jour pour qu’ils récupèrent la dernière version du code, qu’ils configurent la compilation, lancent la compilation et les tests et qu’il soumettent les résultats au tableau de bord. Dans AWS EC2, ça veut dire jouer avec IAM, mais rien de trop difficile, de plus c’est très bien documenté. Sous Linux, le démon cron accepte le mot-clé « reboot », qui indique que la tâche correspondante sera exécutée à chaque fois que l’instance est démarrée.

  1. @ reboot/home/ubuntu/Dashboards/Scripts/Bill-runall.sh

Finalement, il vous suffit d’utiliser la commande shutdown dans votre script pour arrêter l’instance quand les tâches sont terminées.

  1. shutdown -h now

Il ne nous reste plus qu’à automatiser les mises à jour des scripts.

L’astuce utilisée par la communauté ITK est de conserver les scripts (et la table « cron ») dans un dépôt git et de mettre à jour, en premier, ce dépôt. Dans cet exemple, vous pouvez voir depuis le script shell que nous nous attendons à ce que le répertoire ~/Dashboard/Scripts contienne les scripts de compilation, qu’il existe un répertoire ~/Dashboard/Logs, et que la crontable soit mise à jour au passage. Maintenant il me suffit d’effectuer un commit dans mon dépôt git pour que le bot de compilation se mette à jour automatiquement de lui-même. C’est trop bon !

  1. # Aller dans le répertoire de travail
  2. cd /home/ubuntu/Dashboards/Scripts
  3. # Récupérer la dernière version des scripts
  4. git pull -rebase -q
  5. # Mettre à jour la crontable
  6. crontab ./Bill-crontab
  7. # Lancer les compilations et les tests
  8. ctest -S ./Bill-32-Debug.cmake
  9. ctest -S ./Bill-32-Release.cmake
  10. # Terminé. Arrêtons l’instance pour ne pas payer trop
  11. sudo shutdown -h now

Le script complet avec quelques fonctionnalités supplémentaires est disponible ici.

IV. Conclusion

Cela devrait maintenant être assez clair que mettre en place un build bot pour libwebrtc est relativement facile. Le code fourni dans github devrait rendre cette tâche encore plus facile. Vous êtes libres de mettre en place votre propre build bot, y compris avec des paramètres qui ne sont pas encore présents dans les bots contribuant aujourd’hui au tableau de bord, ce qui permettra de contribuer au jeu… Je devrais faire une mise à jour vers un serveur CDash plus gros ce qui permettra très bientôt d’avoir plus de 10 compilations par jour. J’adorerais voir des gens contribuer pour ajouter la compilation pour ARM, Androïd, iOS…

Si vous trouvez ça utile, faites le connaître autour de vous, et sachez que les commentaires sympas sont eux aussi appréciés. 😉

Installer libwebrtc

I. Introduction

Une fois que la bibliothèque pour le développement est compilée, il est possible de l’utiliser directement depuis le « build tree » pour n’importe quel projet qui en dépend. En général ceci n’est pas une bonne idée si votre équipe de développement est constituée de plusieurs membres, si vous utilisez des systèmes divers et/ou si vous voulez répartir votre travail. C’est ici que la notion d’installation et de version a un sens (1). Le packaging (2) vous permet alors une installation sur un ordinateur différent de celui sur lequel vous avez créé votre projet. Après l’installation de la bibliothèque (ainsi que les entêtes correspondantes et les autres fichiers nécessaires) il serait également agréable de pouvoir l’importer (3) facilement dans un autre projet.

La bonne nouvelle est que CMake gère tout cela avec (encore !) un très petit nombre de lignes de code. En utilisant la commande  » install() » vous pouvez choisir quoi installer, où l’installer et, dans une certaine mesure, coupler des fichiers d’extension par composant pour les installateurs interactifs. Vous vous souvenez peut être que je vous ai dit dans un post précédent que CMake est une sorte de trilogie (CMake/CTest/CDash). Eh bien, sachez qu’il existe une suite appelée CPack mais qui n’est pas aussi bien que les premiers (les suites le sont rarement), mais ce dernier a son propre préfixe variable cmake, donc je pense que c’est cool :-). CPack gère la partie mise en paquets qui est générée au-dessus du processus d’installation. Maintenant creusons un peu.

II. Installer les cibles et fichiers localement

Dans notre utilisation de CMake, nous n’avons pas de cible pour chaque bibliothèque ou fichier exécutable. En outre, les tests ne sont pas facilement relocalisable, donc il est préférable de ne pas essayer. Les bibliothèques peuvent être installées dans une arborescence plate, mais les en-têtes doivent se trouver dans une certaine structure de répertoires pour être utilisables, nous devons donc suivre deux stratégies différentes. Finalement, la commande install() a de nombreuses signatures, concentrons-nous donc sur celles qui nous seront utiles.

1. Versionnage

Le versionnage suit la convention CMake (pour être compatible avec les autres outils et commandes) comme expliqué ici :

  1. #———————————————
  2. # Versionnage
  3. set (WEBRTC_MAJOR_VERSION 0) # pas encore complètement testé
  4. set (WEBRTC_MINOR_VERSION 1) # vraiment pas complètement testé, et pas complètement implémenté non plus
  5. set (WEBRTC_BUILD_VERSION 1) # devrait être le numéro de révision SVN, mais il est difficile de l’obtenir automatiquement depuis le message de commit de git
  6. set (WEBRTC_VERSION
  7.              ${WEBRTC_MAJOR_VERSION}.${WEBRTC_MINOR_VERSION}.${WEBRTC_BUILD_VERSION}
  8. )
  9. set (WEBRTC_API_VERSION
  10.     # c’est le style ITK/VTK où SOVERSION est constitué de deux nombres…
  11. « ${WEBRTC_MAJOR_VERSION}.${WEBRTC_MINOR_VERSION} »
  12. )
  13. set( WEBRTC_LIBRARY_PROPERTIES ${WEBRTC_LIBRARY_PROPERTIES}
  14. VERSION         « {WEBRTC_VERSION} »
  15. SOVERSION    « ${WEBRTC_API_VERSION} »
  16. )

Lecture complémentaire:

2. Configurer les dossiers de destination par type de composant

Ici encore, rien de fantaisiste, nous nous contentons de suivre la convention de CMake de façon à ce que find_package puisse être utilisé ultérieurement (voir la documentation de find_package() sur les chemins attendus).

  1. #__________________________________________
  2. # Configurer le « export configuration »
  3. # WEBRTC_INSTALL_BIN_DIR             -binary dir (exécutables)
  4. # WEBRTC_INSTALL_LIB_DIR              -library dir (bibliothèques)
  5. # WEBRTC_INSTALL_DATA_DIR          -share dir (exemples, données, etc.)
  6. # WEBRTC_INSTALL_INCLUDE_DIR   -include dir (en-têtes)
  7. # WEBRTC_INSTALL_CMAKE_DIR      -cmake files (CMake)
  8. if ( NOT WEBRTC_INSTALL_BIN_DIR )
  9.     set ( WEBRTC_INSTALL_BIN_DIR « bin »)
  10. endif()
  11. if ( NOT WEBRTC_INSTALL_LIB_DIR )
  12.     set ( WEBRTC_INSTALL_LIB_DIR « lib » )
  13. endif()
  14. if( NOT WEBRTC_INSTALL_DATA_DIR )
  15.     set( WEBRTC_INSTALL_DATA_DIR « share »)
  16. endif()
  17. if( NOT WEBRTC_INSTALL_INCLUDE_DIR)
  18.     set( WEBRTC_INSTALL_INCLUDE_DIR « include »)
  19. endif()
  20. if( NOT WEBRTC_INSTALL_CMAKE_DIR)
  21.     set( WEBRTC_INSTALL_CMAKE_DIR « lib »)
  22. endif()

3. Gestion des bibliothèques

Comme nous avons fait pour les tests, nous devrons d’abord importer tous les noms de bibliothèques du système de fichiers avant de pouvoir faire quoi que ce soit. Contrairement aux tests, pour lesquels nous devions gérer différents arguments pour chaque test, toutes les bibliothèques sont traitées de la même façon donc nous pouvons automatiser le processus. La commande file(GLOB_RECURSE) fait exactement cela. Sur Mac, toutes les bibliothèques se trouvent à la racine de l’arborescence de compilation de ninja, mais sous Windows chaque bibliothèque est créée dans son propre sous-répertoire, nous devons donc utiliser le GLOB_RECURSE et pas seulement le GLOB comme pour Mac.

  1. set(WEBRTC_BUILD_ROOT ${WebRTC_SOURCE_DIR}/src/out/${CMAKE_BUILD_TYPE}) # la variable CMAKE_BUILD_TYPE permet la cohérence avec la cible de compilation
  2. set(WEBRTC_LIB_EXT a) # valeur par défaut.
  3. if(WIN32)
  4.     set(WEBRTC_LIB_EXT lib) # vous êtes sous Windows ! donc les noms des bibliothèques ont pour extension .lib 🙂
  5. endif()
  6. file( GLOB_recurse # sous Windows, les bibliothèques sont dans des sous-dossiers
  7.     WEBRTC_LIBS        # la variable de sortie.
  8.     ${WEBRTC_BUILD_ROOT}/* ${WEBRTC_LIB_EXT} # le motif, c’est-à-dire tous les fichier ayant la bonne extension se trouvant sous la racine du répertoire de compilation
  9. )

Maintenant, nous pourrions directement alimenter la commande install() avec ceci :

  1. foreach( lib ${WEBRTC_LIBS}
  2.     install(
  3.         FILES                      ${lib}
  4.         DESTINATION ${WEBRTC_INSTALL_LIB_DIR}
  5.          COMPONENT   Libraries
  6. )
  7. endforeach()

Cependant, nous voulons supprimer les bibliothèques qui étaient utilisées pour les tests, et nous devons préparer une liste des bibliothèques pour remplir un fichier de configuration qui sera installé avec les bibliothèques et faciliter l’utilisation de la version installée. La version complète ressemble à cela :

  1. set(WEBRTC_LIBRARIES » ») # préparation de la configuration pour l’arborescence de complation
  2. foreach(lib ${WEBRTC_LIBS})
  3.     string(FIND ${lib} « test » IS_TEST)
  4.     if(IS_TEST EQUAL -1)
  5.         get_filename_component(lib_name ${lib} NAME_WE)
  6.         string(REPLACE « lib » «  » lib_target_name ${lib_name})
  7.         set(WEBRTC_LIBRARIES ${WEBRTC_LIBRARIES} ${lib_target_name})
  8.         install(
  9.             FILES         ${WEBRTC_BUILD_ROOT}/${lib}
  10.             DESTINATION ${WEBRTC_INSTALL_LIB_DIR}
  11.             COMPONENT Libraries
  12.         )
  13.     endif()
  14. endforeach()

4. Gestion des fichiers d’entête

La partie délicate de la gestion des fichiers d’entête vient du fait que les fichiers qui les incluent supposent que les fichiers d’entête sont rangés selon une certaine arborescence définie à partir d’un répertoire racine spécifique. Les fichiers DEPS donnent quelques indications à propos des répertoires à utiliser pour les directives include :

  1. # définir les règles pour lesquelles les chemins d’include sont autorisés dans notre source.
  2. include_rules=[
  3.     # La Base est utilisée uniquement pour construire des tests Android APK et ne doit pas être référencée par le code de production WebRTC
  4.     ‘-base’,
  5.     ‘-chromium’,
  6.     ‘+gflags’,
  7.     ‘+net’,
  8.     ‘+net’,
  9.     ‘+testing’,
  10.     ‘+third_party’,
  11.     ‘+webrtc’,
  12. ]

À part les flags manquants, ce sont tous les répertoires de niveau supérieur des sources WebRTC. Une rapide vérification (grep -R -h \#include * | sort -u > log) confirme qu’il s’agit bien de la disposition attendue par les directives #include.

Donc pour chacun des répertoires /net, /talk, /testing, /third_party, /webrtc, nous devons parcourir leur arborescence et l’utiliser au moment de l’installation (c’est la principale différence avec le code qui gère les bibliothèques). Ceci justifie l’utilisation de l’option RELATIVE pour la commande file(GLOB_RECURSE).

  1. file(
  2.     GLOB_RECURSE header_files                                                      # variable de sortie
  3.     RELATIVE ${WebRTC_SOURCE_DIR}/src                                 # le chemin sera relatif à /src/, comme attendu par les #includes
  4.     FOLLOW_SYMLINKS                                                                      # nous devons suivre les liens symboliques vers les sous-dossiers de Chromium
  5.     ${WebRTC_SOURCE_DIR}/src/net/*.h
  6.     ${WebRTC_SOURCE_DIR}/src/talk/*.h
  7.     ${WebRTC_SOURCE_DIR}/src/testing/*.h
  8.     ${WebRTC_SOURCE_DIR}/src/third_party/*.h
  9.     ${WebRTC_SOURCE_DIR}/src/webrtc/*.h
  10. )

Maintenant il est simple d’écrire la commande d’installation.

  1. foreach( f ${header_files} )
  2.     get_filename_component( RELATIVE_PATH ${f} PATH ) # NOTE D’ALEX : il semble que les versions récentes de CMake utilisent DIRECTORY à la place de PATH…
  3.     install(
  4.         FILES                 ${WebRTC_SOURCE_DIR/src/${f}
  5.         DESTINATION ${WEBRTC_INSTALL_INCLUDE_DIR}/${RELATIVE_PATH}                                 # voici la partie délicate
  6.         COMPONENT   Headers
  7. )
  8. endforeach()

5. Sommes-nous arrivés au bout ?

OUI ! Nous pouvons maintenant installer. Vous avez maintenant une cible d’installation dans votre système de compilation. Sous Mac, vous pouvez simplement taper « make install », sous Windows, si vous utilisez les options par défaut (ninja/MSVC) vous aurez une cible « INSTALL » dans la liste des cibles MSVC. La compilation n’est pas lancée par défaut, vous devez la lancer manuellement. Les droits administrateur sont nécessaires. Par défaut, tout est installé sous /usr/local pour Mac et Unix et sous « Program Files » pour Windows (avec (x86) pour la compilation en 32bits).

Dans un prochain post, je vous montrerais comment assembler ces fichiers dans un package pour les installer sur un ordinateur distant.

Prendre soin de mon tableau de bord

11046789_1010459968998193_7337377444744452326_o

Un tableau de bord est comme un jeune enfant, fragile et en demande d’attention. Alors que pour la plupart des gens le tableau de bord n’apporte pas autant de valeur ajoutée qu’une nouvelle application dans la bibliothèque (comme un joli installateur de bibliothèque, plus d’info dans un prochain post), pour les développeurs c’est la clef du succès.

La plupart des développeurs ont des préférences pour certains systèmes d’exploitation ou outils de développement. En ce qui me concerne, je fais la majorité de mes développements sur Mac. Toutefois, vous devez savoir que le code est testé sous plusieurs systèmes d’exploitation, compilateurs, options, etc. Si votre tableau de bord est à jour et bien entretenu, la plupart du temps ça vous évitera d’avoir à tester votre code pour chaque configuration. Il faut donc mettre en place plusieurs choses pour que le tableau de bord soit utilisable au maximum de ses capacités et soit votre filet de sécurité.

  • Tous les systèmes d’exploitation, compilateurs et options pris en charge doivent apparaître comme une compilation indépendante dans le tableau de bord (dans notre cas, nous voulons avoir autant de compilations qu’il en existe dans la cascade officielle).
  • Le code doit être testé autant que possible sur chaque plateforme, vous devez donc avoir de la visibilité sur la couverture du code pour chaque plateforme (plus dans un prochain post).  Enlever un test défaillant pour faire en sorte que tout soit au vert sur votre tableau de bord, et ainsi cacher une erreur, n’est pas une bonne chose.
  • Le tableau de bord doit toujours rester au vert (donc sans aucune erreur lors des tests), ainsi, quand une nouvelle erreur se produit vous la remarquez immédiatement et elle ne se confond pas avec un test défaillant antérieur.

De ce fait, hier, j’ai passé un peu de temps à tester mes scripts sur Linux. Comme prévu; ça a fonctionné presque tel quel, mais les premiers résultats ont montré 9 tests qui ont échoué ! C’est somme toute beaucoup. Alors j’ai fait un double contrôle sur la cascade officielle, et pour ce qui concerne la compilation Linux, tout était au vert, donc il y a quelque chose que je devais mal faire. Ou peut être pas finalement ?

En regardant la cascade, il y avait 47 rapports de compilation. La matrice de base pour calculer les différentes types de compilation utilise les paramètres suivants :

  • système d’exploitation : Windows, Mac, iOS, Linux, Android,
  • architecture : 32 / 64 bits
  • BUILD_TYPE : Debug / Release
  • OPTIONS : Normal / Large-tests / GN / Simulator / (autres compilations exotiques)
  •  Pour Android : try bots sur des matériels réels : Nexus 5, 7.2, 9

Je ne veux pas tout reproduire, enfin pas pour l’instant, mais j’aimerais commencer par couvrir tous les systèmes d’exploitation, leurs architectures, et les modes de compilation (Debug / Release). En consultant la compilation release linux 32, j’ai réalisé qu’elle exécutait moins de test que les versions Windows ou Mac. J’ai donc commencé par modifier mes scripts de test pour ne pas les inclure ceux qui manquent si la plateforme est Linux. Boum, il ne restait plus que deux erreurs.. La première erreur semble être liée à une mauvaise allocation mémoire. C’est là qu’on réalise que lancer la compilation et les tests sur la plus petite instance de Linux dans AWS etait une mauvaise idée. Cette erreur devrait disparaître lorsque j’hébergerai le bot de compilation de Linux sur une instance AWS plus grande. La seconde erreur est plus difficile à cerner et je ne peux pas la comprendre en utilisant seulement les logs. Lorsque j’aurais mis en place une instance Linux plus puissante pour la compilation, je déboguerais.

Les prochains posts porteront sur le packaging et l’ajout de calcul de couverture (pour les compilateurs gcc et clang) et la vérification des fuites mémoire (en utilisant valgrind). Restez connecté.