«« sommaire »»

II.2 – Ajout d'applications dans l'image

Christophe BLAESS - juillet 2024

Dans la séquence précédente, nous avons modifié le fichier «local.conf» que nous trouvons dans le sous-répertoire «conf/» de notre répertoire de build. Les modifications étaient assez simples : ajustement de l’emplacement des dossiers de stockage temporaire, ajout d’utilisateur et configuration de mots de passe, puis modification du nom de machine.

Dans cette séquence nous allons ajouter quelques applications sur notre système. Pour cela, nous allons commencer en modifiant à nouveau ce fichier, puis nous créerons notre propre recette d'image personnalisée.

Utilitaires connus de Poky

Notre première possibilité est d’ajouter des packages dont les recettes sont livrées avec Poky. Regardons, par exemple les fichiers se trouvant dans les sous-répertoires «recipes*/» du layer meta de Poky :

[build-qemu]$ ls  ../../layers/poky/meta*/recipes-*
../../layers/poky/meta/recipes-bsp:
acpid       efibootmgr  formfactor  grub     libacpi  opensbi   pm-utils   u-boot   usbutils
alsa-state  efivar      gnu-efi     keymaps  lrzsz    pciutils  setserial  usbinit  v86d

../../layers/poky/meta/recipes-connectivity:
avahi   connman    iproute2  libnss-mdns  mobile-broadband-provider-info  ofono    ppp         slirp                wpa-supplicant
bind    dhcpcd     iw        libpcap      neard                           openssh  ppp-dialin  socat
bluez5  inetutils  kea       libuv        nfs-utils                       openssl  resolvconf  ssh-pregen-hostkeys

../../layers/poky/meta/recipes-core:
base-files   dbus-wait  gettext          images         libcgroup  ncurses     packagegroups  systemd      util-linux
base-passwd  dropbear   glib-2.0         init-ifupdown  libxcrypt  netbase     psplash        sysvinit     volatile-binds
busybox      ell        glib-networking  initrdscripts  libxml     newlib      readline       ttyrun       zlib
coreutils    expat      glibc            initscripts    meta       os-release  seatd          udev
dbus         fts        ifupdown         kbd            musl       ovmf        sysfsutils     update-rc.d

../../layers/poky/meta/recipes-devtools:
apt               cmake               dosfstools     gdb               libcomps     makedevs    patchelf    rsync              tcltk
autoconf          createrepo-c        dpkg           git               libdnf       meson       perl        ruby               unfs3
autoconf-archive  debugedit           dwarfsrcfiles  gnu-config        libedit      mmc         perl-cross  run-postinsts      unifdef
automake          dejagnu             e2fsprogs      go                libmodulemd  mtd         pkgconf     rust               vala
binutils          desktop-file-utils  elfutils       help2man          librepo      mtools      pkgconfig   squashfs-tools     valgrind
bison             devel-config        erofs-utils    i2c-tools         libtool      nasm        pseudo      strace             xmlto
bootchart2        diffstat            expect         icecc-create-env  llvm         ninja       python      subversion
btrfs-tools       distcc              fdisk          icecc-toolchain   log4cplus    opkg        qemu        swig
ccache            dmidecode           file           intltool          lua          opkg-utils  quilt       syslinux
cdrtools          dnf                 flex           jquery            m4           orc         repo        systemd-bootchart
chrpath           docbook-xml         gcc            json-c            make         patch       rpm         tcf-agent

../../layers/poky/meta/recipes-extended:
acpica             cronie        gperf     libarchive   lsb        msmtp          psmisc        sysklogd              wget
asciidoc           cups          grep      libidn       lsof       net-tools      quota         sysstat               which
at                 cwautomacros  groff     libmnl       ltp        newt           rpcbind       tar                   xdg-utils
baremetal-example  diffutils     gzip      libnsl       lzip       packagegroups  rpcsvc-proto  tcp-wrappers          xinetd
bash               ed            hdparm    libnss-nis   man-db     pam            screen        texinfo               xz
bc                 ethtool       images    libpipeline  man-pages  parted         sed           texinfo-dummy-native  zip
blktool            findutils     iptables  libsolv      mc         pbzip2         shadow        time                  zstd
bzip2              gawk          iputils   libtirpc     mdadm      perl           slang         timezone
cpio               ghostscript   less      lighttpd     mingetty   pigz           stress-ng     unzip
cracklib           go-examples   libaio    logrotate    minicom    procps         sudo          watchdog

