La guerre pour les talents webrtc

Dans le petit monde du logiciel innovant (Bay Area Fever), les financements ne sont pas difficile à trouver. Il y a beaucoup d’argent autour, BEAUCOUP! Autour de 23% de tout les financements aux USA (47+ milliards) venaient, l’année dernière, de compagnies de SF.

La valeur n’est pas tant associé au capital, mais aux compétences des gens qui vont récupérer ce capital et  faire en sorte que la valeur financière originale soit multipliée. Le capital n’a de valeur que le jour où vous le récupérez, les compétences de l’équipe ont une valeur pour le futur de la compagnie.

L’ingénieur et le chercheur en moi se sent comme à la maison. Si vous faites une différence, vous n’êtes pas un simple employé qui fait son boulot et récupère son salaire, vous êtes quelqu’un qui prends un financement d’un demi million et le transforme en quelque chose qui vaut 20+ millions.

Les chefs intelligents savent ça très bien. Le talent est la clé de la crédibilité, de l’execution et de l’évaluation. Ce n’est pas une surprise que la course aux talents dans la vallée soit devenue une guerre. (ici, ici, ici ). Cela est bon et sain. Les clauses de non concurrence sont par ailleurs illégales en Californie, pour protéger les talents, qui seraient prives d’opportunités. Le temps où Apple et ses concurrents se mettaient d’accord pour ne pas se « piquer » les talents les uns les autres est révolu.

Dans un post précédent, j’ai pointé du doigt certains produits et/ou individus dans l’écosystème webrtc que j’estimais etre exceptionnels. Ca ne surprendra aucun lecteur que l’un des ingénieurs les plus en vu, le numéro un des chercheurs webrtc, hors google et mozilla, Philippe Hancke, ait sauté le pas et ai rejoint Tokbox.

Je voudrais bien croire qu’il a eu peur quand je lui ai dit que nous, à Citrix, allions contester sa suprématie de chercheur en 2016, et qu en reaction il s’est associé avec le numéro 2, je pense que la raison est toute autre. Tokbox a, aujourd’hui, le WebRTC PaaS le plus mature, avec une visibilité totale et en temps réel sur tout ce qui se passe, le genre de visibilité qui permettra à un ingénieur remarquable de faire la différence, ce qui est important pour lui et donc fait rentrer de l’argent, ce qui est important pour Tokbox.

Dans tous les cas, dans la guerre qui se déroule à S.F., illustrée par example au travers de la guerre du sponsoring (je te sponsorise ton event si tu ne laisse pas l autre parler) entre twilio et tokbox pour les événements webrtc en 2015, Tokbox a définitivement gagné cette bataille.

Sérieux coup de chaleur pour WebRTC en Asie ce mois-ci.

Les points chauds pour WebRTC sont saisonniers.

La majorité des nouvelles sur WebRTC nous viennent des USA. Rencontres, événements, développements, levees de fond, tout pointe vers les Etats Unis d’Amérique, avec aussi une poignée de compagnies qui se battent pour que cela arrive un peu plus au nord ( salut à mes amis canadiens de hookflash, priologic, …). Plus récemment l’excellente conférence IIT’s Real-Time organisé simultanément avec tad hack mini a placé le centre de gravité de l’écosystème WebRTC à Chicago.

Régulièrement, le centre d’attention de la communauté webrtc se deplace en europe, habituellement Londres, ou a la conférence annuelle a Paris.

Il est nettement plus rare pour l’Asie de devenir, meme temporairement, le centre d’intérêt pour le petit monde de WebRTC. Malgrès les efforts de la brillante et pionnier Silvia Pfieffer et autres passionnés de webrtc à Sydney, ou la ténacité des japonnais: webrtc hackers de Tokyo, les activités liées a WebRTC en asie restent morcelées, chaque écosystème local ou national se limitant a ses  propres rencontres webrtc.

Nécessitant a la fois une belle collision entre les règles de rotation pour le lieux des meetings IETF, les dates des-dits meetings, et l’intérêt des sponsors industriels de gros événements commerciaux, faire de l’Asie le centre d’intérêt pour webrtc est beau qu’une éclipse (et à peu près aussi rare). Devinez quoi: Nous avons une éclipse ce mois-ci!

Le Japon démarre la fête ( 23 Oct~6 Nov)

Tous mes amis japonnais sont excités, depuis deux semaines non stop, le Japon sera le lieu de passage WebRTC:

  • Le 23 Octobre, pour la 18e édition de leur « HTML5 study meeting », techbuzz japan va se concentrer sur la dernière version de JS (ES6) et webrtc pour les communications en temps réel (en japonais),
  • La dernière semaine d’octobre (26~30), le meeting W3C TPAC, le meeting W3C le plus important de l’année, aura lieu a Sapporo au Japon. Moitié prix pour les nouveaux participants qui se rendront la semaine suivante au meeting IETF! Cela devrait finalement donner naissance aux spécifications les plus attendues de webrtc 1.0 pendant la session dédiée a webrtc les 29 et 30 octobre, avec un peu de chance, cela pourrait inclure simulcast (la plupart en anglais).
  • Le premier jour, il y aura une conférence sur le développement W3C à Sapporo (26 Octobre) (ici).
  • L’original « tokyo webrtc meetup #10 » le 29 Octobre (en japonnais) A ETE REMPLACE par l’événement du 4 Novembre.
  • Après un week-end passé à se remettre de ces discussions intenses, des APIs abstraites et de l’abus de sushis ( ou passé à profiter des folles soirées de l’halloween japonnais),le 94e meeting IETF aura lieu a Yokohama au Japon. Beaucoup de chance, comme d’habitude, pour cette semaine bien remplie, avec la session du groupe rtcweb le 3 et le 5. (la plupart en anglais).
  • Co-localisé avec IETF, mais ouvert à tous, le 4, un événement spécial prendra place en langue anglaise et va présenter les développements locaux. Google va présenter son plan de marche (un bis de la présentation de l’excentrique geek show), Citrix fournira des explications sur leur usage de webRTC, et plus: (en anglais avec des traducteurs japonnais)(ici).

