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-openembedded, meta-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 e 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.