{"id":5897,"date":"2022-01-13T09:00:00","date_gmt":"2022-01-13T08:00:00","guid":{"rendered":"https:\/\/www.blaess.fr\/christophe\/?p=5897"},"modified":"2022-01-24T17:45:11","modified_gmt":"2022-01-24T16:45:11","slug":"yocto-cooker-1-3","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2022\/01\/13\/yocto-cooker-1-3\/","title":{"rendered":"Yocto Cooker (1\/3)"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"alignright size-full\"><a href=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2022\/01\/cooker-logo-small-size.png\"><img loading=\"lazy\" decoding=\"async\" width=\"128\" height=\"160\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2022\/01\/cooker-logo-small-size.png\" alt=\"\" class=\"wp-image-5898\"\/><\/a><\/figure><\/div>\n\n\n\n<p>Cette petite s\u00e9rie de trois articles pr\u00e9sente un outil (<strong>Yocto Cooker<\/strong>) qui permet d&rsquo;organiser tous les fichiers n\u00e9cessaires \u00e0 la compilation d&rsquo;un syst\u00e8me Linux embarqu\u00e9 avec Yocto Project. Cet outil permet \u00e9galement de lancer automatiquement un ou plusieurs <em>builds<\/em> (compilation d&rsquo;images compl\u00e8tes pr\u00eates \u00e0 installer).<\/p>\n\n\n\n<p>Attention: cet article ne pr\u00e9sente pas les concepts propres \u00e0 Yocto Project, on pr\u00e9-suppose une certaine familiarit\u00e9 avec cet environnement. Pour trouver une introduction \u00e0 Yocto, et un tutorial complet sur son utilisation, on se reportera \u00e0 l&rsquo;article <a href=\"https:\/\/www.blaess.fr\/christophe\/yocto-lab\/\">Linux embarqu\u00e9 avec Yocto Project<\/a>.<\/p>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\">Probl\u00e9matique<\/h2>\n\n\n\n<p>L&rsquo;outil Yocto Project repr\u00e9sente aujourd&rsquo;hui l&rsquo;une des deux principales solutions pour mettre au point et produire un syst\u00e8me embarqu\u00e9 bas\u00e9 sur Linux.<\/p>\n\n\n\n<p>\u00c0 mon sens, le meilleur avantage de Yocto sur son principal concurrent (<em>Buildroot<\/em>) est la possibilit\u00e9 de g\u00e9rer la configuration du syst\u00e8me \u00e0 diff\u00e9rents niveaux (param\u00e9trage des packages, contenu de l&rsquo;image, d\u00e9finition de la plateforme cible, etc.) et de partager ces \u00e9l\u00e9ments de configuration entre diff\u00e9rents <em>builds<\/em>. On peut ainsi g\u00e9rer ais\u00e9ment une gamme compl\u00e8te de produits que ce soit au niveau mat\u00e9riel (lorsque la m\u00eame application m\u00e9tier doit tourner sur diff\u00e9rente plateformes, avec diff\u00e9rentes options en terme de p\u00e9riph\u00e9riques) ou au niveau applicatif (lorsqu&rsquo;on propose plusieurs versions du m\u00eame code m\u00e9tier&nbsp;: \u00ab\u00a0<em>lite<\/em>\u00a0\u00bb , normal, \u00ab\u00a0<em>full-featured<\/em>\u00a0\u00bb etc.).<\/p>\n\n\n\n<p>La contrepartie de cette versatilit\u00e9 est la complexit\u00e9 de la configuration (qui repr\u00e9sente donc le point faible de Yocto Project par rapport \u00e0 Buildroot).<\/p>\n\n\n\n<p>On peut se retrouver rapidement avec plusieurs dizaines de <em>layers<\/em>, une douzaine de configurations pour les <em>machines<\/em>, les <em>images<\/em>, voire les <em>distros<\/em>. Pour chaque <em>build<\/em> on peut avoir \u00e0 g\u00e9rer des fichiers <code>local.conf<\/code> et <code>bblayers.conf<\/code> sp\u00e9cifiques. Bref, la maintenance d&rsquo;un environnement destin\u00e9 \u00e0 produire des images pour plusieurs projets, plusieurs plateformes ou plusieurs versions logicielles peut vite devenir un enfer.<\/p>\n\n\n\n<p>Confront\u00e9s \u00e0 ce probl\u00e8me pour le projet d&rsquo;un client, nous avons d\u00e9cid\u00e9, avec mon coll\u00e8gue Patrick Boettcher de d\u00e9velopper un outil permettant d&rsquo;organiser le plus simplement possible les diff\u00e9rents <em>builds<\/em>. Notre objectif \u00e9tait de centraliser dans un seul fichier tous les \u00e9l\u00e9ments n\u00e9cessaires pour r\u00e9aliser un voire plusieurs <em>builds<\/em> : notamment les noms et origines des <em>layers<\/em> \u00e0 utiliser et les param\u00e8tres sp\u00e9cifiques \u00e0 ajouter dans le fichier <code>local.conf<\/code>.<\/p>\n\n\n\n<p>L&rsquo;environnement Yocto Project utilise un vocabulaire issu de la cuisine (<em>recipes<\/em>, <code>bitbake<\/code>, etc.). Nous avons souhait\u00e9 nous inscrire dans cette coutume, et comme notre logiciel est destin\u00e9 \u00e0 encadrer le travail du cuisinier <code>bitbake<\/code>, nous avons d\u00e9cid\u00e9 de l&rsquo;appeler <code>chef<\/code>. Malheureusement, \u00e0 peine celui-ci publi\u00e9 nous avons re\u00e7u des menaces de proc\u00e8s car un logiciel commercial de gestion de configuration utilise d\u00e9j\u00e0 ce nom.<\/p>\n\n\n\n<p>Nous avons choisi de le re-baptiser (un peu dans l&rsquo;urgence) <strong>Yocto Cooker<\/strong>. Ce nom, choisi rapidement, n&rsquo;est pas non plus parfait, car il existe au sein m\u00eame de <code>bitbake<\/code> un fichier <code>cooker.py<\/code>. Attention donc \u00e0 ne pas faire de confusion, notre projet est compl\u00e8tement ext\u00e9rieur \u00e0 <code>bitbake<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Principe<\/h2>\n\n\n\n<p><a href=\"https:\/\/github.com\/cpb-\/yocto-cooker\" target=\"_blank\" rel=\"noreferrer noopener\">Yocto Cooker<\/a> &#8211; ou plus simplement <code>cooker<\/code> &#8211; est un script Python qui, apr\u00e8s analyse d&rsquo;un fichier de configuration au format JSON, pr\u00e9pare les r\u00e9pertoires de travail n\u00e9cessaires, t\u00e9l\u00e9charge les <em>layers<\/em> choisis et d\u00e9marre <code>bitbake<\/code> pour r\u00e9aliser le <em>build<\/em> d\u00e9sir\u00e9.<\/p>\n\n\n\n<p>Comme <code>cooker<\/code> est l\u00e0 pour organiser le travail du cuisinier <code>bitbake<\/code>, son fichier de configuration en JSON s&rsquo;appelle un <strong>menu<\/strong>.<\/p>\n\n\n\n<p>Partant d&rsquo;un simple fichier menu, <code>cooker<\/code> va pr\u00e9parer les r\u00e9pertoires et les fichiers selon l&rsquo;arborescence suivante.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>+- layers\/ +- poky\/\n|          +- meta-openembedded\/\n|          +- meta-custom-layer\/\n|          +- ...\n|\n+- downloads\/ ...\n|\n+- sstate-cache\/ ...\n|\n+- builds\/ +- build-custom-1\/ conf\/ +- local.conf\n           |                        +- bblayers.conf\n           |                        +- templateconf.cfg\n           |\n           +- build-custom-2\/ conf\/ +- local.conf\n           |                        +- bblayers.conf\n           |                        +- templateconf.cfg\n           |\n           +- ...<\/code><\/pre>\n\n\n\n<p>Tous les <em>layers<\/em> t\u00e9l\u00e9charg\u00e9s sont proprement rang\u00e9s dans le sous-r\u00e9pertoire <code>layers\/<\/code>. Durant la phase de mise au point, il est possible de travailler dans certains d&rsquo;entre-eux, nous en reparlerons. Notons que parfois les <em>layers<\/em> se trouvent en r\u00e9alit\u00e9 \u00e0 un degr\u00e9 d&rsquo;imbrication plus loin. C&rsquo;est le cas par exemple de la dizaine de layers se trouvant dans l&rsquo;arborescence <code>meta-openembedded<\/code>.<\/p>\n\n\n\n<p>Le r\u00e9pertoire <code>downloads\/<\/code> est utilis\u00e9 par <code>bitbake<\/code> comme point de stockage lorsqu&rsquo;il t\u00e9l\u00e9charge les sources des packages. Ceci afin d&rsquo;\u00e9viter un t\u00e9l\u00e9chargement inutile si le package est d\u00e9j\u00e0 pr\u00e9sent. \u00c0 cet emplacement de l&rsquo;arborescence, ce r\u00e9pertoire est mutualis\u00e9 entre tous les <em>builds<\/em>.<\/p>\n\n\n\n<p>De m\u00eame le r\u00e9pertoire <code>sstate-cache\/<\/code> contient des \u00e9l\u00e9ments produits lors d&rsquo;un <em>build<\/em>, qui sont susceptibles d&rsquo;\u00eatre r\u00e9utilis\u00e9s lors des <em>builds<\/em> suivants. Donc <code>cooker<\/code> le place \u00e0 c\u00f4t\u00e9 de <code>download<\/code> pour le partager entre tous les <em>builds<\/em>.<\/p>\n\n\n\n<p>Le r\u00e9pertoire <code>builds\/<\/code> enfin contient un sous-dossier pour chaque <em>build<\/em> d\u00e9sir\u00e9. Dans chaque sous-dossier, <code>cooker<\/code> pr\u00e9pare les fichiers <code>conf\/local.conf<\/code> et <code>conf\/bblayers.conf<\/code> en fonction du contenu du menu fourni. Le fichier <code>conf\/templateconf.cfg<\/code> est toujours identique.<\/p>\n\n\n\n<p>Apr\u00e8s avoir rempli cette arborescence, <code>cooker<\/code> va ex\u00e9cuter <code>bitbake<\/code> successivement dans chaque r\u00e9pertoire de <em>build<\/em> (sauf s\u00e9lection explicite sur la ligne de commande) en ayant correctement initialis\u00e9 ses variables d&rsquo;environnement.<\/p>\n\n\n\n<p>Bien s\u00fbr <code>cooker<\/code> propose diff\u00e9rentes options de fonctionnement et permet de lancer directement une sous-t\u00e2che pr\u00e9cise. Nous verrons cela dans les prochains articles.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installation<\/h2>\n\n\n\n<p>Yocto Cooker \u00e9tant un script Python, son installation se fait facilement \u00e0 l&rsquo;aide de <code>pip<\/code>. Vous pouvez t\u00e9l\u00e9charger les sources, les examiner, et les installer avec<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>git clone <a href=\"https:\/\/github.com\/cpb-\/yocto-cooker\">https:\/\/github.com\/cpb-\/yocto-cooker<\/a><\/strong>\n\n$ <strong>cd yocto-cooker<\/strong>\n\n$ <strong>sudo pip3 install .<\/strong>\n<\/code><\/pre>\n\n\n\n<p>Il est aussi possible de faire l&rsquo;installation directe avec&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>sudo python3 -m pip install --upgrade git+https:\/\/github.com\/cpb-\/yocto-cooker.git<\/strong><\/code><\/pre>\n\n\n\n<p>Notez que vous pouvez \u00e9galement utiliser l&rsquo;option <code>-e<\/code> de <code>pip3 install<\/code> pour que le script soit \u00e9ditable, dans le cas o\u00f9 vous souhaiteriez contribuer \u00e0 notre projet (et je vous y encourage fortement&nbsp;!).<\/p>\n\n\n\n<p>Une fois le script <code>cooker<\/code> install\u00e9, vous pouvez le lancer avec l&rsquo;option <code>--help<\/code> pour voir ses sous-commandes disponibles ou l&rsquo;option <code>--version<\/code> pour vous assurer de la version install\u00e9e&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>cooker --version<\/strong>\n# 1.1.0\n\n$ <strong>cooker --help<\/strong>\nusage: Cooker &#91;-h] &#91;--debug] &#91;--version] &#91;-v] &#91;-n] {cook,init,update,generate,show,build,shell,clean} ...\n\npositional arguments:\n  {cook,init,update,generate,show,build,shell,clean}\n               subcommands of Cooker\n  cook         prepare the directories and cook the menu\n  init         initialize the project-dir\n  update       update source layers\n  generate     generate build-configuration\n  show         show builds and targets information\n  build        build one or more configurations\n  shell        run an interactive shell ($SHELL) for the given build\n  clean        clean a previously build recipe\n\noptional arguments:\n -h, --help    show this help message and exit\n --debug       activate debug printing\n --version     cooker version\n -v, --verbose activate verbose printing (of called subcommands)\n -n, --dry-run print what would have been done (without doing anything)\n<\/code><\/pre>\n\n\n\n<p>Pour pouvoir r\u00e9aliser un <em>build<\/em> complet \u00e0 partir d&rsquo;une distribution Ubuntu-2020.04 fra\u00eechement install\u00e9e, il faut ajouter les packages suivants <code>chrpath<\/code>, <code>cpio<\/code>, <code>diffstat<\/code>, <code>gawk<\/code>, <code>git<\/code>, <code>locales<\/code>, <code>locales-all<\/code>, <code>python3-pip<\/code>, <code>wget<\/code>.  Si besoin on d\u00e9finira la variable d&rsquo;environnement <code>LC_ALL<\/code> ainsi avant de lancer la compilation&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>export LC_ALL=en_US.UTF-8<\/strong>\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Menu<\/h2>\n\n\n\n<p>Pour le premier test de <code>cooker<\/code>, nous allons lui demander de compiler une image de base pour une seule cible. Le menu sera donc tr\u00e8s simple. En voici une version que je vais d\u00e9tailler plus bas.<\/p>\n\n\n\n<p>On peut le t\u00e9l\u00e9charger ici&nbsp;: <a href=\"https:\/\/www.blaess.fr\/christophe\/files\/yocto-cooker\/menu-001.json\">menu-001.json<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>cat menu-001.json<\/strong>\n{\n  \"sources\" : &#91;\n    { \"url\": \"git:\/\/git.yoctoproject.org\/poky\", \"branch\": \"dunfell\", \"rev\": \"yocto-3.1.13\" }\n  ],\n\n  \"layers\" : &#91;\n    \"poky\/meta\",\n    \"poky\/meta-poky\",\n    \"poky\/meta-yocto-bsp\"\n  ],\n\n  \"builds\" : {\n\n    \"qemuarm\": {\n\n      \"target\" : \"core-image-base\",\n      \"local.conf\": &#91;\n        \"MACHINE = 'qemuarm' \",\n        \"IMAGE_FEATURES += 'empty-root-password' \"\n      ]\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>Comme indiqu\u00e9 plus haut le fichier est au format JSON. Il d\u00e9crit un objet menu<br>poss\u00e9dant trois attributs (<code>\"sources\"<\/code>, <code>\"layers\"<\/code> et <code>\"builds\"<\/code>). C&rsquo;est le<br>cas le plus fr\u00e9quent, m\u00eame si nous verrons dans le prochain article deux<br>autres attributs possibles.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>sources<\/code><\/h3>\n\n\n\n<p>Le premier attribut (<code>\"sources\"<\/code>) est un ensemble d&rsquo;objets indiquant comment t\u00e9l\u00e9charger les layers utilis\u00e9s pendant le <em>build<\/em>. Pour ce premier exemple nous n&rsquo;utiliserons que Poky, mais on ajoute souvent le d\u00e9p\u00f4t \u00ab\u00a0<code>meta-openembedded<\/code>\u00a0\u00bb ainsi que les layers permettant de supporter la cible mat\u00e9rielle et des layers d\u00e9velopp\u00e9s sp\u00e9cifiquement.<\/p>\n\n\n\n<p>Un objet <code>source<\/code> peut \u00eatre d\u00e9fini gr\u00e2ce quelques attributs&nbsp;:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>le champ <code>\"url\"<\/code> indique la provenance du d\u00e9p\u00f4t Git du layer. Pour le moment <code>cooker<\/code> ne sait g\u00e9rer que des d\u00e9p\u00f4ts Git. Si le besoin s&rsquo;en fait sentir nous pourrons ajouter d&rsquo;autres types de t\u00e9l\u00e9chargements ult\u00e9rieurement.<\/li><li>le champ <code>\"branch\"<\/code> (facultatif) permet de restreindre le clonage \u00e0 une branche pr\u00e9cise. Ceci permet de passer facilement d&rsquo;une version <em>debug<\/em> \u00e0 une version <em>release<\/em> par exemple.<\/li><li>le champ <code>\"rev\"<\/code> (facultatif) contient un identifiant de <em>commit<\/em> Git ou un <em>tag<\/em>.<\/li><\/ul>\n\n\n\n<p>L&rsquo;objectif du projet Yocto Cooker est de g\u00e9rer facilement des <em>builds<\/em> du m\u00eame projet sur plusieurs plateformes et de garantir une p\u00e9rennit\u00e9 de l&rsquo;environnement de compilation. Ainsi, il est fortement conseill\u00e9 de pr\u00e9ciser syst\u00e9matiquement le champ <code>\"rev\"<\/code> pour garantir la reproductibilit\u00e9 du <em>build<\/em>.<\/p>\n\n\n\n<p>Un quatri\u00e8me attribut de l&rsquo;objet <code>source<\/code> est <code>\"method\"<\/code>, absent ci-dessus. Il est surtout utile durant la phase de mise au point d&rsquo;un layer, lorsqu&rsquo;on le modifie directement sur place avant de relancer le <em>build<\/em>. Dans ce cas aucun t\u00e9l\u00e9chargement ne doit plus avoir lieu, et l&rsquo;on indique <code>\"method\": \"ignore\"<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>layers<\/code><\/h3>\n\n\n\n<p>Le second attribut (<code>\"layers\"<\/code>) du menu est l&rsquo;ensemble des <em>layers<\/em> \u00e0 prendre en consid\u00e9ration pour <strong>tous<\/strong> les <em>builds<\/em>. On voit que <code>poky\/<\/code>, t\u00e9l\u00e9charg\u00e9 pr\u00e9c\u00e9demment, est un r\u00e9pertoire comprenant trois <em>layers<\/em> que nous utiliserons syst\u00e9matiquement (en fait Poky comprend deux autres layers <code>meta-selftest<\/code> et <code>meta-skeleton<\/code> qui ne nous sont pas utiles).<\/p>\n\n\n\n<p>Nous verrons dans le prochain article qu&rsquo;il est possible pour chaque <em>build<\/em> de s\u00e9lectionner des <em>layers<\/em> suppl\u00e9mentaires. Si deux <em>builds<\/em> par exemple sont destin\u00e9s \u00e0 deux machines diff\u00e9rents, chacun pourra inclure le <em>layer<\/em> contenant le support pour son type de processeur.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>builds<\/code><\/h3>\n\n\n\n<p>Le troisi\u00e8me attributs du menu (<code>\"builds\"<\/code>) contient un ensemble de paires cl\u00e9\/valeur qui d\u00e9crivent les <em>builds<\/em> \u00e0 produire. Dans notre cas un seul <em>build<\/em> est indiqu\u00e9&nbsp;: <code>\"qemuarm\"<\/code>. C&rsquo;est un nom tout \u00e0 fait arbitraire. Je l&rsquo;ai choisi bien entendu pour repr\u00e9senter la cible, mais ce pourrait \u00eatre n&rsquo;importe quel nom. Attention, il sera utilis\u00e9 pour cr\u00e9er le r\u00e9pertoire de compilation, \u00e9vitez donc les espaces et les caract\u00e8res invalides dans les noms de fichiers.<\/p>\n\n\n\n<p>Un objet <code>build<\/code> est \u00e0 son tour d\u00e9crit par plusieurs attributs. Les deux indiqu\u00e9s ci-dessus sont les seuls v\u00e9ritablement indispensables.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>target<\/code><\/h4>\n\n\n\n<p>Le premier attribut (<code>\"target\"<\/code>) indique le nom de l&rsquo;image qui doit \u00eatre produite par <code>bitbake<\/code>. C&rsquo;est l&rsquo;argument qui lui sera pass\u00e9 sur sa ligne de commande.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><code>local.conf<\/code><\/h4>\n\n\n\n<p>Le second attribut (<code>\"local.conf\"<\/code>) est l&rsquo;ensemble des cha\u00eenes de caract\u00e8res \u00e0 ajouter dans le fichier <code>conf\/local.conf<\/code> du r\u00e9pertoire de <em>build<\/em>. Il s&rsquo;agit de lignes se pr\u00e9sentant toujours sous la forme suivante.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\" VARIABLE_1 = 'valeur 1' \",\n\" VARIABLE_2 = 'valeur 2' \"<\/code><\/pre>\n\n\n\n<p>L&rsquo;encadrement de la ligne compl\u00e8te par des guillemets permet de respecter la syntaxe JSON, et l&rsquo;encadrement des valeurs par des quotes simples correspond \u00e0 la syntaxe de Yocto Project. Lorsque plusieurs lignes sont pr\u00e9sentes  elles doivent \u00eatre s\u00e9par\u00e9es par des virgules.<\/p>\n\n\n\n<p>Ce menu remplit la variable <code>MACHINE<\/code> avec la cha\u00eene <code>qemuarm<\/code> afin que <code>bitbake<\/code> pr\u00e9pare une image susceptible d&rsquo;\u00eatre ex\u00e9cut\u00e9e par l&rsquo;\u00e9mulateur <strong>Qemu<\/strong>. Cette ligne est indispensable pour r\u00e9aliser un <em>build<\/em> avec Yocto.<\/p>\n\n\n\n<p>On ajoute \u00e9galement la cha\u00eene <code>empty-root-password<\/code> dans la variable <code>IMAGES_FEATURES<\/code> afin que Yocto nous pr\u00e9pare une image sans mot de passe pour <code>root<\/code>. C&rsquo;\u00e9tait le comportement par d\u00e9faut jusqu&rsquo;\u00e0 la mi-2021. D\u00e9sormais la connexion sans mot de passe explicite (configur\u00e9 avec <code>inherit extrausers<\/code>) est impossible sans cette option. Bien entendu elle n&rsquo;est pr\u00e9sente qu&rsquo;\u00e0 titre d&rsquo;exemple pour cet article, on ne l&rsquo;utilise jamais sur un syst\u00e8me r\u00e9el.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lancement<\/h2>\n\n\n\n<p>L&rsquo;ex\u00e9cution de Yocto Cooker est tr\u00e8s simple. Nous lan\u00e7ons la commande&nbsp;: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>cooker  cook  menu-001.json<\/strong><\/code><\/pre>\n\n\n\n<p>Ceci demande \u00e0 <code>cooker<\/code> de pr\u00e9parer (action <code>cook<\/code>) tous les <em>builds<\/em> (un seul dans notre cas) d\u00e9crits dans le fichier menu.<\/p>\n\n\n\n<p>Nous laissons <code>cooker<\/code> et <code>bitbake<\/code> travailler pendant une heure environ (cela d\u00e9pend bien s\u00fbr des performances de la machine de compilation) afin d&rsquo;obtenir une image.<\/p>\n\n\n\n<p>Au bout d&rsquo;un moment, on observe le compte-rendu de la compilation suivant. Les premi\u00e8res lignes, pr\u00e9fix\u00e9es par un caract\u00e8re di\u00e8se <code>#<\/code>, sont dues \u00e0 <code>cooker<\/code>, les suivantes \u00e0 <code>bitbake<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>cooker cook menu-001.json<\/strong>\n# Update layers in project directory\n# Downloading source from  git:\/\/git.yoctoproject.org\/poky\n# Updating source \/home\/cpb\/Lab\/cooker-article\/layers\/poky...\n# Generating dirs for all build-configurations\n# Building build-qemuarm (core-image-base)\n\n&#91;...]\nParsing recipes: 100% |################################################################################| Time: 0:00:16\nParsing of 774 .bb files complete (0 cached, 774 parsed). 1326 targets, 61 skipped, 0 masked, 0 errors.\nNOTE: Resolving any missing task queue dependencies\n\nBuild Configuration:\nBB_VERSION           = \"1.46.0\"\nBUILD_SYS            = \"x86_64-linux\"\nNATIVELSBSTRING      = \"ubuntu-20.04\"\nTARGET_SYS           = \"arm-poky-linux-gnueabi\"\nMACHINE              = \"qemuarm\"\nDISTRO               = \"poky\"\nDISTRO_VERSION       = \"3.1.13\"\nTUNE_FEATURES        = \"arm armv7ve vfp thumb neon callconvention-hard\"\nTARGET_FPU           = \"hard\"\nmeta\nmeta-poky\nmeta-yocto-bsp       = \"HEAD:795339092f87672e4f68e4d3bc4cfd0e252d1831\"\n\nNOTE: Fetching uninative binary shim http:\/\/downloads.yoctoproject.org\/releases\/uninative\/3.4\/x86_64-nativesdk-libc.tar.xz;sha256sum=126f4f7f6f21084ee140dac3eb4c536b963837826b7c38599db0b512c3377ba2 (will check PREMIRRORS first)\nInitialising tasks: 100% |#############################################################################| Time: 0:00:01\nSstate summary: Wanted 1592 Found 0 Missed 1592 Current 0 (0% match, 0% complete)\nNOTE: Executing Tasks\nNOTE: Tasks Summary: Attempted 4090 tasks of which 8 didn't need to be rerun and all succeeded.\n\n$<\/code><\/pre>\n\n\n\n<p>Nous pouvons v\u00e9rifier que <code>bitbake<\/code> nous a bien produit une image. Pour cela il a cr\u00e9\u00e9 un r\u00e9pertoire <code>builds\/build-qemuarm<\/code> puisque le nom du <em>build<\/em> est <code>qemuarm<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>ls builds\/build-qemuarm\/tmp\/deploy\/images\/qemuarm\/<\/strong>\ncore-image-base-qemuarm-20220108105921.qemuboot.conf\ncore-image-base-qemuarm-20220108105921.rootfs.ext4\ncore-image-base-qemuarm-20220108105921.rootfs.manifest\ncore-image-base-qemuarm-20220108105921.rootfs.tar.bz2\ncore-image-base-qemuarm-20220108105921.testdata.json\ncore-image-base-qemuarm.ext4\ncore-image-base-qemuarm.manifest\ncore-image-base-qemuarm.qemuboot.conf\ncore-image-base-qemuarm.tar.bz2\ncore-image-base-qemuarm.testdata.json\nmodules--5.4.158+gitAUTOINC+db8bfc3a10_414c50525a-r0-qemuarm-20220108105921.tgz\nmodules-qemuarm.tgz\nzImage\nzImage--5.4.158+gitAUTOINC+db8bfc3a10_414c50525a-r0-qemuarm-20220108105921.bin\nzImage-qemuarm.bin\n\n$\n<\/code><\/pre>\n\n\n\n<p>L&rsquo;arborescence produite \u00e0 ce stade est la suivante (j&rsquo;ai indiqu\u00e9 surtout les r\u00e9pertoires et fichiers avec lesquels nous sommes susceptibles d&rsquo;interagir).<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">+- layers\/ +- poky\/\n|\n+- downloads\/...\n|\n+- sstate-cache\/...\n|\n+- builds +-build-qemuarm +-conf\/+-local.conf\n                          |      +-bblayers.conf\n                          |\n                          +-tmp\/+-deploy\/ +- images\/\n                          |     |         +- licenses\/\n                          |     |         +- rpm\/\n                          |     |\n                          |     +-work\/ + all-poky-linux\/\n                          |     |       +- armv7veth...\/\n                          |     |       +- qemuarm-poky...\/\n                          |     |       +- x86_64-linux\/\n                          |   [...]\n                        [...]<\/pre>\n\n\n\n<p>Pour tester notre <em>build<\/em>, il faut lancer <code>qemu-system-arm<\/code> en lui passant pas mal de param\u00e8tres. Or ceux-ci sont d\u00e9j\u00e0 pr\u00e9sents dans le fichier d&rsquo;extension <code>.qemuboot.conf<\/code> ci-dessus et sont lus par le script <code>runqemu<\/code> fourni par Poky.<\/p>\n\n\n\n<p>N\u00e9anmoins il n&rsquo;est pas possible de lancer directement <code>runqemu<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>runqemu<\/strong>\nrunqemu: command not found\n\n$<\/code><\/pre>\n\n\n\n<p>Pour cela il faudrait avoir charg\u00e9 les variables d&rsquo;environnement fournies par Poky (c&rsquo;est le r\u00f4le du fameux script <code>poky\/oe-init-build-env<\/code>). C&rsquo;est ce que nous propose <code>cooker<\/code> avec son action <code><strong>shell<\/strong><\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ <strong>cooker shell build-qemuarm<\/strong>\n\n### Shell environment set up for builds. ###\n&#91;...]\n\n&#91;build-qemuarm]$ <strong>pwd<\/strong>\n\/home\/cpb\/Lab\/cooker-article\/builds\/build-qemuarm\n\n&#91;build-qemuarm]$<\/code><\/pre>\n\n\n\n<p>On notera que pour l&rsquo;action <code>shell<\/code> il n&rsquo;est pas n\u00e9cessaire de pr\u00e9ciser le nom du fichier menu, celui-ci est m\u00e9moris\u00e9 dans un fichier <code>.cookerconfig<\/code> dans le r\u00e9pertoire o\u00f9 l&rsquo;on a lanc\u00e9 <code>cooker cook<\/code> . Nous retrouverons ce comportement pour d&rsquo;autres actions de <code>cooker<\/code> qui seront pr\u00e9sent\u00e9es dans le troisi\u00e8me article de cette s\u00e9rie.<\/p>\n\n\n\n<p class=\"has-small-font-size\">Note&nbsp;: au moment de la r\u00e9daction de ces lignes, cette commande peut \u00e9chouer sur les syst\u00e8mes o\u00f9 le fichier <code>\/bin\/sh<\/code> est un lien symbolique vers <code>\/bin\/dash<\/code>. Pour corriger le probl\u00e8me, il suffit de renseigner la variable d&rsquo;environnement <code>SHELL<\/code> avant de lancer <code>cooker<\/code> ainsi&nbsp;: <code>export SHELL=\/bin\/bash<\/code>.<\/p>\n\n\n\n<p>Ici <code>cooker<\/code> nous a initialis\u00e9 un nouveau shell avec les variables d&rsquo;environnement n\u00e9cessaires. Il nous a \u00e9galement   d\u00e9plac\u00e9s dans le r\u00e9pertoire de <em>build<\/em>. Il faudra penser \u00e0 quitter ce shell avant de relancer \u00e9ventuellement <code>cooker<\/code>.<\/p>\n\n\n\n<p>Relan\u00e7ons <code>runqemuarm<\/code> avec deux arguments&nbsp;: le premier pour qu&rsquo;il d\u00e9marre en console texte uniquement, le second pour indiquer l&rsquo;architecture de la cible.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;build-qemuarm]$ <strong>runqemu nographic qemuarm<\/strong>\nrunqemu - INFO - Running MACHINE=qemuarm bitbake -e ...\nrunqemu - INFO - Continuing with the following parameters:\nKERNEL: &#91;\/home\/cpb\/Lab\/cooker-article\/builds\/build-qemuarm\/tmp\/deploy\/images\/qemuarm\/zImage--5.4.158+gitAUTOINC+db8bfc3a10_414c50525a-r0-qemuarm-20220108105921.bin]\nMACHINE: &#91;qemuarm]\nFSTYPE: &#91;ext4]\n  &#91;...]\n&#91;    0.000000] Booting Linux on physical CPU 0x0\n&#91;    0.000000] Linux version 5.4.158-yocto-standard (oe-user@oe-host) (gcc version 9.3.0 (GCC)) #1 SMP PREEMPT Tue Nov 9 16:43:05 UTC 2021\n&#91;    0.000000] CPU: ARMv7 Processor &#91;412fc0f1] revision 1 (ARMv7), cr=30c5387d\n&#91;    0.000000] CPU: div instructions available: patching division code\n&#91;    0.000000] CPU: PIPT \/ VIPT nonaliasing data cache, PIPT instruction cache\n&#91;    0.000000] OF: fdt: Machine model: linux,dummy-virt\n&#91;    0.000000] Memory policy: Data cache writealloc\n&#91;    0.000000] psci: probing for conduit method from DT.\n  &#91;...]\n&#91;    5.747954] udevd&#91;137]: starting version 3.2.9\n&#91;    5.814839] udevd&#91;138]: starting eudev-3.2.9\n&#91;    7.933359] EXT4-fs (vda): re-mounted. Opts: (null)\n&#91;   15.199894] Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n&#91;   16.930967] NFSD: Using \/var\/lib\/nfs\/v4recovery as the NFSv4 state recovery directory\n&#91;   16.944135] NFSD: Using legacy client tracking operations.\n&#91;   16.945009] NFSD: starting 90-second grace period (net f0000039)\n\nPoky (Yocto Project Reference Distro) 3.1.13 qemuarm \/dev\/ttyAMA0\n\nqemuarm login:<\/code><\/pre>\n\n\n\n<p>Notre <em>build<\/em> s&rsquo;est donc bien pass\u00e9, nous pouvons m\u00eame nous connecter (sans mot de passe puisque nous l&rsquo;avons configur\u00e9 ainsi)&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>qemuarm login: <strong>root<\/strong>\nroot@qemuarm:~# <strong>uname -a<\/strong>\nLinux qemuarm 5.4.158-yocto-standard #1 SMP PREEMPT Tue Nov 9 16:43:05 UTC 2021 armv7l GNU\/Linux\n&#91;...]\nroot@qemuarm:~# <strong>halt<\/strong>\n&#91;...]\n\nDeactivating swap...\nUnmounting local filesystems...\n&#91;  274.354864] EXT4-fs (vda): re-mounted. Opts: (null)\n&#91;  275.562475] reboot: Power down\nrunqemu - INFO - Cleaning up\n\n&#91;build-qemuarm]$<\/code><\/pre>\n\n\n\n<p>Attention, \u00e0 ce niveau nous sommes encore dans le shell que <code>cooker<\/code> a lanc\u00e9 pour nous et nous devons le quitter pour revenir \u00e0 l&rsquo;\u00e9tat initial.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;build-qemuarm]$ <strong>exit<\/strong>\n\n$<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Dans l&rsquo;exp\u00e9rience ci-dessus nous avons vu que Yocto Cooker nous facilite la t\u00e2che de compilation d&rsquo;une image, en  regroupant tous les param\u00e8tres du <em>build<\/em> dans un seul fichier, le menu, qui devient le n\u0153ud central de la configuration,  le seul fichier \u00e0 sauvegarder, \u00e0 versionner et \u00e0 conserver pour assurer la reproductibilit\u00e9 de l&rsquo;op\u00e9ration. <\/p>\n\n\n\n<p>Dans l&rsquo;<a href=\"https:\/\/www.blaess.fr\/christophe\/2022\/01\/20\/yocto-cooker-2-3\/\" data-type=\"post\" data-id=\"5948\">article suivant<\/a> nous examinerons des attributs suppl\u00e9mentaires du menu, ainsi que la notion d&rsquo;h\u00e9ritage entre les <em>builds<\/em>. Dans le troisi\u00e8me et dernier article de cette s\u00e9rie nous verrons d&rsquo;autres options et actions propos\u00e9es par <code>cooker<\/code>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Cette petite s&eacute;rie de trois articles pr&eacute;sente un outil (Yocto Cooker) qui permet d&rsquo;organiser tous les fichiers n&eacute;cessaires &agrave; la compilation d&rsquo;un syst&egrave;me Linux embarqu&eacute; avec Yocto Project. Cet outil permet &eacute;galement de lancer automatiquement un ou plusieurs builds (compilation d&rsquo;images compl&egrave;tes pr&ecirc;tes &agrave; installer). Attention: cet article ne pr&eacute;sente pas les concepts propres &agrave; [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,8,21],"tags":[],"class_list":["post-5897","post","type-post","status-publish","format-standard","hentry","category-embarque","category-linux-2","category-yocto-project"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/5897","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/comments?post=5897"}],"version-history":[{"count":31,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/5897\/revisions"}],"predecessor-version":[{"id":5955,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/5897\/revisions\/5955"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=5897"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=5897"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=5897"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}