La Chine suit en force (10~11 Nov)

Mes amis chinois sont encore plus excités quand à la première de la Conféfence WebRTC et infos vient à Pékin les 10 et 11 novembre! Plus orienté sur le business que la précédente, une piste spécifique sur la langue chinoise et une sur l’université (exécuté par les habituels Dan et Alan, co-auteurs de « the reference webrtc book, utilisé dans les cours des universités américaines, le couple le plus connu de l’industrie de webrtc).

La conférence prendra place dans le district de HaiDan (shopping de composants électroniques, quelqu’un?), plus spécifiquement à ZongGuancun, qui n’est pas simplement  la Silicon Valleyde Pékin (université numéro 1 et 2 de chine +  centres Oracle, Google, … ), mais est aussi à quelques blocs du principal quartier Coréen et du quartier étudiant de WuDaoKU avec tous les beaux restaurants pas cher, les karaokés et les clubs. Choisissez votre votre solution culinaire à Lushen regardant le croisement, et descendez de deux marches pour arriver au principal club de Pékin (il n’y a qu’en chine qu’un club peut s’appeler « propaganda »). Si les scènes de vies ne sont pas pour vous, vous êtes a quelques dollars en taxi du Summer Palace qui est à voir, pendant la journée.

Le grand finish à Singapour (12~22 Nov)

Mes amis singapouriens sont extatiques, alors que la JSConf.asia revient à Singapour cette année ( les 19 et 20 Novembre), avec une multitude de choses et événements annexes, de grands speakers, tout visible sous la Dev Fest Asia, étirant la fête des développeurs du web du 12 au 22 novembre. A part Monsieur Thomas Gorissen, l’organisateur ( et consultant pour skylink.io) « himself », plusieurs autres discutions webRTC/webaudio apparaissent au travers de l’agenda comme celle de Paul Adenot de Mozilla. Plus sur les intervenants sur le blog de l’événement.

Choisissez votre événement et venez rejoindre la fête, alors que la chaleur de webrtc frappe l’Asie ce mois-ci.

Modifications (patch) quasi automatiques de libwebrtc

I. Introduction

La plupart des logiciels utilisant libwebrtc ont besoin de pouvoir la modifier pour rajouter des fonctionnalités. Certain vendeurs, comme TokBox, vont  changer les paramètres (flags) de compilation de libvpx par example, pour activer le mode d’encodage par couche (SVC) de VP8 dans leurs SDKs mobiles, our avoir une meilleure qualité video. D’autres, tel que Voxeet, vont ajouter des codecs audio supplémentaires, dans leur cas pour emuler de l’audio 3D et reproduire le positionnement des participants dans une conference. Beaucoup, y compris pristine.io, vont vouloir ajouter H.264 pour etre compatibles avec les cartes graphiques de plus d’ordinateurs et de telephones.

Quel que soit le but, chacun aura besoin d’être capable de modifier de façon cohérente le code source d’une bibliothèque qui change souvent, tout en s’assurant que le nombre de patchs et la manière de les appliquer reste gérable dans le temps.

De plus, comme il s’agit d’un code public, il y a des patchs qu’on va proposer et qui profiteront à tous, mais certains utilisateurs pourraient vouloir créer leurs propres patchs privés et les garder pour eux par se différencier. L’architecture de la méthode de gestion des patchs doit permettre cela.

Finalement, juste pour le plaisir, je voulais disposer d’un mécanisme me permettant d’avoir rapidement des patchs à partir du processus de revue et d’integration de nouvelle fonctionnalistes de Google pour profiter de ces nouvelles fonctionnalités de libwebrtc avant même qu’elles n’apparaissent dans Chrome (ou pour tester ces patchs avec mon système).

Dans ce post, nous allons proposer une manière simple, mais efficace, pour aboutir à ce résultat.

II. Mise en œuvre

1. Commandes spécifiques CMake que nous allons utiliser

CMake dispose de la commande add_subdirectory(). Cette commande permet de parcourir l’arborescence du dossier mentionné en argument et à traiter tous les fichiers CMakeLists.txt qu’y s’y trouvent.

  1. add_subdirectory(Patches)

En conditionnant l’appel à cette commande vous pouvez concevoir une belle structure de dossier pour gérer vos patchs, par example selon le type de plateforme :

  1. if( APPLE )
  2.     add_subdirectory( mac )
  3. elseif( WIN32 )
  4.     add_subdirectory( win )
  5. endif()

2. Création des patchs et conditions spécifiques à libwebrtc

Le code source de libwebrtc est un patchwork de bibliothèques indépendantes qui sont récupérées en fonction des entrees dans le fichier DEPS a la racine. Bien que gclient ait une option pour générer des patchs globaux, nous préférons simplement utiliser git. Ainsi, chaque patch que vous générez est applicable à une arborescence git spécifique et vous devez savoir à quel endroit (racine du patch) l’appliquer.

Nous avons créé une macro CMake pour aider à automatiser cela :

  1. set_webrtc_patch_target(
  2.     GIT_APPLY_CMD
  3.     APPLY_DIR
  4.     PATCH
  5.     DEPENDS_ON_TARGET
  6. )

L’option DEPENDS_ON_TARGET nous permet d’être sûr que les patchs sont appliqués après le téléchargement du code.

Le GIT_APPLY_COMMAND apporte de la flexibilité à la commande git que vous utilisez. Certains vont préfèrer l’approche « git diff » / « git apply », alors que d’autres préfèreront « git format-patch » / « git am ». Dans notre cas nous gardons les choses simples :

  1. set(
  2.     GIT_APPLY_CMD
  3.     git apply –ignore-space-change –ignore-whitespace
  4. )