../../layers/poky/meta/recipes-gnome:
epiphany    gi-docgen              gsettings-desktop-schemas  hicolor-icon-theme  libdazzle  libnotify  libsecret
gcr         gnome                  gtk+                       json-glib           libgudev   libportal  libxmlb
gdk-pixbuf  gobject-introspection  gtk-doc                    libadwaita          libhandy   librsvg

../../layers/poky/meta/recipes-graphics:
builder          glslang        libepoxy          menu-cache      shaderc               wayland                    xorg-lib
cairo            graphene       libfakekey        mesa            spir                  x11-common                 xorg-proto
cantarell-fonts  harfbuzz       libmatchbox       mini-x-session  startup-notification  xcursor-transparent-theme  xorg-util
drm              igt-gpu-tools  libsdl2           packagegroups   ttf-fonts             xinput-calibrator          xorg-xserver
fontconfig       images         libva             pango           virglrenderer         xorg-app                   xrestop
freetype         jpeg           matchbox-session  piglit          vulkan                xorg-driver                xwayland
glew             kmscube        matchbox-wm       pong-clock      waffle                xorg-font

../../layers/poky/meta/recipes-kernel:
blktrace   dtc         kexec  libtraceevent  linux-firmware      lttng             modutils-initscripts  powertop   wireless-regdb
cryptodev  kern-tools  kmod   linux          linux-libc-headers  make-mod-scripts  perf                  systemtap

../../layers/poky/meta/recipes-multimedia:
alsa    flac       lame    libogg    libpng         libsndfile  libtiff    mpeg2dec  pulseaudio  speex  x264
ffmpeg  gstreamer  liba52  libomxil  libsamplerate  libtheora   libvorbis  mpg123    sbc         webp

../../layers/poky/meta/recipes-rt:
README  images  rt-tests

../../layers/poky/meta/recipes-sato:
images     matchbox-config-gtk  matchbox-panel-2   matchbox-theme-sato  pulseaudio-sato  sato-icon-theme  shutdown-desktop
l3afpad    matchbox-desktop     matchbox-sato      packagegroups        puzzles          sato-screenshot  webkit
libptytty  matchbox-keyboard    matchbox-terminal  pcmanfm              rxvt-unicode     settings-daemon

../../layers/poky/meta/recipes-support:
appstream        curl                   gnutls         libdaemon         libksba        libunistring  nghttp2         shared-mime-info
apr              db                     gpgme          libevdev          libmd          libunwind     npth            sqlite
argp-standalone  debianutils            icu            libevent          libmicrohttpd  liburcu       nss-myhostname  taglib
aspell           diffoscope             iso-codes      libexif           libmpc         libusb        numactl         user-creation
atk              dos2unix               itstool        libffi            libnl          libxslt       p11-kit         utfcpp
attr             enchant                libassuan      libfm             libpcre        libyaml       pinentry        vim
bash-completion  fribidi                libatomic-ops  libgcrypt         libproxy       lz4           popt            vte
bmaptool         gdbm                   libbsd         libgit2           libpsl         lzo           ptest-runner    xxhash
boost            gmp                    libcap         libgpg-error      libseccomp     lzop          re2c
ca-certificates  gnome-desktop-testing  libcap-ng      libical           libsoup        mpfr          rng-tools
consolekit       gnupg                  libcheck       libjitterentropy  libssh2        nettle        serf

La liste n’est pas évidente à lire, mais un comptage rapide avec «find ../../layers/poky/meta -name '*bb'| wc -l» nous indique la présence de plus de 900 recettes livrées dans Poky. La plupart d’entre-elles sont des services ou des utilitaires bas-niveaux assez peu visibles au premier abord. Nous pouvons toutefois ajouter sur notre image un petit outil que j’aime bien : mc le Midnight Commander. Pour cela nous ajoutons simplement la ligne suivante dans local.conf :

