Linux Embedded

Le blog des technologies libres et embarquées

Ajouter un package dans OpenEmbedded en 5 minutes

Après avoir vu comment ajouter facilement un package dans buildroot (voir Comment ajouter un paquet dans buildroot en 5 minutes), nous allons nous attaquer au cas de OpenEmbedded.

OpenEmbedded est un système de génération de rootfs et de cross compilation très paramétrable. Le système est basé sur l'outil bitbake qui lit des fichiers de recettes ou recipes et exécute les actions décrites un peu comme le ferait make avec des fichiers Makefile. Bitbake est un outil écrit en python.

Le système OpenEmbedded est très puissant, mais peu paraître un peu lourd au premier abord. Nous allons ici voir comment ajouter facilement un package et construire le .ipkg correspondant puis comment l'inclure dans un rootfs minimaliste.

Pour des informations plus complètes, n'hésitez pas à consulter la documentation officielle de OpenEmbedded.

L'ajout d'un logiciel dans OpenEmbedded.

Tout d'abord commençons par préparer l'environnement de travail :


$oe> mkdir OE
$oe> cd OE

Cela sera le répertoire racine pour la suite de l'article.
Installons openembedded et utilisons la branche de développement :

$oe> git clone git://github.com/openembedded/openembedded.git
$oe> git checkout org.openembedded.dev

Afin de pouvoir utiliser openembedded, il faut aussi installer bitbake (disponible sur le site officiel). Pour cela, il suffit de taper

$oe> wget http://prdownload.berlios.de/bitbake/bitbake-1.12.0.tar.gz
$oe> tar zxf bitbake-1.12.0.tar.gz
$oe> cd bitbake-1.10.2
$oe> ./setup.py build

Ensuite, il faut préparer un répertoire de build pour OpenEmbedded et préparer le répertoire de travail

$oe> mkdir build
$oe> mkdir build/conf

OpenEmbedded a besoin d'une configuration pour fonctionner ainsi que de certaines variables globales. Nous allons donc écrire un script build/setup_env.sh permettant d’exporter les variables nécessaires :

#
# OpenEmbedded environment
#
# OpenEmbedded base directories
export OEDIR=<path_to_your_openembedded_root>
export TOPDIR=<path_to_your_project_root>/build

# update PATH since we will use local bitbake
PATH=$PATH:<path_to_your_bitbake_install>/bin

# bitbake base directories separated by:
export BBPATH=$TOPDIR:$OEDIR

# this is required for bitbake to work properly
export BB_ENV_EXTRAWHITE="OEDIR TOPDIR"

Le fichier de configuration de OpenEmbedded décrit les options de base et sera copié dans build/conf/local.conf:

#
# OpenEmbedded config
#
MACHINE = "i686-generic"
DISTRO = "minimal"
TARGET_ARCH = "i686"
TARGET_OS = "linux-gnu"
COLLECTIONS = "${OEDIR}"
TMPDIR = "${TOPDIR}/tmp"
DL_DIR = "${TOPDIR}/dl/"
BUILDDIR = "${TOPDIR}/"
PSTAGE_DIR = "${BUILDDIR}/cached-builds"
LOCAL_MIRROR = "${OEDIR}"
BBFILES = "${OEDIR}/recipes/*/*.bb"

Il suffit alors d'exécuter :

$oe> source build/setup_env.sh

et l'environnement est pret.

Les fichiers recipes sont stockés par défaut dans $OEDIR/recipes. Vous pouvez bien sur définir votre propre dossier recipes contenant vos recettes personnelles, cependant celui ci devra se nommer recipes et son chemin devra être ajouté dans setup_env.sh (variable BBPATH) et dans local.conf (variable COLLECTIONS). Pour l'instant nous restons dans le dossier OpenEmbedded traditionnel :

$oe> mkdir $OEDIR/recipes/my-helloworld/
$oe> vi $OEDIR/recipes/my-helloworld/my-helloworld_1.0.bb

Ici nous créons un paquet nommé my-helloworld car un paquet helloworld existe déjà dans OpenEmbedded en tant que cible bouchon. Le "_" utilisé entre my-helloworld et 1.0 permet de séparer le nom du package de son numéro de version.
Le fichier .bb contient la description du package ainsi que les règles de construction. Encore une fois nous utiliserons le paquet helloworld.tar.gz, défini dans l'article sur buildroot
le fichier my-helloworld_1.0.bb contiendra donc :

#
# my-helloworld bb file
#
DESCRIPTION = "Helloworld software"
LICENSE = "GPL"
PR = "r0"

SRC_URI = "http://helloworld.com/dl/helloworld-1.0.tar.gz"
S = ${WORKDIR}/${PN}

do_install() {
        oe_runmake install DESTDIR=${D}
}

PACKAGES = my-helloworld
FILES_${PN} = ${bindir}/helloworld