3. Comment exécuter une commande clean/undo

Le problème avec les patchs, c’est qu’ils laissent l’arborescence du code source modifie, ce que git n’aime pas.

Quand on utilise git, une façon de retourner à un état propre est faire un reset : « git reset –hard -q« . Cela ramènera tous les fichiers suivis par git dans un état propre, mais peut laisser des fichiers non suivis par git dans l’arborescence, par exemple si vous ajoutez de nouveaux fichiers ou si vous en supprimez d’autres. « git clean -qfdx »est donc nécessaire si vous voulez vous assurer que l’arborescence du code source est revenue dans l’état que vous souhaitez. Le code ressemble à ça :

  1. set( GIT_RESET_CMD git_reset –hard -q )
  2. set( GIT_CLEAN_CMD git clean -qfdx )

De plus, vous devez savoir à quel endroit de l’arborescence appliquer ces commandes, donc vous devez noter tous les répertoires où des patchs ont été appliqués. Pour chaque patch, nous allons ajouter dans une liste le répertoire auquel il s’applique. Quand le moment sera venu d’annuler l’application du patch, nous utiliserons cette liste :

  1. list(REMOVE_DUPLICATES PATCHED_DIRS) # enlève les doublons
  2. add_custom_target(
  3.     UNPATCH_ALL
  4.     ${CMAKE_COMMAND} -E touch dummy.phony
  5. )
  6. foreach( dir ${PATCHED_DIRS} )
  7.   add_custom_command(
  8.     TARGET                                UNPATCH_ALL           POST_BUILD
  9.     COMMAND                         ${GIT_RESET_CMD}
  10.     COMMAND                         ${GIT_CLEAN_CMD}
  11.    WORKING_DIRECTORY   ${WebRTC_SOURCE_DIR}/${dir}
  12.    COMMENT                          « Unpatching ${dir} »
  13.  )
  14. endforeach()

4. Comment intégrer mes patchs privés/propriétaires ?

Avec la commande add_subdirectory() les choses sont relativement simples. Le code ci-dessous vérifie s’il existe un sous-répertoire « PvtPatches » et s’il y en a un, rentre dedans. Vous pouvez utiliser les sous-arborescences git, ou la méthode de votre choix, pour avoir dans votre copie locale un tel répertoire, avec un CMakeFiles copié (hum… largement inspiré) de celui dans Patches et tout sera pour le mieux.

  1. if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/PvtPatches)
  2.     add_subdirectory(pvtPatches)
  3. endif()

Notez qu’une attention particulière a été portée à la variable qui contient la liste des répertoires sur lesquels appliquer la commande de reset et de nettoyage, pour que vous puissiez la modifier de l’intérieur des sous-répertoires et qu’elle reste valide. L’option « CACHE » vous assure de la cohérence à travers tout le projet quel que soit le répertoire source. L’option « INTERNAL » est ici pour pour s’assurer que cette variable n’apparaîtra pas dans l’interface graphique qui est distribuée avec CMake.

  1. set( PATCHED_DIRS «  » CACHE INTERNAL « Internal variable. »)

Bien entendu, vous êtes susceptible de devoir relancer l’outil de génération de compilation après avoir appliqué les patchs :

  1. python /src/webrtc/build/gyp_webrtc.py

III. Conclusion

Vous avez vu dans ce post comment installer un système de patchs simple pour libwebrtc. Bien sûr, ce ne serait pas complet sans quelques examples. Nous laissons a titre d exercice pour le lecteur, l’intégration de quelques patchs Google :

  • support pour openH264 (patch)
  • support pour les rendus d’images AVFoundation pour Mac (patch)

Cheers.

Alex

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é.

Comment tester la librairie C++ libwebrtc ?

I. Introduction

Compiler une bibliothèque est relativement facile, mais vous ne savez pas s’il y a des bugs tant que vous ne la liez pas avec un exécutable et que vous n’avez pas exécuté cet exécutable (link, run).

Bien que la compilation de libwebrtc (et libjingle) soient devenues relativement faciles grâce à depot_tools, tester libwebrtc est un vrai problème. Comme les commits sont appliqués, testés et potentiellement retires dans le système de Google, il n’est pas possible d’être certain que la dernière révision (HEAD) soit stable a un moment donne.

En utilisant branch_heads il est possible de compiler et de tester les versions correspondant à une version publiée de Chrome. Cependant, tester des versions plus récentes de libwebrtc / libjingle, comme celles utilisées dans Canary, est quelque chose que l’on voudrait pouvoir faire afin d’être prêt lorsque ces versions entreront en production, mais c’est très difficile. Ce post va aborder deux points : le système de tests de Google (pour les curieux) et la manière d’atteindre le même niveau de test que Google avec quelques lignes de code CMake.

II. Je veux ma propre cascade de test!

La page officielle décrit comment voir les tests en cours d’exécution, ou comment en ajouter de nouveaux, mais pas comment faire pour les démarrer ou les lancer localement. Ce n’est pas que vous ne pouvez pas le faire, c’est juste que c’est assez compliqué de lancer les tests localement et que cela demande une machinerie assez importante. Ce que l’on voudrait vraiment être capable de faire, ce serait d’avoir, au minimum, la capacité de tester localement les résultats de la compilation avant de l’installer ou d’en faire un package (plus sur cela dans un prochain post). Dans le meilleur des cas, on souhaiterait disposer de l’équivalent d’une cascade qui pourrait être lancée à la demande. Tout d’abord, pour les pressés, il n’y a quasiment aucun moyen de réaliser cela par soi-même car l’infrastructure est la propriété de Google et nécessite que vous ayez un compte committer soit pour WebRTC soit pour Chrome. Je ne sais pas si c’est possible, je peux seulement dire que je ne connais personne dans l’écosystème (à l’exception d’un employé de chez Intel) qui bénéficie de ce privilège. Pour les curieux ou ceux qui ont le temps, lisez la suite pour savoir ce que vous pouvez faire pour obtenir le plus proche équivalent.

