Yocto: integrazione di layers con repo

da | Feb 3, 2021

Questo articolo prosegue la serie di pezzi tecnici su Yocto, affrontando il primo problema (l’integrazione di layers) con il quale ci si scontra al momento del setup del proprio ambiente: come aggregare i meta-layers che compongono il nostro progetto.

In riferimento all’articolo precedente [Yocto – Una scelta vincente], il nostro progetto di esempio è così strutturato:

├── bitbake*
├── documentation*
├── meta*
├── meta-hmi
├── meta-intel
├── meta-openembedded
├── meta-poky*
├── meta-qt5
├── meta-selftest*
├── meta-skeleton*
├── meta-acme-localization
├── meta-yocto-bsp*
├── oe-init-build-env
└── scripts*

Si noti che:

• Le directory marcate con asterisco (*) fanno parte del repository principale di Yocto

 meta-openembeddedmeta-intel e meta-qt sono repository git esterni/terze-parti

 meta-hmi e meta-acme-localization sono repository git interni/proprietari

Integrazione di layers con repo

La soluzione che andiamo ad illustrare, e che raccomandiamo ai nostri clienti, è basata su repo, un tool costruito sopra git per i seguenti scopi:

 Gestire repository git multipli

 Effettuare gli uploads verso i sistemi di controllo revisione, come gerrit

 Automatizzare parte del workflow di sviluppo

La funzionalità di interesse nel nostro caso è la capacità di repo di aggregare molteplici repository git in un solo contenitore, evitando l’utilizzo dei git submodules, ma certamente anche le altre funzionalità devono essere tenute in considerazione.

Quanto descritto può essere fatto in modo molto semplice mediante un file manifest di repo, che andremo tipicamente a versionare su un repository git dedicato, ad esempio denominato manifests: tale repository conterrà i manifest per tutti i nostri progetti Yocto.

Il file manifest di repo

Il nostro manifest, denominato ad esempio acme-hmi.xml, sarà così definito:

<?xml version="1.0" encoding="UTF-8"?>
<manifest>

   <remote  name="acme"
            fetch=".."
            revision="master" />

   <remote name="oe" fetch="git://github.com/openembedded" />
   <remote name="yocto" fetch="git://git.yoctoproject.org" />
   <remote name="qt5" fetch="https://github.com/meta-qt5" />
   <default revision="thud"
            remote="yocto"
            sync-j="8"
            sync-c="true" />
   
   <project name="poky" path="poky" />
   <project name="meta-intel" path="poky/meta-intel" />
   <project name="meta-openembedded" path="poky/meta-openembedded" remote="oe" />
   <project name="meta-qt5" path="poky/meta-qt5" remote="qt5" />
   <project name="ACMELOC/meta-acme-localization" path="poky/meta-acme-localization" remote="acme" revision="master" />
   <project name="ACMELOC/meta-hmi" path="poky/meta-hmi" remote="acme" revision="master" />

</manifest>

“La funzionalità di interesse nel nostro caso è la capacità di repo di aggregare molteplici repository git in un solo contenitore, evitando l’utilizzo dei git submodules”

Configurazione remotes defaults

Vediamo le parti più interessanti, iniziando dalla configurazione dei remotes:

<remote name="acme"
fetch=".."
        revision="master" />

   <remote name="oe" fetch="git://github.com/openembedded" />
   <remote name="yocto" fetch="git://git.yoctoproject.org" />
   <remote name="qt5" fetch="https://github.com/meta-qt5" />

Questa sezione ci dice che il nostro remote denominato acme, ovvero l’url git dal quale andremo a prendere i layers proprietari, si trova allo stesso livello del repository manifests (che è da dove prendiamo, appunto, il file acme-hmi.xml), ed è pertanto raggiungibile mediante il percorso “..”.

Questa è una soluzione semplice e pulita, ma può ovviamente essere modificata in base alle necessità.

Gli altri remotes ovviamente sono scaricati da url esterni.

<default revision="thud"
          remote="yocto"
          sync-j="8"
          sync-c="true" />

Particolarmente interessante è il tag <default>, che specifica gli attributi di default da utilizzare per i successivi tags <project>, nel caso in cui essi non siano specificati. Vedremo di seguito alcuni esempi.

Aggiunta dei projects componenti

Vediamo adesso come si aggiungono i diversi componenti che compongono il nostro progetto, partendo dal componente principale, denominato poky, che contiene i tools ed i metadati fondamentali di Yocto:

<project name="poky" path="poky" />

Per quanto definito dal tag <default>, utilizzeremo la revision “thud” (che corrisponde al branch per Yocto 2.6), che scaricheremo dal remote denominato yocto.

Questa linea, mediante l’attributo path, definisce anche la root directory per il nostro progetto, che chiamiamo poky per omonimia con il repository.

Le linee seguenti aggiungono i repository esterni al nostro path poky, specificando il path di destinazione ed il remote da usare per scaricare il  meta-layer:

<project name="meta-intel" path="poky/meta-intel" />
<project name="meta-openembedded" path="poky/meta-openembedded" remote="oe" />
<project name="meta-qt5" path="poky/meta-qt5" remote="qt5" />

Si noti ancora una volta che il componente meta-intel non specifica il remote, e quindi utilizzerà il default: git://git.yoctoproject.org/<name> (branch <revision>)

che nel caso vale 

git://git.yoctoproject.org/meta-intel (branch thud)

Infine si includono i repository interni:

<project name="ACMELOC/meta-acme-localization" path="poky/meta-acme-localization"
           remote="acme" revision="master" />
<project name="ACMELOC/meta-hmi" path="poky/meta-hmi"
           remote="acme" revision="master" />

Si noti che ACMELOC è il nome del progetto che contiene i repositories git (nel nostro caso ospitato su  Bitbucket).

Fetching del progetto repo

A questo punto scaricare il nostro intero progetto Yocto è un gioco da ragazzi:

1. Creiamo la root del nostro progetto, che conterrà il progetto (directory poky con tutti i meta-layers) e la build:

$ mkdir yocto-hmi
$ cd yocto-hmi

2. Inizializziamo il progetto, prendendo il file xml da repository manifests:

$ repo init -u ssh://git@<server>/ACMELOC/manifests.git -m acme-hmi.xml

3. Sincronizziamo i repositories:

$ repo sync

La struttura risultante sarà quella descritta inizialmente:

├── bitbake*
├── documentation*
├── meta*
├── meta-hmi
├── meta-intel
├── meta-openembedded
├── meta-poky*
├── meta-qt5
├── meta-selftest*
├── meta-skeleton*
├── meta-acme-localization
├── meta-yocto-bsp*
├── oe-init-build-env
└── scripts*

Allo stesso livello di poky consigliamo di creare la directory di build, nella quale verranno scaricati i pacchetti sorgenti e generati i pacchetti, il root filesystem e l’SDK.

Conclusioni

Come si è visto l’utilizzo del tool repo per gestire un progetto Yocto è estremamente semplice e pulito, perché si basa su un singolo file xml che descrive interamente il progetto, includendo le versioni dei vari componenti e la struttura su disco. Entrambi gli aspetti sono facilmente customizzabili e consentono di tener ben distinti i componenti terze parti dai layers proprietari, che possono essere riusati in diversi progetti.

Sandro Pinna
Sandro Pinna
Dopo la laurea in Governo d’Impresa mi sono dedicato a molte attività, tutte di diversa tipologia, ma alla fine mi sono dedicato a quello che più mi appassionava: il digital marketing.

Potrebbe piacerti anche