Lorsqu’on effectue un build pour Yocto Project, l’outil bitbake
parcourt des fichiers de configuration que nous avons pu examiner dans l’article précédent. Pendant ce parcours, un nombre important de variables sont remplies.
Il est facile de retrouver dans la documentation de Yocto Project la signification d’une variable, mais l’opération inverse n’est pas toujours facile : trouver quelle variable remplir pour répondre à un problème donné.
C’est la question à laquelle j’ai essayé de répondre dans cette série d’articles, en commençant par les variables globales, dont le contenu est disponible durant tout le build. Le prochain article traitera des variables définies dans les contextes de recette.
Sommaire
J’ai limité ma liste aux variables les plus courantes. J’ai pris comme référence celles que je me souviens avoir configuré à plusieurs reprises durant les derniers mois.
J’ai classé arbitrairement les variables en fonction des usages suivants :
- Performances pendant le build
- Erreurs et incompatibilités de recettes
- Spécificités du build
- Toolchain et SDK
- Support matériel
- Image binaire et partitionnement
- Distro, choix et fonctionnalités
- Image et fonctionnalités d’image
- Caractéristiques des layers
La plupart des variables globales de Yocto peuvent être renseignées indifféremment dans plusieurs fichiers. J’ai indiqué entre parenthèses les fichiers dans lesquels leurs configurations me semblaient avoir le plus de sens. Quand je mentionne « site.conf
ou local.conf
» la variable peut éventuellement être définie dans les deux fichiers, l’un ayant précédence sur l’autre par le jeu des opérateurs =
et ?=
.
Petit rappel de l’article précédent concernant les fichiers ${BUILDDIR}/conf/site.conf
et ${BUILDDIR}/conf/local.conf
que nous rencontrerons dans la description de nombreuses variables :
site.conf
n’existe pas par défaut, c’est à nous de le créer. Il est lu en premier et sert à configurer des éléments concernant la machine sur laquelle on fait le build. Il est propre au développeur et à son poste de travail.local.conf
fournit les informations principales sur le build à réaliser. Contrairement àsite.conf
, ce fichier est habituellement partagé entre les développeurs qui souhaitent reproduire le build sur leurs différentes machines.
–
1 – Performances pendant le build
Limitation de la consommation de ressources
Durant la production d’un build, bitbake
est assez gourmand en ressources. Si l’ordinateur utilisé pour cette production est utilisé simultanément pour d’autres tâches (développement, visioconférence, navigation web, lecture de vidéos, etc.) il peut être utile de limiter la charge CPU par exemple de bitbake
.
BB_NUMBER_THREADS
(site.conf
oulocal.conf
) : nombre de jobs simultanés lancés parbitbake
pendant le build. Par défautbitbake
lance simultanément autant de jobs —do_fetch()
,do_unpack()
,do_configure()
,do_compile()
,do_install()
,do_package()
, etc — qu’il y a de cœurs de CPU disponibles. Diminuer un peu cette valeur pour garder quelques cœurs en réserve peut être souhaitable pour conserver une certaine fluidité du système.
PARALLEL_MAKE
(site.conf
oulocal.conf
) : lors des étapesdo_compile()
,bitbake
appelle la commandemake
avec l’option-j <n>
pour lui indiquer de paralléliser la compilation, n étant égal au nombre de cœurs de CPU. Ceci signifie qu’on risque de se retrouver avec n jobs de compilation (si on n’a pas modifiéBB_NUMBER_THREADS
), chacun lançant n tâches. Soit n² compilations simultanées. Outre le ralentissement du système, le risque est alors le manque de mémoire et l’échec du build. Ne pas hésiter à limiterPARALLEL_MAKE
si on a beaucoup de cœurs de CPU et une quantité de RAM pas très élevée.
BB_NUMBER_PARSE_THREADS
(site.conf
oulocal.conf
) : avant de commencer les compilations,bitbake
passe du temps à parcourir et charger en mémoire tous les fichiers de configuration que nous avons vus dans l’article précédent, toutes les recettes, tous les fichiers.bbappend
, etc. Cette étape est également assez gourmande en ressources, et il peut être intéressant de réduire un peu le nombre de threads actifs (donc la charge CPU et les accès disques simultanés).
Les tâches lancées par bitbake
étant en concurrence avec les autres tâches du système, on peut aussi jouer sur leurs priorités :
BB_TASK_NICE_LEVEL
etBB_TASK_IONICE_LEVEL
(site.conf
oulocal.conf
) : Les valeurs de nice et d’ionice correspondent à des niveaux de priorités inversés respectivement pour l’accès au CPU et pour les accès au système de fichier. Plus la valeur est basse, plus la priorité est élevée. Les valeurs de nice évoluent entre0
(par défaut) et+19
. Pour ionice l’intervalle est de0
(défaut) à7
; je n’ai toutefois jamais remarqué d’effet sensible pour ce dernier paramètre.
Lorsqu’on souhaite limiter l’impact du build sur le système hôte, il est possible de jouer aussi sur d’autres paramètres, de niveaux plus élevés :
BB_PRESSURE_MAX_CPU
,BB_PRESSURE_MAX_IO
etBB_PRESSURE_MAX_MEMORY
(site.conf
oulocal.conf
) : le noyau Linux fournit dans ses fichiers/proc/pressure/cpu
,/proc/pressure/io
et/proc/pressure/memory
une appréciation de la charge moyenne qu’il a subi durant les 10 dernières secondes, la dernière minute et les 5 dernières minutes. On peut indiquer dans ces variables, les seuils au-delà desquelsbitbake
cesse temporairement de lancer de nouvelles tâches. Les valeurs sont dans l’intervalle 0 – 1.000.000 mais il n’est pas simple d’estimer leurs niveaux de charge effective. À titre d’exemple voici les trois valeurs pendant un build Yocto :
[~]$ cat /proc/pressure/cpu
some avg10=80.54 avg60=70.09 avg300=70.38 total=677633725
full avg10=0.00 avg60=0.00 avg300=0.00 total=0
[~]$ cat /proc/pressure/io
some avg10=0.00 avg60=0.00 avg300=0.28 total=31380922
full avg10=0.00 avg60=0.00 avg300=0.12 total=24911970
[~]$ cat /proc/pressure/memory
some avg10=0.00 avg60=0.00 avg300=0.00 total=251014
full avg10=0.00 avg60=0.00 avg300=0.00 total=215441
Pour en savoir plus, voir l’article « Pressure Stall Information » dans la documentation du kernel.
Accélération du build
À l’inverse de la problématique précédente, on peut vouloir accélérer autant que possible le build pour attendre moins longtemps la disponibilité de l’image produite. Pour cela, un moyen très efficace est de partager entre les différents builds que l’on peut réaliser sur notre système le maximum de résultats intermédiaires. Nous pouvons jouer facilement sur l’emplacement de deux répertoires :
DL_DIR
(site.conf
oulocal.conf
) : cette variable contient le chemin où les fichiers sources des packages sont stockés après téléchargement – étapedo_fetch()
– et avant décompression – étapedo_unpack()
. Les noms des fichiers incluant bien les numéros de version voire les niveaux de révision, il est tout à fait possible de partager ce répertoire entre différents builds pour accélérer sensiblement le téléchargement des packages sources.SSTATE_DIR
(site.conf
oulocal.conf
) : le répertoire shared state cache contient des fichiers intermédiaires de la compilation (par exemple fichiers objets ou exécutables pas encore installés). Le partage est également possible entre différents builds, ce qui permet d’éviter de répéter plusieurs fois les mêmes opérations.
À titre d’exemple, pour mes formations « Linux embarqué avec Yocto Project » et « Yocto Project avancé« , je réalise un build complet la veille de la session (ce qui dure plusieurs heures), je sauvegarde les répertoires dowloads/
et sstate-cache/
et j’efface toute le reste. Puis le jour de la formation je les copie sur les répertoires de travail des participants, ce qui fait qu’après configuration correcte (en jouant sur DL_DIR
et SSTATE_CACHE
) notre premier build dure 5 à 10 minutes au lieu de plusieurs heures.
Une autre solution pour accélérer le build est de partager ces répertoires entre plusieurs machines du même sous-réseau.
PREMIRRORS
etMIRRORS
(site.conf
oulocal.conf
) : contiennent des chemins de recherche supplémentaires pour les packages sources. Dans l’ordrebitbake
consulte :- le chemin mentionné dans
DL_DIR
, - les emplacements dans
PREMIRRORS
, - les URL indiquées dans
SRC_URI
, - les emplacements indiqués dans
MIRRORS
.
- le chemin mentionné dans
SSTATE_MIRRORS
(site.conf
etlocal.conf
) joue pour le shared state cache le même rôle queMIRRORS
. Cette mise en œuvre est un petit peu plus compliquée car différentes machines peuvent utiliser différentes versions de Yocto Project, et différentes versions du compilateur ou de la LibC.BB_NO_NETWORK
(site.conf
etlocal.conf
) interdit l’usage du réseau pour télécharger les sources. Cette approche est un peu drastique, on lui préfère souvent l’option suivante :BB_ALLOWED_NETWORKS
(site.conf
etlocal.conf
) contient la liste des réseaux autorisés. C’est un moyen efficace de forcer l’utilisation d’un miroir par exemple.
Une dernière approche – beaucoup plus limitée dans ses effets – est de réduire la quantité de compilations nécessaires :
ASSUME_PROVIDED
(site.conf
etlocal.conf
) contient une liste de packages qu’il n’est pas nécessaire de recompiler et qu’on peut considérer comme déjà présents sur la machine hôte. Cela représente surtout des outils du SDK et influe donc sur le temps de la première compilation.
–
2 – Erreurs et incompatibilités de recettes
Déclenchement des erreurs
BB_DANGLINGAPPENDS_WARNONLY
(local.conf
) est une variable que je mets souvent à « 1 » durant mes builds. Elle indique que si un fichier.bbappend
est trouvé lors du parsing initial des recettes, mais qu’il ne s’applique sur aucun fichier.bb
présent,bitbake
doit simplement afficher un avertissement et non déclencher une erreur de compilation. C’est une situation courante, du moins pendant la phase de mise au point où l’on hérite de fichiers.bbappend
d’un projet précédent, qui ne s’appliquent pas sur les recettes des layers actuellement présents.ALLOW_EMPTY:<recipe-name> (local.conf
ou<recipe-name>.bb
) en mettant cette variable à « 1 » on demande àbitbake
de créer un package vide même si la recette ne produit pas de fichiers. C’est un moyen d’éviter des erreurs si une recette (hors de notre contrôle) a une dépendance runtime vers<recipe-name>
.BB_DISKMON_DIRS
etBB_DISKMON_WARNINTERVAL
(site.conf
oulocal.conf
) : cette variable contient une liste de comportements à adopter quand la place disponible sur un disque de stockage diminue. Un comportement est une suite de trois ou quatre éléments séparés par des virgules : le type d’action à effectuer (par ordre croissant de criticité :WARN
,STOPTASKS
ouHALT
), le répertoire concerné par le monitoring (notamment${TMPDIR}
qui est la base de l’arborescence des fichiers de sortie debitbake
), la place libre minimale et éventuellement le nombre minimum d’i-nodes disponibles suffixés par les multiplicateursK
,M
ouG
.
Filtrage des recettes
BBMASK
(local.conf
) décrit une liste de recettes dontbitbake
ne doit pas tenir compte. C’est comme si l’on supprimait les fichiers.bb
et.bbappend
correspondant (alors qu’ils sont bien présents dans un layer qu’on a téléchargé).BAD_RECOMMENDATIONS
(local.conf
) : liste de recettes à ne pas installer sur la cible si elles sont seulement mentionnées dans la listeRRECOMMENDS
d’une autre recette. Si une recette est explicitement indiquée dansIMAGE_INSTALL
ou dans uneRDEPENDS
, elle sera installée normalement même si elle est indiquée dans cette variable.SKIP_RECIPE
(local.conf
ou${DISTRO}.conf
) : table de recettes à ne pas compiler accompagnées des raisons justifiant ce choix. Le format estSKIP_RECIPE[<recipe-name>]="<reason>"
.INCOMPATIBLE_LICENSE
(local.conf
) : liste de noms de licences incompatibles avec le build que nous souhaitons réaliser. Il s’agit souvent d’exclure les packages sous licence GPLv3 et dérivées quand on prépare un système doté de fonctionnalités de type secure boot où l’utilisateur ne peut pas remplacer les packages par des versions modifiées, même s’il a bien accès aux sources. Les licences concernées sont généralement :GPL-3.0*
,LGPL-3.0*
etAGPL-3.0*
.INCOMPATIBLE_LICENSE_EXCEPTIONS
(local.conf
) : liste de couples package:licence à installer même si la licence est dansINCOMPATIBLE_LICENSE
. Surtout utilisé pendant la phase de mise au point avec des outils de développement ou de débogage (nano:GPL-3.0-only
etgdbserver:GPL-3.0-only
par exemple)LICENSE_FLAGS_ACCEPTED
(local.conf
) : liste de licences spécifiques (généralement propriétaires) qu’il faut accepter explicitement pour pouvoir compiler les recettes du projet.
–
3- Spécificités du build
Les variables rentrant dans cette catégorie sont un peu disparates. Il s’agit de paramétrer le comportement du build.
BUILDNAME
(local.conf
) le contenu de cette variable est intégré dans les noms des fichiers produits en fin de compilation. Par défaut c’est le time stamp (horodatage) du début du build.PACKAGE_CLASSES
(local.conf
) : contientpackage_rpm
,package_deb
oupackage_ipk
suivant le format désiré pour stocker les paquets binaires avant leur installation sur l’image finale.BBLAYERS
(bblayers.conf
) la liste des emplacements des layers à parcourir pour rechercher les recettes disponibles. Cette variable est stockée normalement dansconf/bblayers.conf
(le premier fichier parcouru parbitbake
). On la manipule avec la commandebitbake-layers
.- OE_TERMINAL (
site.conf
oulocal.conf
) : cette variable indique quel type de terminalbitbake
doit invoquer lorsqu’on effectue des opérations commemenuconfig
oudevshell
. Il est parfois nécessaire de modifier la valeur quand on est connecté à distance (par SSH) à la machine de build pour indiquerscreen
par exemple. EXTERNALSRC:pn-<recipe-name>
(avecINHERIT += "externalsrc"
danslocal.conf
) ouEXTERNALSRC
(avecinherit externalsrc
dans<recipe-name>.bb
) : permet de préciser le chemin local des sources à utiliser pour compiler le package sans les télécharger. Surtout utilisé par l’intermédiaire de la commandedevtool modify <package>
pour préparer un patch sur le package.
–
4 – Toolchain et SDK
SDKMACHINE
(local.conf
) : cette variable contient le type de machine pour laquelle le SDK (que l’on extrait avec l’option-c populate_sdk
debitbake
) est compilé. Par défautSDKMACHINE
(machine sur laquelle on utilisera le SDK) est égale àBUILD_ARCH
(machine sur laquelle on compile le SDK). La valeur la plus courante estx86_64
. SiSDKMACHINE
etBUILD_ARCH
sont différentes on parle d’une situation de « cross canadian toolchain » .SDK_VENDOR
(${SDKMACHINE}.conf
oulocal.conf
) : les outils de compilation du SDK seront nommés avec le schéma${TARGET_ARCH}-${SDK_VENDOR}-${TARGET_OS}-<toolname>
, par exemplearm-poky-linux-gnueabi-gcc
. Par défaut la valeur estpoky
.TARGET_ARCH
etTUNE_ARCH
(${MACHINE}.conf
) l’architecture de la cible (arm
,x86_64
,riscv
, etc.)TARGET_OS
(${SDKMACHINE}.conf
oulocal.conf
) : contient le nom de l’OS de la cible :linux
,linux-gnueabi
,linux-musl
,linux-musleabi
.
–
5 – Support matériel
MACHINE
(local.conf
) : cette variable contient le nom de la plateforme matérielle supportant le système. Une fois le fichierlocal.conf
lu,bitbake
recherche un fichier${MACHINE}.conf
en parcourant – par ordre de priorité croissante – les sous-répertoiresconf/machine/
des layers indiqués dans${BBLAYERS}
.MACHINEOVERRIDES
(local.conf
ou${MACHINE}.conf
) : liste d’overrides correspondant à la machine sélectionnée. Par défaut il s’agit simplement du contenu de${MACHINE}
toutefois il est possible de l’étendre pour s’assurer qu’un override est bien présent dans la liste${COMPATIBLE_MACHINE}
d’une recette (généralement celle du kernel).MACHINE_FEATURES
(local.conf
ou${MACHINE}.conf
) : liste des fonctionnalités hardware supportées par la cible. Cette liste est normalement renseignée dans la description de la cible et amendée (en supprimant des fonctionnalités) danslocal.conf
. La liste des fonctionnalités supportées par Yocto Project est décrite ici : https://docs.yoctoproject.org/dev/singleindex.html#ref-features-machine.PREFERRED_PROVIDER_virtual/kernel
,PREFERRED_PROVIDER_virtual/bootloader
,PREFERRED_PROVIDER_virtual/egl
, etc. (${MACHINE}.conf
oulocal.conf
) : le choix de la recette à utiliser pour compiler, le noyau Linux, le bootloader, la bibliothèque graphique, etc.PREFERRED_VERSION_<package>
(${MACHINE}.conf
oulocal.conf
) : le numéro de version choisi pour la recette<package>
indiquée dans unPREFERRED_PROVIDER_virtual/
ci-dessus.SERIAL_CONSOLES
(${MACHINE}.conf
oulocal.conf
) : liste des consoles séries sur lesquelles démarrer une terminalgetty
.KERNEL_MODULE_AUTOLOAD
(${MACHINE}.conf
oulocal.conf
) : liste de modules noyau à charger automatiquement au boot.
D’autres options de configuration du support matériel sont présentes dans les recettes du kernel et du bootloader que nous verrons dans le prochain article.
–
6 – Image binaire et partitionnement
Le terme « image » fait ici référence au fichier-image binaire obtenu à la fin de build, et que l’on copie sur le support de stockage de la cible.
WKS_FILE
ouWKS_FILES
(${MACHINE}.conf
oulocal.conf
) : nom du fichier de description du partitionnement de l’image finale. Ce fichier est recherché dans les sous-répertoireswic/
des différents layers. La variableWKS_FILES
contient une liste de fichiers.wks
, seul le premier trouvé en parcourant les layers par ordre croissant de priorité est pris en considération.IMAGE_NAME
(local.conf
) : nom du fichier d’image binaire. Par défaut il s’agit d’une séquence «${IMAGE_BASENAME}${IMAGE_MACHINE_SUFFIX}${IMAGE_VERSION_SUFFIX}
» mais on peut être amené à modifier ce nom, surtout lorsque l’image est ensuite copiée automatiquement (via des scripts) sur la cible de test.IMAGE_FSTYPES
(${MACHINE}.conf
oulocal.conf
) contient la liste des formats de fichiers de sortie attendus (généralementtar.xz
etwic
). La liste complète des formats disponibles se trouve ici : https://docs.yoctoproject.org/dev/singleindex.html#term-IMAGE_TYPES.IMAGE_BOOT_FILES
(${MACHINE}.conf
oulocal.conf
) : liste des fichiers à installer sur la partition de boot. Les fichiers sont recherchés dans le répertoire${DEPLOY_DIR_IMAGE}
. En général ce sont les fichiers du bootloader et éventuellement le kernel et le device tree.IMAGE_ROOTFS_EXTRA_SPACE
(${MACHINE}.conf
oulocal.conf
) : espace mémoire supplémentaire à ajouter dans l’image binaire une fois copié le rootfs. L’unité utilisé est le kilo-octet.
–
7 – Distro, choix et fonctionnalités
Une distro est un ensemble de paramètres de configuration qui sélectionnent des packages et les configurent pour répondre à certains besoins.
DISTRO
(local.conf
) : contient le nom de la distro utilisé pour le build. Ce nom doit correspondre à un fichier${DISTRO}.conf
se trouvant dans un sous-répertoireconf/distro/
d’un layer. Par défautDISTRO
vaut «poky
» et le fichier de description estpoky/meta-poky/conf/distro/poky.conf
.DISTRO
(${DISTRO}.conf
) : dans le fichier de configuration, la variableDISTRO
contient le nom cours de la distribution, par exemple «poky
«DISTRO_NAME
(${DISTRO}.conf
) : nom complet de la distribution, par exemple «Poky (Yocto Project Reference Distro)
»DISTRO_VERSION
(${DISTRO}.conf
) : numéro de version de la distribution.DISTRO_FEATURES
(${DISTRO}.conf
oulocal.conf
) : liste de fonctionnalités de haut-niveau proposées par la distribution. Une recette peut adopter certains comportement en fonction de la présence ou de l’absence d’une fonctionnalité dans cette liste.INIT_MANAGER
(${DISTRO}.conf
oulocal.conf
) : choix du mécanisme d’initialisation après le boot du kernel. Par défautsysvinit
, peut être remplacé parsystemd
oumdev-busybox
,REQUIRED_DISTRO_FEATURES
,ANY_OF_DISTRO_FEATURES
,CONFLICT_DISTRO_FEATURES
: ces variables sont utilisées dans le contexte d’une recette. Nous les verrons dans le prochain article.DISTROOVERRIDES
(${DISTRO}.conf
) : liste (dont le séparateur est le deux-points «:
» ) des overrides définis par la distribution. Le contenu de cette variable est ajouté à la variable globaleOVERRIDES
. En fin de parsing des recettes, une variable «foo
» sera remplacée par le contenu de la variable «foo:bar
» si la chaîne «bar
» est dans la liste desOVERRIDES
.TCLIBC
(${DISTRO}.conf
oulocal.conf
) : choix de la bibliothèque C (utilisée par tous les processus de l’espace utilisateur pour invoquer des appels-système), par défaut c’estglibc
, mais on peut préférermusl
,newlib
oubaremetal
.
–
8 – Image et fonctionnalités d’image
La notion d’image correspond ici à la sélection des packages et au paramétrage que l’on retrouvera dans l’arborescence du root filesystem, et donc dans le fichier d’image binaire tel que nous l’avons vu au paragraphe 6.
IMAGE_BASENAME
: définie automatiquement à partir du nom de la recette d’image qui doit se trouver dans un sous-répertoirerecipes-*/images/
d’un layer.IMAGE_INSTALL
(${IMAGE_BASENAME}.bb
,local.conf
) : liste des packages et des groupes de packages à installer sur la cible. Cette variable doit être configurée en utilisant «:append
» et non pas"+=
» pour des raisons de définition de contenu par défaut.IMAGE_FEATURES
(${IMAGE_BASENAME}.bb
) : fonctionnalités de haut-niveau permettant d’installer et configurer de multiples packages. On trouve une liste des fonctionnalités disponibles ici : https://docs.yoctoproject.org/dev/singleindex.html#ref-features-image.EXTRA_IMAGE_FEATURES
(local.conf
) : liste de fonctionnalités complémentaires à ajouter àIMAGE_FEATURES
.EXTRA_USERS_PARAMS
(dans${IMAGE_BASENAME}.bb
avec la clauseinherit extrausers
, ou danslocal.conf
avec la ligneINHERIT += "extrausers"
) : liste (dont le séparateur est le point-virgule) de commandes pour ajouter (useraddd
,groupadd
), supprimer (userdel
,groupdel
), ou modifier (usermod
,groupmod
) des utilisateurs ou des groupes d’utilisateurs.
–
9 – Caractéristiques des layers
Les variables mentionnées ici sont renseignées dans les fichiers conf/layer.conf
de chaque layer. Les layers sont listés dans la variable BBLAYERS
de conf/bblayers.conf
.
BBFILES
(layer.conf
) : liste de motifs du shell listant tous les fichiers de recette (*.bb)
et d’extension (*.bbappend
) à charger. Chaque fichierlayer.conf
parcouru étend cette liste globale.BBPATH
(layer.conf
) : emplacements des différents layers listés sous forme de path (le séparateur est un deux-points) alors queBBLAYERS
contient une liste dont le séparateur est une espace.BBFILE_COLLECTIONS
(layer.conf
) : liste des layers représentés par des identifiants uniques. L’identifiant d’un layer est fourni danslayer.conf
, c’est souvent le nom qui suit le préfixemeta-
du répertoire l’abritant.BBFILE_PRIORITY_layer-id
(layer.conf
) : la priorité du layer dont l’identifiant estlayer-id
. Les layers sont parcourus par ordre de priorité croissante. Il est conseillé d’utiliser une priorité inférieure à 99, car c’est celle utilisé pour le layerworkspace
dedevtool
, employé pendant la mise au point du système.LAYERSERIES_COMPAT_layer-id
(layer.conf
) : liste des versions (code name) de Poky avec laquelle le layer est compatible.
–
Conclusion
Nous avons vu ici une petite partie des variables globales utilisées par bitbake
. Ce sont celles qu’on utilise le plus couramment.
Dans le prochain article, nous examinerons les variables spécifiques aux contextes des recettes.
–
Pour en savoir plus et mettre en pratique, n’hésitez à participer à une session de formation « Linux embarqué avec Yocto Project » ou « Yocto Project avancé » que j’anime chez Logilin.
–