1. Les infos manquantes pour tester libwebrtc

Cette partie traitera de toutes les infos manquantes dans la page webrtc.org (mais diffusées sur les différentes pages wiki de Chromium) pour vraiment mettre en place les tests à la façon de Google.

Le système utilisé par Google pour le développement de Chromium est super. Honnêtement, il a beaucoup de sens et beaucoup d’efforts ont été déployés pour faire face au grand nombre de développeurs travaillant sur Cromium. La dernière « infra » (comme ils l’appellent) doit pouvoir traiter plus de 200 commits par jour sans interruption, et il semble qu’elle fasse du bon travail. Ceci étant dit, c’est assez démesuré pour quelqu’un qui voudrait seulement travailler sur libwebrtc et il est malheureux que même de petites équipes soient obligées soit d’utiliser ce mastodonte soit de faire l’impasse sur les tests.

La partie d’origine des tests de l’infra est constituée de plusieurs éléments : Gtest pour écrire les tests unitaires, les outils habituels pour intégrer Gtest au processus de construction (gyp, DEPS…), buildbot pour … eh bien, les bots de compilation et une nouvelle infrastructure d’essaimage spéciale (ici et ) couplée avec des tests isolés (ici et ). Je ne vais pas aborder ici GTest, gyp ou DEPS, mais traiter de ce qui doit être mis en place pour pouvoir effectuer les tests après une compilation réussie de libwebrtc. Plus précisément, je vais traiter uniquement des tests concernant libwebrtc en tant que bibliothèque indépendante et non ceux portant sur webrtc-in-chromium et autres tests intégrés (*ces tests sont en effet assez différents, tout spécialement ceux concernant le rendu, le partage d’écran, etc., aussi nous devons y aller pas à pas). Finalement, je vais compiler uniquement la bibliothèque de webrtc.org et non la version Gecko/Firefox (ici aussi, c’est assez différent, j’aime le partage d’écran sous Firefox et leur intégration de H.264, mais encore une fois nous devons y aller étape par étape).

Le lien ci-dessous vous indique pas à pas tout ce dont vous aurez besoin pour configurer en local vos propres buildbot (avec esclaves), trybot et autres.  Notez bien que les liens que je mentionne vers les dépôts pourront être obsolètes quand vous lirez ce post (cible en mouvement RAPIDE…) et vous pourriez vouloir lire le code dans la partie « infra » de depot_tools pour connaître la dernière façon de faire les choses (sic), et plus spécifiquement, le contenu du répertoire /build qui peut être directement extrait de https://chromium.googlesource.com/chromium/tools/build.git . Les dossiers qui configurent les cascades de libwebrtc version autonome se trouvent dans master.client.webrtc . Chaque colonne de la cascade correspond à un buildbot (esclave) dont les informations se trouvent aussi dans le même dossier.

pour en savoir plus
  • https://www.chromium.org/developers/testing/chromium-build-infrastructure

2. Test isolé, c’est quoi ca ?

Après la compilation de libwebrtc vous trouverez votre dossier de compilation (/src/out/<CONFIG> par défaut, <CONFIG> étant soit Debug soit Release) assez encombré.  Parmi tous ces fichiers, vous allez voir quelques exécutables dont le nom contient « isolated » ou « isolated.state ». Ces fichiers sont utilisés par le système d’essaimage pour distribuer les tests (ici et ). Dans notre cas, l’information importante est qu’ils contiennent la liste des fichiers dont vous avez besoin comme arguments pour lancer les tests. Ce sont toujours des travaux en cours, mais ils sont d’ores et déjà assez stables pour pouvoir être utilisés. Il y a 22 tests semblables qui sont listés. Maintenant, si vous regardez la cascade, vous verrez qu’en gros il y a deux types de buildbots, les normaux qui lancent toutes les tests unitaires et les « Large » qui lancent les tests de performances et les longs tests tels que [vie|voe]_auto_test, video_capture_tests et audio_device_tests. Ceux-ci prennent assez de temps à s’exécuter et sont beaucoup plus longs que les autres tests, ce qui justifie de les lancer séparément sur des instances plus costaudes. Tous les tests doivent êtres lancés avec l’argument suplémentaire -test-launcher-bot-mode. Pour être exhaustif, j’ajouterais que vie_ et voe_auto_test sont des exécutables interactifs très puissants qui méritent un post rien que pour eux. J’encourage tout le monde à les utiliser et à regarder leur code source. Quelle source d’inspiration ! Pour être lancés comme des tests vous devez leur ajouter l’argument supplémentaire -automated.

3. Alors, comment faire pour lancer ces tests facilement avec CMake ?

CMake fait partie d’une trilogie (eh oui, encore une), la trilogie CMake/CTest/CDash. CMake est l’outil principal de configuration et de coompilation, CTest est votre principal outil de test et de gestion de gestion de tests, et c’est aussi un client pour CDash, l’équivalent de la cascade, c’est-à-dire un tableau de bord interactif qui interagit avec les résultats envoyés par CTest de vos compilations et des tests. L’avantage c’est que tout est intégré.

NOTE : la meilleure façon de faire serait d’analyser les fichiers isolés et d’en extraire la ligne de commande exacte ainsi que les fichiers de sortie. Dans notre cas, pour simplifier et gagner du temps, nous allons ajouter manuellement les 22 tests un par un et nous ignoreront leur sortie si le test a réussi. On peut améliorer cette méthode, mais elle vous fournira néanmoins 99% de ce que vous souhaitez obtenir en 30 minutes de travail…

Pour activer le module des tests dans CMake vous devez seulement ajouter au script CMake les deux lignes de code suivantes :

  1. enable_testing()
  2. include(CTest)