SRC_URI[md5sum] = "17b0b63fe5bf84c83989b90bc23a0921"
SRC_URI[sha256sum] = "bfb864326301cb75619855edc0d802bc3d8cb99c70ab5faa86091968bd5fea06"

En se penchant un peu plus sur le fichier, nous voyons aisement la description du logiciel :

  • La variable PR contient le numéro de révision du paquet.
  • La variable S contient le répertoire de travail dédié pour le paquet helloworld.
  • do_install est une règle pour installer le paquet.
  • La variable D est utilisée pour renseigner le répertoire dans lequel OpenEmbedded s'attend à voir helloworld installé dans la règle do_install
  • La variable PACKAGES permet de lister le nom des packages qui doivent être construit (séparés par des espaces)
  • La variable FILES_${PN} se résoud en tant que FILES_my-helloworld et permet de lister le contenu du paquet my-helloworld. Ici, un seul fichier : /usr/bin/helloworld.
  • Les dernières lignes décrivent le md5sum et le sha256sum permettant de valider l'intégrité et la validité du package qui sera utilisé.

Aucune règle de construction n'est présente ici. Ceci est du au fait que OpenEmbedded propose des actions par défaut. La règle do_build exécute un oe_runmake dans les sources du paquet, il n'est donc pas nécessaire de la redéfinir nous même. oe_runmake est un simple wrapper sur make.

Certaines autres variables sont rendues disponibles par OpenEmbedded, en particulier : PV pour product version et PN pour product name. Nous n'avons pas besoin de celles-ci dans notre cas.

Une fois ce fichier créé, il suffit de rendre disponible les sources helloworld-1.0.tar.gz dans le répertoire défini par la variable DL_DIR du fichier de configuration d'OpenEmbedded et de lancer :

$oe> bitbake my-helloworld

bitbake va commencer par lire toutes les recettes et configuration, puis, un long processus de compilation va démarrer car nous entrainons (la première fois) le téléchargement de toutes les sources, ainsi que la compilation de toute la chaine de compilation. Une fois le processus de compilation terminé sans erreur, le package my-helloworld_1.0-r0_i686.ipk sera créé dans $TMPDIR/deploy/ipk/$ARCH/. Il est possible de vérifier son contenu sous debian/ubuntu avec les commandes :

$oe> dpkg -c my-helloworld_1.0-r0_i686.ipk
$oe> dpkg -I my-helloworld_1.0-r0_i686.ipk

Il est à noter que ce package peut être installé sur toute plateforme (de même architecture) supportant les paquets au format ipkg/opkg.

Intégration dans un rootfs

Nous allons maintenant inclure ce paquet à un rootfs minimaliste. Sous openembedded, tout se fait en utilisant des règles définies dans un fichier recipe. Les règles de création d'une image prédéfinie se trouvent donc naturellement dans le dossier recipes de openembedded, dans le sous répertoire images. Nous allons ici rester sur un exemple minimaliste, et donc utiliser le fichier minimal-image.bb. En jetant un coup d'oeil à ce fichier, nous voyons que sa structure est simple. Les lignes qui nous interessent sont :

  • inherit image
  • IMAGE_INSTALL = ...
  • IMAGE_FSTYPES = ...

La premiere indique que nous allons ici décrire la construction d'une image. Openembedded fournit un mécanisme d'héritage permettant de mutualiser les règles génériques. Ainsi, l'utilisateur pourra par exemple trouver dans le répertoire classes les règles pour la construction de package basique : base.bbclass mais aussi, celle permettant de s'adapter à un package au format autotools : autotools.bbclass.

La deuxième ligne définit une variable utilisée par la classe image.bbclass pour remplir l'image, c'est la liste des packages à installer (leurs dépendances seront résolues par OpenEmbedded).

La troisième ligne n'est pas encore présente dans le fichier par défaut. La variable IMAGE_FSTYPES permet de contrôler le format de sortie des images générées. Celle ci est configurée dans le fichier de description de la distribution : conf/distro/minimal.conf, que nous avons inclus dans conf/local.conf en ajoutant la variable DISTRO = "minimal". Sa valeur par défaut est IMAGE_FSTYPES = "ext2.gz". Nous allons donc ajouter dans le fichier minimal-image.bb la ligne :

IMAGE_FSTYPES = "tar.gz"

l'image résultant sera alors disponible sous forme d'un fichier tar.gz.

Dans notre cas il suffira donc d'ajouter my-helloworld à la liste IMAGE_INSTALL puis de lancer

$oe> bitbake minimal-image

Les images seront disponibles dans le dossier $TMPDIR/deploy/images/$ARCH/

$oe> mkdir output
$oe> tar zxf minimal-minimalist-image-eglibc-ipk-dev-snapshot-20110817-i686-generic.rootfs.tar.gz -C output

va extraire le contenu du rootfs dans le dossier output. Nous pourrons donc valider que notre helloworld est bien présent dans output/usr/bin/helloworld.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.