IMAGE_INSTALL:append = " mc"

La variable «IMAGE_INSTALL» contient la liste des noms de packages à installer sur le système cible.

Le suffixe «:append» indique que la chaîne fournie en partie droite de l'affectation doit être ajoutée à la fin de la variable concernée. Nous ajoutons donc le nom du package mc précédé d'une espace qui sert de séparateur entre les éléments de la liste de packages.

Nous pourrions également utiliser :

IMAGE_INSTALL:prepend = "mc "

pour ajouter la chaîne en début de variable (et en la faisant suivre de l'espace de séparation).

Plusieurs lignes de ce type peuvent se suivre pour allonger d’autant le contenu de l’image.

Après avoir regénéré «core-image-base» et nous être connectés, nous pouvons lancer la commande «mc» et retrouver l'atmosphère un peu surannée des années 1990 sur Ms-Dos (figure II.2-1). Malgré son aspect désuet aujourd'hui, cet outil peut encore s'avérer très pratique lors de la mise au point d’un système embarqué pour le confort du développement en ligne de commande.

Il existe d’autres outils dont les recettes se trouvent dans Poky que j’aime bien intégrer dans mes images embarquées afin de permettre la mise au point du système ou du code métier : dtc, valgrind, powertop, gdbserver… Nous en reparlerons dans la troisième partie, pour l’instant contentons-nous d’ajouter les lignes suivantes :

IMAGE_INSTALL:append = " mc"
IMAGE_INSTALL:append = " dtc valgrind"
IMAGE_INSTALL:append = " gdbserver powertop"

Comme on le voit, on peut aussi bien enchaîner des lignes d’ajout que regrouper les différents packages désirés dans une seule ligne.

Après recompilation de l’image, je vérifie la présence des outils ajoutés. Je ne m’intéresse pas ici à leurs fonctionnements ou leurs résultats, juste à leurs présences sur ma cible :

Poky (Yocto Project Reference Distro) 5.0.2 mybox /dev/ttyAMA0

mybox login: root
Password: (linux)

WARNING: Poky is a reference Yocto Project distribution that should be used for
testing and development purposes only. It is recommended that you create your
own distribution for production use.


root@mybox:~# dtc --version
Version: DTC v1.7.0+

root@mybox:~# valgrind --version
valgrind-3.22.0

root@mybox:~# gdbserver --version
GNU gdbserver (GDB) 14.2
Copyright (C) 2023 Free Software Foundation, Inc.
gdbserver is free software, covered by the GNU General Public License.
This gdbserver was configured as "arm-poky-linux-gnueabi"

root@mybox:~# powertop --version
PowerTOP version 2.15
root@mybox:~#

Ajout de packages hors Poky

Pendant la mise au point d’un système embarqué, on a souvent besoin d’éditer des fichiers directement sur la cible. Sur une installation «core-image-base», nous disposons bien de l’éditeur «vi», intégré dans le package busybox. Néanmoins tout le monde n’est pas familier des commandes de vi, et l’utilisation d’un outil un peu plus intuitif s’avère généralement plus reposante. Supposons que nous souhaitions installer l'éditeur «nano» par exemple, qui est plus simple d’emploi que vi.

Essayons simplement d’ajouter la ligne :

IMAGE_INSTALL:append = " nano"

dans notre fichier «local.conf». Dès le lancement du build bitbake va se plaindre, nous afficher une série de lignes rouges et terminer en indiquant une erreur :

ERROR: Nothing RPROVIDES 'nano' (but /home/Builds/Lab/Yocto-lab/poky/meta/recipes-core/images/core-image-base.bb RDEPENDS on or otherwise requires it)
NOTE: Runtime target 'nano' is unbuildable, removing...
Missing or unbuildable dependency chain was: ['nano']
ERROR: Required build target 'core-image-base' has no buildable providers.
Missing or unbuildable dependency chain was: ['core-image-base', 'nano']

Summary: There were 2 ERROR messages, returning a non-zero exit code.

Visiblement, bitbake n’a pas trouvé dans les recettes fournies par Poky celle permettant de construire nano.

Il va probablement nous falloir trouver un layer (un ensemble de recettes) à installer sur notre système. Pour cela, l'usage est de se rendre sur le site https://layers.openembedded.org, de cliquer sur l’onglet «recipes», de sélectionner la version de Poky qui nous concerne et de saisir le nom du package désiré dans le moteur de recherche. Nous trouvons alors une page de résultat comme celle de la figure II.2-2.

Clairement la recette qui m’intéresse est la première de la liste. Elle se trouve dans le layer indiqué dans la colonne de droite : «meta-oe». En cliquant sur ce lien je vois qu’il s’agit d’un layer appartenant à un repository nommé «meta-openembedded», et je trouve l’adresse du téléchargement à effectuer.

Rappelons que les layers sont des répertoires contenant des recettes. Les layers ont un nom qui commence par «meta-». À cet égard, «meta-openembedded» est plutôt mal nommé, car il ne s'agit pas d'un dépôt mais d'un ensemble de dépôts. J'aurais trouvé plus logique de l'appeler «openembedded-layers» par exemple.

[build-qemu]$ cd ../../layers/

[layers]$ git clone  git://git.openembedded.org/meta-openembedded -b scarthgap 
Cloning into 'meta-openembedded'...
remote: Enumerating objects: 246096, done.
remote: Counting objects: 100% (673/673), done.
remote: Compressing objects: 100% (227/227), done.
remote: Total 246096 (delta 437), reused 505 (delta 422), pack-reused 245423
Receiving objects: 100% (246096/246096), 60.65 MiB | 16.06 MiB/s, done.
Resolving deltas: 100% (150463/150463), done.


[layers]$ ls meta-openembedded/
contrib      meta-filesystems  meta-initramfs   meta-networking  meta-perl    meta-webserver  README.md
COPYING.MIT  meta-gnome        meta-multimedia  meta-oe          meta-python  meta-xfce

[layers]$ cd ../builds/build-qemu/

[build-qemu]$ 

L’ensemble «meta-openembedded» est assez incontournable dès lors que l’on prépare un système avec Yocto. Il contient plus de deux mille recettes pour de nombreux packages très utiles pour Linux embarqué.

Nous devons ajouter le layer «meta-oe» à la liste de ceux pris en compte dans notre build. C'est le rôle de la sous-commande «add-layer» de la commande «bitbake-layers» fournie par Poky.

[build-qemu]$ bitbake-layers add-layer ../../layers/meta-openembedded/meta-oe/ 
NOTE: Starting bitbake server...

[build-qemu]$ 

Nous pouvons à présent relancer notre compilation, elle se déroule normalement et nano est intégré dans notre image.

[build-qemu]$ bitbake  core-image-base
  [...]

Par exemple, sur la figure II.2-3, nous l'employons pour consulter le fichier /etc/passwd.

Utilisation des fonctionnalités d’image

Nous avons utilisé la compilation avec «core-image-base» un peu aveuglément, sans comprendre véritablement ce que cela signifie. Nous allons examiner son contenu plus en détail. Pour cela nous recherchons le fichier qui décrit «core-image-base» dans les sous-répertoires de Poky. Il s’agit d’une recette avec l’extension «.bb».

[build-qemu]$ find  ../../layers/poky/  -name  core-image-base.bb 
../../layers/poky/meta/recipes-core/images/core-image-base.bb

Lorsque nous demandons à bitbake de produire une image, il recherche un fichier d'extension «.bb» avec le nom de l'image. Ce fichier doit se trouver dans un sous-répertoire «images/» se trouvant dans un répertoire dont le nom commence par «recipes-»

Le fichier trouvé correspond bien à ces critères. Voyons son contenu.

[build-qemu]$ cat  ../../layers/poky/meta/recipes-core/images/core-image-base.bb 
SUMMARY = "A console-only image that fully supports the target device \
 hardware."

IMAGE_FEATURES += "splash"

LICENSE = "MIT"

inherit core-image

Hormis la description et la licence, deux lignes nous intéressent :

Nous voyons que Yocto nous propose ainsi ce mécanisme de features d'image, des fonctionnalités de haut-niveau que l’on peut sélectionner sans se soucier du détail du ou des packages correspondants.

Voici quelques fonctionnalités proposées par la classe «core-image», qui est implémentée dans le fichier ../../layers/poky/meta/classes-recipe/core-image.bbclass.

x11Serveur X-window
x11-baseServeur X-window et environnement minimal (Matchbox)
x11-satoServeur X-window et environnement Sato pour mobile.
westonEnvironnemnt graphique Wayland et compositeur Weston.
tools-debugOutils de débogage (gdb, gdbserver, strace, gcore…)
eclipse-debugOutils de débogage distant avec Eclipse.
tools-profileOutils de profiling (perf, lttng, gprof...)
tools-testappsOutils de tests du matériel.
tools-sdkInstallation des outils de développement natifs (gcc, make...) sur la cible.
nsf-serverServeur NFS
nfs-clientClient NFS
ssh-server-dropbearServeur SSH basé sur Dropbear.
ssh-server-opensshServeur SSH basé sur Openssh
hwcodecsSupport des codecs pour l’accélération matérielle
package-managementSupport des packages sur la cible (installation des outils et base de données).
dev-pkgsInstallation des fichiers headers nécessaire pour le développement des packages présents.
dbg-pkgsTous les packages sont compilés avec les informations de débogage
doc-pkgsInstallation de la documentation associée à tous les packages
bash-completion-pkgsComplétions de la ligne de commande de Bash
read-only-rootfsSystème de fichiers en lecture-seule.
splashÉcran d’accueil pendant le boot
...

Nous pouvons, par exemple, ajouter dans notre fichier local.conf la ligne :

IMAGE_FEATURES += "tools-sdk"

pour intégrer dans notre image les outils nécessaires à la compilation de code directement sur la cible. La compilation ci-dessous a bien lieu sur ma cible ARM émulée par Qemu :

mybox login: root
Password: (linux)

root@mybox:~# nano my-hello.c
   #include <stdio.h>
   #include <unistd.h>

   int main(void)
   {
     char host[512];  
     gethostname(host, 512);
     printf("Hello from %s\n", host);
     return 0;
   }

root@mybox:~# gcc my-hello.c -o my-hello -Wall 

root@mybox:~# ./my-hello 
Hello from mybox

root@mybox:~# g++ --version
g++ (GCC) 13.3.0
[...]

root@mybox:~# 

Il n’est pas fréquent d’installer une chaîne de compilation native directement sur la plateforme cible, mais cela peut s’avérer intéressant pendant la phase de prototypage et de mise au point. Il s’agit d’un point sur lequel Yocto est plus puissant que son confrère Buildroot qui a renoncé à cette possibilité il y a quelques années.

Création d’une image spécifique

Jusqu’à présent nous avons utilisé l’image core-image-base en ajoutant dans local.conf des lignes «IMAGE_INSTALL:append» et «IMAGE_FEATURES +=» Cette approche est parfaitement adaptée pour les premières phases de configuration du système, mais trouve rapidement ses limites. Pour les systèmes industriels en effet, il est souvent nécessaire de gérer toute une gamme de produits différents. On est donc amenés à réaliser régulièrement des séries de builds avec peu de différences entre-eux. On préfère généralement factoriser toute la configuration commune aux différents produits dans une image particulière et ne laisser dans les fichiers local.conf que les spécificités propres à chaque build.

Autrement dit nous allons créer notre propre fichier de description d’image, et nous n’invoquerons plus «bitbake core-image-base» mais «bitbake my-image» par exemple (en situation réelle, je nomme plutôt l’image en fonction du projet de mon client).

Pour cela, nous devons commencer par créer notre propre layer. Rien de compliqué, l’outil «bitbake-layers» est là pour nous aider.

[build-qemu]$ bitbake-layers  create-layer  ../../layers/meta-my-layer
NOTE: Starting bitbake server...
Add your new layer with 'bitbake-layers add-layer ../meta-my-layer'

[build-qemu]$ ls  ../../layers
meta-my-layer  meta-openembedded  meta-raspberrypi  poky

[build-qemu]$ ls ../../layers/meta-my-layer/
conf  COPYING.MIT  README  recipes-example

[build-qemu]$

Dans le layer nouvellement créé nous trouvons un squelette de fichier `README`, un exemplaire de la license MIT, un répertoire `recipes-example` contenant un recette minimale affichant un message et un répertoire `conf` contenant un fichier `layer.conf` correspondant aux paramétrages du layer.

[build-qemu]$ cat ../../layers/meta-my-layer/conf/layer.conf
# We have a conf and classes directory, add to BBPATH
BBPATH .= ":${LAYERDIR}"

# We have recipes-* directories, add to BBFILES
BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
            ${LAYERDIR}/recipes-*/*/*.bbappend"

BBFILE_COLLECTIONS += "meta-my-layer"
BBFILE_PATTERN_meta-my-layer = "^${LAYERDIR}/"
BBFILE_PRIORITY_meta-my-layer = "6"

LAYERDEPENDS_meta-my-layer = "core"
LAYERSERIES_COMPAT_meta-my-layer = "scarthgap"

Dans ce fichier, deux variables sont particulièrement utiles :

Le layer est bien créé mais, comme «bitbake-layers» nous l’affiche de manière un peu ambiguë, il n’est pas encore intégré dans la liste des layers que bitbake parcourera lors des builds. Nous devons l’y ajouter :

[build-qemu]$ bitbake-layers  show-layers
NOTE: Starting bitbake server...
layer                 path                                      priority
==========================================================================
meta                  /home/Builds/Lab/Yocto-lab/layers/poky/meta  5
meta-poky             /home/Builds/Lab/Yocto-lab/layers/poky/meta-poky  5
meta-yocto-bsp        /home/Builds/Lab/Yocto-lab/layers/poky/meta-yocto-bsp  5
meta-oe               /home/Builds/Lab/Yocto-lab/layers/meta-openembedded/meta-oe  5

[build-qemu]$ bitbake-layers  add-layer  ../../layers/meta-my-layer/
NOTE: Starting bitbake server...

[build-qemu]$ bitbake-layers  show-layers
NOTE: Starting bitbake server...
layer                 path                                      priority
==========================================================================
meta                  /home/Builds/Lab/Yocto-lab/layers/poky/meta  5
meta-poky             /home/Builds/Lab/Yocto-lab/layers/poky/meta-poky  5
meta-yocto-bsp        /home/Builds/Lab/Yocto-lab/layers/poky/meta-yocto-bsp  5
meta-oe               /home/Builds/Lab/Yocto-lab/layers/meta-openembedded/meta-oe  5
meta-my-layer         /home/Builds/Lab/Yocto-lab/layers/meta-my-layer  6

[build-qemu]$ 

Nous créons dans notre layer un début d'arborescence pour héberger nos recettes personnelles. Son nom doit commencer par «recipes-». Je choisis arbitrairement «recipes-custom», pour les projets de mes clients, je travaille souvent dans «recipes-<nom-de-l-entreprise>».

[build-qemu]$ mkdir  ../../layers/meta-my-layer/recipes-custom/ 

Il faut ensuite y créer un sous-répertoire nommé «images» pour stocker nos recettes décrivant des images. Puis nous y copions le fichier core-image-base.bb pour avoir un point de départ.

[build-qemu]$ mkdir  ../../layers/meta-my-layer/recipes-custom/images/ 

[build-qemu]$ cp  ../../layers/poky/meta/recipes-core/images/core-image-base.bb ../../layers/meta-my-layer/recipes-custom/images/my-image.bb 

En le copiant, j'ai renommé le fichier «core-image-base.bb» en «my-image.bb». Éditons-le, pour obtenir par exemple le contenu suivant :

[build-qemu]$ nano  ../../layers/meta-my-layer/recipes-custom/images/my-image.bb

SUMMARY = "A customized image for development purposes."
LICENSE = "MIT"
inherit core-image
IMAGE_FEATURES += "splash"
IMAGE_FEATURES += "tools-debug"
IMAGE_FEATURES += "tools-profile"
IMAGE_FEATURES += "tools-sdk"
IMAGE_FEATURES += "ssh-server-dropbear"
IMAGE_INSTALL:append = " mc"
IMAGE_INSTALL:append = " nano"

Nous éditons local.conf pour supprimer toutes les lignes «IMAGE_INSTALL:append» et «IMAGE_FEATURES» que nous avions ajoutées auparavant et lançons le nouveau build avec :

[build-qemu]$ bitbake  my-image

Après compilation, nos fichiers seront disponibles dans tmp/deploy/images/qemuarm/ avec le préfixe «my-image-qemuarm-». Au lancement, runqemu utilise la configuration la plus récente. Néanmoins, il est possible de préciser le nom de l'image pour éviter toute confusion ainsi :

[build-qemu]$ runqemu  nographic  my-image

On peut noter, dans la recette d'image ci-dessus la présence de deux syntaxes différentes pour ajouter une chaîne de caractères à la fin du contenu d'une variable :

Mais la différence entre ces deux syntaxes ne se limite pas uniquement à cette histoire d'espace. Sinon nous utiliserions toujours «+=» qui semble plus simple.

Savoir quand utiliser «+=» et quand préférer «:append» n'est pas simple quand il s'agit de compléter des variables initialisées dans des recettes fournies par Poky (ou par des layers supplémentaires, notamment pour le support du matériel). Il est souvent nécessaire d'aller jeter un œil sur l'implémentation des recettes, et il est bon de se familiariser avec l'arborescence de poky/ et celle de meta-openembedded/ par exemple.

On peut toutefois préciser quelques cas d'usage habituels 

Création d'une distro personnelle

Depuis la version Scarthgap (5.0) de Poky, un message d'avertissement apparaît à la connexion :

Poky (Yocto Project Reference Distro) 5.0.2 mybox /dev/ttyAMA0

mybox login: root
Password: (linux)

WARNING: Poky is a reference Yocto Project distribution that should be used for
testing and development purposes only. It is recommended that you create your
own distribution for production use.


root@mybox:~#

Ce message nous indique que la distribution «poky» (une distro dans la terminologie de Yocto) inclut des fonctionnalités utiles pour tester ou déboguer des systèmes mais qui ne sont pas recommandées sur un système en production (pour des problèmes de robustesse et surtout de sécurité).

Il faut bien distinguer deux choses :

La distro poky est définie dans le fichier suivant :

[build-qemu]$ cat ../../layers/poky/meta-poky/conf/distro/poky.conf 
DISTRO = "poky"
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"
DISTRO_VERSION = "5.0.2"
DISTRO_CODENAME = "scarthgap"
SDK_VENDOR = "-pokysdk"
SDK_VERSION = "${@d.getVar('DISTRO_VERSION').replace('snapshot-${METADATA_REVISION}', 'snapshot')}"
SDK_VERSION[vardepvalue] = "${SDK_VERSION}"

MAINTAINER = "Poky Maintainers <poky@lists.yoctoproject.org>"

TARGET_VENDOR = "-poky"

LOCALCONF_VERSION = "2"

# Override these in poky based distros
POKY_DEFAULT_DISTRO_FEATURES = "opengl ptest multiarch wayland vulkan"
POKY_DEFAULT_EXTRA_RDEPENDS = "packagegroup-core-boot"
POKY_DEFAULT_EXTRA_RRECOMMENDS = "kernel-module-af-packet"

DISTRO_FEATURES ?= "${DISTRO_FEATURES_DEFAULT} ${POKY_DEFAULT_DISTRO_FEATURES}"

PREFERRED_VERSION_linux-yocto ?= "6.6%"
PREFERRED_VERSION_linux-yocto-rt ?= "6.6%"

SDK_NAME = "${DISTRO}-${TCLIBC}-${SDKMACHINE}-${IMAGE_BASENAME}-${TUNE_PKGARCH}-${MACHINE}"
SDKPATHINSTALL = "/opt/${DISTRO}/${SDK_VERSION}"

DISTRO_EXTRA_RDEPENDS += "${POKY_DEFAULT_EXTRA_RDEPENDS}"
DISTRO_EXTRA_RRECOMMENDS += "${POKY_DEFAULT_EXTRA_RRECOMMENDS}"

TCLIBCAPPEND = ""

PACKAGE_CLASSES ?= "package_rpm"

SANITY_TESTED_DISTROS ?= " \
            poky-4.3 \n \
            poky-5.0 \n \
            ubuntu-20.04 \n \
            ubuntu-22.04 \n \
            ubuntu-23.04 \n \
            fedora-38 \n \
            fedora-39 \n \
            centosstream-8 \n \
            debian-11 \n \
            debian-12 \n \
            opensuseleap-15.4 \n \
            almalinux-8.8 \n \
            almalinux-9.2 \n \
            rocky-9 \n \
            "
# add poky sanity bbclass
INHERIT += "poky-sanity"

# QA check settings - a little stricter than the OE-Core defaults
# (none currently necessary as we now match OE-Core)
#WARN_TO_ERROR_QA = "X"
#WARN_QA_remove = "${WARN_TO_ERROR_QA}"
#ERROR_QA_append = " ${WARN_TO_ERROR_QA}"

require conf/distro/include/poky-world-exclude.inc
require conf/distro/include/no-static-libs.inc
require conf/distro/include/yocto-uninative.inc
require conf/distro/include/security_flags.inc
INHERIT += "uninative"

BB_SIGNATURE_HANDLER ?= "OEEquivHash"
BB_HASHSERVE ??= "auto"

POKY_INIT_MANAGER = "sysvinit"
INIT_MANAGER ?= "${POKY_INIT_MANAGER}"

# We need debug symbols so that SPDX license manifests for the kernel work
KERNEL_EXTRA_FEATURES:append = " features/debug/debug-kernel.scc"

# Enable creation of SPDX manifests by default
INHERIT += "create-spdx"

On peut y observer qu'elle définit pas mal de variables. Entre autres 

Lors de la création d'une distro pour un projet client, je vérifie et rédéfinis si besoin toutes les variables. Ici nous allons simplement modifier les identifiants «DISTRO_...». Nous allons donc définir un fichier de distro personnalisée et inclure avec la directive «require» la distro poky originale.

Je crée donc un sous-répertoire «conf/distro› dans mon layer 

[build-qemu]$ mkdir ../../layers/meta-my-layer/conf/distro

Dans ce répertoire j'ajoute un fichier «my-distro.conf» contenant :

require conf/distro/poky.conf

DISTRO = "my-distro"
DISTRO_NAME = "My experimental distro"
DISTRO_VERSION = "1.0"

Enfin, il ne faut pas oublier de sélectionner notre distro. Ceci s'obtient dans le fichier «conf/local.conf». Par défaut une ligne «DISTRO ?= "poky"» est présente un peu avant le milieu du fichier. Nous pouvons la surcharger en ajoutant au début du fichier la ligne suivante 

DISTRO = "my-distro"

Après recompilation, quand je démarre l'émulateur je vois :

[...]
Starting bluetooth: bluetoothd.
Starting syslogd/klogd: done
 * Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon
   ...done.

My experimental distro 1.0 mybox ttyAMA0

mybox login: root
Password: (linux)

root@mybox:~#

Il n'y a plus de messages de warning et le prompt de connexion est précédé des identifiants que nous avons mis dans le fichier de configuration de notre distro.

Conclusion

Nous avons vu dans cette séquence – assez longue – comment personnaliser notre image en ajoutant des applications dont les recettes sont livrées avec Poky ou référencées sur le site Open Embedded Layers Index. Nous avons également réussi à créer notre propre image, plutôt que de se limiter à enrichir core-image-base et même à créer notre propre distro.

Dans la prochaine séquence, nous verrons comment modifier le comportement d’une application existante, sans toucher aux recettes téléchargées…

 

Si vous préférez une session de cours interactif, en mode présentiel ou distanciel, n'hésitez pas à vous inscrire à mes formations "Développeur Linux embarqué avec Yocto Project" ou "Yocto Project avancé" .

Ce document est placé sous licence Creative Commons CC BY-NC. Vous pouvez copier son contenu et le réemployer à votre gré pour une utilisation non-commerciale. Vous devez en outre mentionner sa provenance.

Le nom Yocto Project est une marque déposée par la Linux Foundation. Le présent document n'est en aucune façon approuvé par Yocto Project ou la Linux Foundation.

«« sommaire »»