ATTENTION : sans ces deux lignes, le reste du code ne plantera pas ni ne soulèvera aucune erreur, mais aucun test ne sera généré.

Pour chaque test que vous souhaitez ajouter, vous pouvez utiliser la commande add_test() . Ci-dessous, un exemple qui supporte Windows et Mac pour ajouter un test normal, tout en vérifiant que le nom passé en argument correspond à un fichier existant (rappelez vous : cible en mouvement RAPIDE…):

  1. set( my_test_binary_name « common_audio_unittests »)
  2. set( my_test_binary ${my_test_binary_name) )
  3. if( WIN32 )
  4.     set( my_test_binary ${my_test_binary} exe )
  5. endif()
  6. if( EXISTS ${MY_BUILD_DIR}/${my_test_binary )
  7. add_test(
  8.     NAME                                  imp_${my_test_binary_name}
  9.     COMMAND                        ${my_test_binary} –test-launcher-bot-mode
  10.     WORKING_DIRECTORY ${MY_BUILD_DIR}
  11. )
  12. else()
  13.     message( WARNING « ${my_test_binary} – NOT FOUND. »)
  14. endif()

Vous pouvez recommencer pour d’autres exemples. Le code final peut être consulté ici (et la macro add_webrtc_test est définie ici).

Quand la compilation du projet est terminée, vous pouvez vérifier quels tests ont été ajoutés en lançant cette commande dans le répertoire de compilation : « ctest -N« . Cela donnera la liste des tests sans les lancer. Les commandes « ctest » ou « make test » (sous Mac/Linux) sont équivalentes et lancent tous les tests l’un après l’autre. Pour libwebrtc, il est préférable de ne pas utiliser l’option -jX pour lancer les tests en parallèle car ils accèdent au matériel et peuvent interférer les uns avec les autres. Pour être sûr que personne ne commette cette erreur, vous pouvez ajouter une dépendance entre chaque test et son prédécesseur dans la liste. Nous n’avons pas mis ça en place (même si ça ne représente qu’une seule ligne). Si vous souhaitez voir la sortie des tests sur votre écran, vous pouvez ajouter -V à la ligne de commande. Et voilà, vous pouvez tester la bibliothèque de façon aussi complète que les tests de Google le feraient (enfin presque, il manque la détection des fuites mémoire et autres conflits de threads, mais c’est déjà bien d’avoir les tests. L’ajout des contrôles de fuites mémoire et des calculs de couverture seront expliqués dans un prochain post). Maintenant nous pouvons faire la fête comme si on était en 1999, ou pas ?

NOTE : webrtc_perf_test a besoin d’un accès réseau, de même pour voe_auto_test, ainsi si vous testez sous Windows, il vous faudra soit configurer votre pare-feu pour l’autoriser, manuellement, en cliquant N fois sur autoriser quand vous y êtes invités, soit passer ce test si vous voulez lancer la suite de tests.

4. Ok, je peux lancer tous les tests localement mais je n’ai toujours pas ma cascade !

À ce stade vous en avez assez pour construire et tester la sortie sur une seule machine. C’est une bonne base pour préparer un package de la bibliothèque, un sujet que nous aborderons dans un prochain post. Toutefois vous n’avez aucune visibilité sur le résultat de la compilation de la même base de code sur différents systèmes et compilateurs, avec différentes options de compilateurs, et vous n’avez pas non plus de beau visuel en ligne sur votre tableau de bord.

C’est ici que CDash devient très utile. CDash est le composant serveur de la cascade et CTest peut être très facilement configuré pour envoyer les résultats de la compilation et des tests à un serveur CDash. KitWare, l’une des principales compagnies derrière cmake/ctest/cdash et le lieu de travail des ingénieurs les plus impressionnant avec qui j’ai pu travailler dans ma vie, propose un hébergement gratuit pour les projets open source et des options d’hébergements à un prix très raisonnable. Bien sûr, le code est gratuit et open source et vous pouvez installer votre propre serveur CDash en interne si vous préférez. J’ai choisi d’avoir mon propre petit compte et voici le contenu très simple du fichier CTestConfig.cmake que vous devez ABSOLUMENT garder dans la racine du code source.

  1. set(CTEST_PROJECT_NAME « libwebRTC »)                               # c’est relié a un projet que vous devez avoir préalablement créé sur le serveur.
  2. set(CTEST_NIGHTLY_START_TIME « 00:00:00 EST »)             # L’heure que vous voulez, en général une heure où l’ordinateur n’est pas utilisé.
  3. set(CTEST_DROP_METHOD « http »)
  4. set(CTEST_DROP_SITE « my.cdash.org »)                                  # Cela peut changer en fonction de l’installation de votre serveur.
  5. set(CTEST_DROP_LOCATION « /submit.php?project=libwebRTC »)
  6. set(CTEST_DROP_SITE_CDASH TRUE)

Depuis un répertoire vide (recommandé) vous pouvez lancer ctest -D Experimental pour configurer, compiler, lancer les tests (optionnellement vérifier les fuites mémoire, calculer la couverture…) et envoyer les résultats au tableau de bord. Pour cet exemple, voici à quoi ressemble le tableau de bord (Mac). Vous pouvez aussi voir apparaître las compilations Windows et Linux. Puisque CMake est multi-plateformes il fonctionne effectivement tel quel (sauf pour des détails de ligne de commande et des différences d’extensions) sur toutes les plateformes. Ici chaque ligne est esclave, par opposition à la cascade où c’est une colonne qui est esclave, et vous pouvez cliquer sur le résultat de chaque étape (configuration, compilation, test) pour récupérer les résultats tels qu’ils auraient étés affichés sur l’écran, vous donnant approximativement les mêmes fonctionnalités que le buildbot de la cascade. Éventuellement pour un projet plus mûr cela ressemblerait à ça.

CTest a également la capacité de télécharger des fichiers séparément. Dans un prochain post, j’expliquerais comment l’utiliser pour envoyer automatiquement vers un dépôt public une version compilée de la bibliothèque ou une version package de ces bibliothèques si et seulement si tous les tests ont réussi. Ainsi les développeurs peuvent faire confiance en toute bibliothèque ou paquet mis à disposition, sans avoir à les recompiler et les retester (choisissez vous même votre danse de la victoire).

Lectures suggérées

  • https://www.cmake.org/Wiki/CMake/Testing_With_CTest
  • https://www.cmake.org/Wiki/CMake_Scripting_Of_CTest (niveau avancé : comment mettre en place des instances de construction automatiques.)

III. Conclusion

Le système de Google est certainement plus évolutif que celui présenté ici. Il permet ainsi de déclencher automatiquement des compilations afin de valider des commits, ce qui est top. Alors que CMake/CTest/CDash a été amélioré au cours des 5 dernières années pour faire cela, c’est toujours une fonctionnalité difficile à déployer (POUR AUTANT QUE JE SACHE, je ne suis pas forcément à jour avec les dernières évolutions de CMake). Dans le cas d’un très gros projet (plus de 200 commits par jour …) avec seulement un petit nombre de compagnies impliquées, c’est top.

Ce qui est génial avec le système C^3, c’est que n’importe qui peut bénévolement mettre en place un hôte de compilation et contribuer au journal de bord. Vous avez une configuration inhabituelle (version initiale non publique d’un compilateur, vieille version d’un compilateur [BorlandCC 5.6]…) que personne ne peut tester, vous pouvez néanmoins toujours compiler et rapporter les erreurs pour que les développeurs les voient. Rapporter des erreurs est aussi simple que « ctest -D Experimental ». Si vous configurez votre ordinateur pour être un hôte de compilation nocturne, les développeurs peuvent modifier le code et vérifier si le résultat résout le problème sans avoir accès à votre machine (oui, vous pouvez diriger le bot vers une branche git, afin de ne pas polluer la branche de développement principale ou la branche master pendant le processus d’essais et d’erreurs). Donc, pour les projets plus simples, avec beaucoup de petites équipes qui contribuent (comme une communauté open source autour d’une bibliothèque…), c’est top. La barrière d’entrée est basse, tout en proposant un système assez puissant. Ce mécanisme est disponible depuis des années, et il a été utilisé dans de multiples projets, il est donc facile de trouver des gens qui ont la connaissance des outils (qui utilise depot-tools en dehors des membres du projet chromium ?). Il dispose également une grande base de code dont les gens peuvent s’inspirer. Et il prend en charge ninja…

Ici, en quelques heures, nous avons été capable d’apprendre à tester libwebrtc localement à un niveau équivalent à celui de Google, et à faire un rapport à un tableau de bord hébergé pouvant être partagé. Dans les posts suivants, nous verrons comment ajouter une analyse des fuites mémoire, un calcul de couverture de code (compiler c’est un bon départ, tester c’est mieux, mais quel pourcentage du code testons-nous exactement ?), comment créer des paquets qui permettront d’installer libwebrtc sur des ordinateurs, et comment importer automatiquement une version installée dans des projets utilisant CMake pour configurer leur compilation.

Automatiser la construction de libwebrtc avec CMake.

I. Introduction

Libwebrtc est la base de nombreux produits. C’est, bien sûr, la base de l’implémentation de l’API JavaScript du même nom dans Chrome, Firefox et Opera, mais c’est aussi la base de beaucoup de SDKs et autres produits sur mobiles. Conserver une version de libwebrtc à jour, et testée sur un code de base stable, est, comme chacun le sait, difficile si vous n’êtes pas un employé de chez Google. Ce post est le premier d’une série qui explique pas à pas comment mettre en place un système capable de compiler, tester et générer un installteur de libwebrtc automatiquement sur de nombreuses plateformes. Il fait suite à un précédent post qui expliquait comment fonctionne le système de compilation de Google (depot tools), et va plus se concentrer sur la partie automatisation grâce à CMake.

II. Il existe déjà (quelques) très bonnes ressources

Il n’existe pas de « meilleure solution » pour compiler des bibliothèques. Du moment qu’elles sont compilées, testées et intégrées automatiquement, le boulot est fait. Pour le mobile spécifiquement, les scripts développés par Pristine (voir ci-dessous) font un bon boulot. J’avoue avoir un avis biaisé vis-à-vis de CMake puisque c’est le moteur de production multi-plateformes avec lequel j’ai travaillé pendant la plus grande partie de la dernière décennie, mais il y a de très bonnes raisons qui expliquent pourquoi j’ai continué à utiliser CMake pendant si longtemps. Ainsi, ne pas avoir à gérer les différences de compilateurs est un vrai bonheur. De même, ne pas avoir à se préoccuper des différences de systèmes d’exploitation est tout autant une source de joie. Ajoutez à cela être capable d’ajouter un test à la volée avec une simple commande qui à son tour permettra l’envoi du résultat du test vers le tableau de bord, ce qui est une immense joie. Mais ce n’est pas tout, sachez que Valgrind est supporté par défaut, ce qui est ÉNORME. Enfin, même la génération d’un installeur est facilitée (et oui, tout ce que je viens de lister est multi-plateformes).

Avec cette série de posts, vous serez capable en quelques jours seulement d’implémenter un système très performant assurant à la fois la compilation, les tests et la production d’un installeur pour libwebrtc, alors que ça pourrait facilement vous prendre beaucoup plus de temps (d’après mon expérience).

Bien sûr, si vous disposez déjà d’une infrastructure de tests et d’une solution d’intégration continue, elles ne seront probablement pas très compatibles avec CMake. Mais il est souvent plus efficace de séparer la compilation de libwebrtc de la solution que vous construisez autour de libwebrtc, qu’il s’agisse d’un plugin WebRTC, d’un wrapper Apache Cordova (voir ci-dessous) ou d’un SDK mobile.

Pour approfondir:

III. Comment utiliser CMake au mieux

CMake est un gestionnaire de configuration multi-plateformes multi-compilateurs, parfois appelé système de méta-construction. Sa fonctionnalité principale est de trouver pour vous, sur l’ordinateur hôte, les bibliothèques et les programmes dont vous avez besoin pour votre compilation, et de préparer la génération les cibles (fichiers exécutables, bibliothèques, tests…), quel que soit votre système d’exploitation et votre compilateur.

Au strict minimum, vous pouvez utiliser CMake comme n’importe quel autre langage de script et essayer d’encapsuler le système de génération de libwebrtc dans des appels système. La commande « execute_process » sert à celà. Cette façon de procéder a le désavantage de tout faire au moment de la configuration, et ce de façon linéaire. À chaque fois que vous ferez appel à ce type de script, toutes les commandes seront relancées. Il est préférable de définir les cibles et les dépendances au moment de la configuration (c’est-à-dire la seule fois où vous lancerez directement cmake) et ensuite d’utiliser le compilateur natif pour s’occuper du reste du travail.

Un usage intégral de cmake consisterait à l’utiliser pour remplacer entièrement le système de génération de libwebrtc et redéfinir toutes les bibliothèques, les fichiers exécutables, les fichiers sources correspondants, les options de compilation, etc. Bien que cela soit faisable pour un seul fichier exécutable, ou une bibliothèque, réaliser cette opération pour tout libwebrtc voudrait dire devoir migrer tous les fichiers gyp[i] et s’assurer qu’on les garde synchrones à chaque mise à jour de libwebrtc. N’importe qui, saint d’esprit, qui s’est penché sur la complexité que représentent les 6000 lignes du fichier src/build/common.gypi, n’a aucune envie de s’attaquer à ce genre de tâche.

Dans ce post, nous allons utiliser l’approche: dite de « super build » qui consiste à laisser cmake piloter le système de compilation de Google, importer et lancer les tests, ajouter un support de couverture de code, générer les installeurs et ainsi de suite. Ainsi, nous utiliserons le système de compilation de Google tel quel pour les actions de base, et nous réserverons l’ussge de CMake pour les tâches où il est le meilleur.

IV. C’est parti !

1. Un nouveau module CMake pour détecter depot tools.

CMake dispose d’une collection de modules lui permettant de détecter et d’utiliser vos bibliothèques habituelles plus facilement. Ce mécanisme est multi-plateformes. La plupart de ces modules consistent en du code CMake placé dans un fichier appelé FindXXX.cmake. Vous pouvez appeler ce module en invoquant « find_package( XXX ) ». S’il s’agit d’un paquet obligatoire, vous pouvez demander à find_package de se terminer immédiatement en erreur en ajoutant l’argument REQUIRED, Par exemple, CMake est livré avec un FindGit.cmake pré-installé que nous pouvons utiliser dans notre code en écrivant simplement ceci:

  1. find_package(Git REQUIRED)

Actuellement, depot tools nest pas reconnu par CMake. Toutefois, il existe un mécanisme permettant aux projets CMake d’augmenter les capacités de CMake. Vous pouvez écrire vos propres modules FindXXXXX.cmake et permettre à CMake de les trouver en définissant dans votre code la variable CMAKE_MODULE_PATH . Faites bien attention d’étendre et non pas d’écraser cette variable, dans le cas où votre code serait appelé depuis un autre code CMake (style super génération). Dans notre cas, nous mettons les scripts dans un répertoire « CMake » juste sous le répertoire racine du projet CMake.

  1. set( CMAKE_MODULE_PATH
  2. ${CMAKE_MODULE_PATH} # pour intégration en super construction
  3. ${CMAKE_CURRENT_SOURCE_DIR}/Cmake
  4. )

Le code complet est disponible ici.

Il nous reste encore à écrire le code de FindDepotTools.cmake. CMake fournit toutes les primitives pour cela. Dans notre cas, il suffit seulement de trouver la commande gclient. Tout le reste est pris en charge par CMake pour nous, y compris les différences de système d’exploitation et de chemins.

  1. find_program(DEPOTTOOLS_GCLIENT_EXECUTABLE
  2. NAMES gclient gclient.bat   # indices à propos du nom de l’exécutable. gclient.bat est la version Windows
  3. )
  4. #  En-dessous de cette ligne on trouve le code standard de CMake pour que tous les paquets gèrent les options QUIET, REQUIRED…
  5. include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardARGS.cmake)
  6. find_package_handle_standard_args(DepotTools
  7. REQUIRED_VARS DEPOTTOOLS_GCLIENT_EXECUTABLE
  8. FAIL_MESSAGE »could not find the gclient executable »
  9. )

Maintenant, le cœur du script principal est relativement facile à écrire.

  1. project(webrtc)
  2. set(CMAKE_MODULE_PATH
  3. ${CMAKE_MODULE_PATH}  # pour une intégration dans une super génération.
  4. ${CMAKE_CURRENT_SOURCE_DIR}/Cmake
  5. )
  6. find_package(depottools REQUIRED)
  7. find_package(Git                REQUIRED)

Le code complet est disponible ici.

2. Implémenter « gclient config » comme une commande et une cible personnalisées de CMake.

Maintenant nous voulons lancer la ligne de commande « gclient config » depuis CMake. Cette ligne de commande créera un fichier .gclient qui ne devait pas déjà exister. Si le fichier existe, la commande ne devrait rien faire. De plus, je veux que le système de construction essaye à chaque fois qu’il est lancé. Je veux que ça fonctionne quel que soit le système d’exploitation.

Commençons par définir ce que la commande devrait être d’une manière multi-plateformes.

  1. set( gclient_config
  2. $(DEPOTTOOLS_GCLIENT_EXECUTABLE} config  # gclient a déjà été trouvé automatiquement
  3. –name src
  4. http://chromium.googlesource.com/external/webrtc.git
  5. )
  6. if(WIN32)
  7.     set(gclient_config cmd /c ${gclient_config})  # syntaxe pour le prompt de Windows
  8. endif()

Les premières contraintes surviennent avec le add_custom_command() de CMake. Il permet de créer une commande qui générera un fichier en sortie mais cette commande ne sera pas déclenchée si le fichier existe déjà.

  1. add_custom_command(
  2. OUTPUT ${CMAKE_SOURCE_DIR}/.gclient
  3. COMMAND ${glient_config}
  4. )

Toutefois, rien dans le script ne vous dit quand lancer cette commande personnalisée. C’est là que add_custom_target() entre en scène. Il crée une cible (éventuellement vide) pour le système de génération choisi sur laquelle les commandes pourront s’attacher. Cela permet aussi de définir les dépendances avec d’autres cibles pour définir l’odre de construction/exécution. Dans le cas de la configuration de gclient, il n’y a pas d’étape précédente donc pas de dépendance. En faisant dépendre la cible du fichier généré par la commande vous les liez automatiquement. Le paramètre ALL inclue toujours cette cible dans la génération.

  1. add_custom_target(
  2.      webrtc_configuration ALL
  3.      DEPENDS ${CMAKE_SOURCE_DIR}/.gclient
  4. )

3. Implémenter « gclient sync » et ajouter une dépendance.

Implémenter « gclient sync » est plus ou moins la même chose : définir la commande, ajouter une commande personnalisée, puis ajouter une cible personnalisée. Cependant, cette fois, nous voulons que cette cible s’exécute uniquement APRÈS « gclient config ». Nous devons donc ajouter une dépendance. Le code est auto-explicatif. Notez que nous forçons la commande sync à NE PAS lancer les hooks (option -n).

  1. set(gclient_sync ${DEPOTTOOLS_GCLIENT_EXECUTABLE} sync -n -D -r 88a4298)
  2. if(win32)
  3.    set(gclient_sync cmd /c ${gclient_sync})
  4. endif()
  5. add_custom_command(
  6.    OUTPUT ${CMAKE_SOURCE_DIR}/src/all.gyp
  7.    COMMAND ${gclient_sync}
  8. )
  9. add_custom_target(
  10.    webrtc_synchronization ALL
  11.    DEPENDS ${CMAKE_SOURCE_DIR}/src/all.gyp
  12. )
  13. add_dependencies( webrtc_synchronization webrtc_configuration )

4. Implémenter « gclient runhooks »

Gclient runhooks va produire des fichiers de compilation, donc nous devons être sûr que les paramètres les plus évidents sont définis au préalable. Ninja gère les modes Release et Debug au moment de la compilation, nous n’avons donc pas besoin de nous en soucier pour le moment. Le passage d’une architecture 32 bits à une architecture 64 bits (ou arm pour les mobiles) est géré par des variables d’environnement. CMake a une fonction proxy pour y accéder:

  1. if(DEFINED ENV{GYP_DEFINES})
  2.    message( WARNING « GYP_DEFINES is already set to ENV{GYP_DEFINES} »
  3. else()
  4. if(APPLE)
  5.     set(ENV{GYP_DEFINES} « target_arch=x64 »)
  6. else()
  7.    set(ENV{GYP_DEFINES} « target_arch=ia32 »)
  8. endif()
  9. endif()

Maintenant le reste du code est sensiblement le même qu’avant:

  1. set(gclient_runhooks ${DEPOTTOOLS_GCLIENT_EXECUTABLE}runhooks)
  2. if(WIN32)
  3.  set(gclient_runhooks cmd / c ${gclient_runhooks})
  4. endif()
  5. add_custom_command(
  6.  OUTPUT ${CMAKE_SOURCE_DIR}/src/out  # c’est arbitraire
  7.  COMMAND ${gclient_runhooks}
  8. )
  9. add_custom_target(
  10.   webrtc_runhooks ALL
  11.  DEPENDS ${CMAKE_SOURCE_DIR}/src/out
  12. )
  13. add_dependencies(webrtc_runhooks webrtc_synchronization)

L’intégralité du code pour sync et unhook se trouve ici.

5. Préparer la compilation avec la cible Ninja.

Comme mentionné précédemment, on doit traiter ici les modes Debug / Release. Nous suivons la syntaxe CMake qui, par chance, correspond à la syntaxe Ninja.

  1. if( NOT CMAKE_BUILD_TYPE)       # permet de le mettre dans un « superscript » et de le traiter ici
  2. set(CMAKE_BUILD_TYPE Debug)  # Debug par défaut
  3. endif()

Nous pouvons donc lancer l’habituel.

  1.  set(webrtc_build ninja -v -C ${CMAKE_SOURCE_DIR}/src/out/ ${CMAKE_BUILD_TYPE}
  2.  add_custom_command(
  3.     OUTPUT ${CMAKE_SOURCE_DIR}/src/out/${CMAKE_BUILD_TYPE}/ libwebrtc.a  # c’est arbitraire
  4.     COMMAND ${webrtc_build}
  5. )
  6. add_custom_target(
  7.     webrtc_build ALL
  8.     DEPENDS ${CMAKE_SOURCE_DIR}/src/out/${CMAKE_BUILD_TYPE} /libwebrtc.a
  9. )
  10. add_dependencies(webrtc_build webrtc_runhooks)

6. Enfin nous arrivons à la compilation !

Vous pouvez maintenant lancer cmake une seule fois et ensuite lancer la compilation avec votre compilateur d’origine. Ce code a été testé sur Mac (en utilisant « make ») et Windows (ouvrez webrtc.sln dans MS Visual Studio, et construisez TOUTES les cibles, ou appuyez sur F7).