Yocto:SDK:HD51
Die Basis um Images für aktuelle Hardware zu erstellen, auf der Neutrino-HD/MP läuft, wurde bereits für stlinux-basiernde Geräte beschrieben. Damit ist es generell möglich, mit bestimmten Linux-Grundkenntnissen, sein eigenes Image zu erzeugen, bzw. gibt Distributoren ein solides Werkzeug in die Hand, um Releases mit einer zuverlässigen Paktierung für Updates bereitzustellen und zu warten. Das Yocto-Build ist dafür quasi ein Standard und besitzt hierfür eine recht ausgereifte, gewartete und nachhaltig durchdachte Struktur. Für Entwickler ist es allerdings notwendig einen flexiblen Arbeitsbereich zu haben, um Applikationen zu entwickeln, zu warten und zu testen. Auch hierfür bietet Yocto passende Mittel. Dieser Artikel soll erklären, wie man eine solche Umgebung (SDK) aufsetzt und benutzt.
Inhaltsverzeichnis
Vorbereitungen
Diese Anleitung wurde getestet mit OpenSuse 42.3. Für Debian basierende Distributionen sollten im wesentlichen die bereits hier genannten Schritte zur Vorbereitung zutreffend sein.
Die hier verwendete Basis für die Erstellung einer Arbeitsumgebung basiert auf der Arbeit von Community-Mitgliedern. Auf Vollständigkeit, inhaltliche und rechtliche Korrektheit sowie Funktionsfähigkeit kann daher keine Garantie gegeben werden. Fehlerberichte, Meinungen und Vorschläge sollten daher an die Betreuer der jeweiligen Buildsysteme bzw. Layer gerichtet werden.
Pakete installieren
Für Debian basierte Systeme (getestet mit Wheezy und Jessie in 32/64bit).
$ sudo apt-get update
$ sudo apt-get install libsdl1.2-dev chrpath git build-essential automake texinfo
Für OpenSuse (getestet mit OpenSuse 42.3/15.0 64bit)
$ sudo zypper install git make gcc-g++ diffstat texinfo chrpath libSDL-devel python3-curses zip glew-devel freeglut-devel libid3tag-devel libmad-devel libogg-devel libsigc++2-devel flac-devel
libvorbis-devel yasm
Bei Bedarf kann man weitere benötigte Pakete auch mit Hilfe der Suse Downloadsuche direkt nachinstallieren:
https://software.opensuse.org/search
Des Weiteren benötigt man ein extra Verzeichnis im $HOME
in dem man alle nötigen Verzeichnisse samt zusätzlicher Unterverzeichnisse anlegen kann. Im folgenden wird $HOME/yocto
verwendet, das kann natürlich jeder seinen Gepflogenheiten anpassen. Achtung, ein späteres Verschieben ist nicht einfach möglich da innerhalb der erzeugten Toolchain mit absoluten Pfaden gearbeitet wird!
$ mkdir ~/yocto && cd ~/yocto
Innerhalb dieses Verzeichnisses sollte man direkt auch einen gemeinsamen Downloadordner für die möglichen verschiedenen Systeme anlegen, dies erspart später mehrfaches Herunterladen der diversen Source Pakete. Wer ein entsprechendes Verzeichnis für derartige Downloads schon besitzt kann natürlich dieses auch per Symlink einbinden (oder in der späteren Konfiguration den entsprechenden Pfad angeben).
$ mkdir download
Option 1 Download SDK
Hierbei wird nur ein von der Größe her moderates Installationsskript für das SDK heruntergeladen und nachfolgend bei der Erzeugung der Entwicklungsumgebung alles nachgeladen, was benötigt wird. Diese Variante ist recht simpel und mit einer geeigneten Internetverbindung relativ schnell erledigt. Wer lieber selbst bauen will, sollte mit der Option 2 fortfahren. Das Ergebnis ist aber im Wesentlichen gleich.
- SDK Installations-Skript herunterladen
$ cd Downloads
$ wget https://tuxbox-images.de/images/hd51/sdk/oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-ext-nodistro.0.sh
--2017-11-10 17:08:08-- https://tuxbox-images.de/images/hd51/sdk/oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-ext-nodistro.0.sh
Auflösen des Hostnamen »tuxbox-images.de (tuxbox-images.de)«... 217.160.11.114
Verbindungsaufbau zu tuxbox-images.de (tuxbox-images.de)|217.160.11.114|:443... verbunden.
HTTP-Anforderung gesendet, warte auf Antwort... 200 OK
Länge: 28509099 (27M) [text/x-sh]
In »»oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-ext-nodistro.0.sh«« speichern.
100%[============================================================================================================================>] 28.509.099 1,53MB/s in 18s
2017-11-10 17:08:27 (1,49 MB/s) - »»oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-ext-nodistro.0.sh«« gespeichert [28509099/28509099]
$
- Installationsscript ausführbar machen
$ chmod 755 oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-ext-nodistro.0.sh
- Anschließend wie unter SDK installieren beschrieben fortfahren!
Option 2 Eigenbau SDK
Hierbei wird quasi das komplette SDK mit Bitbake selbst erzeugt und anschließend das erzeugte SDK installiert. Im Gegensatz zur oben genannten Downloadmethode sind hier mehrere Schritte notwendig. Dies nimmnt natürlich mehr Zeit in Anspruch.
Schritt 1: Benötigte Repos klonen
- Klonen des Yocto Poky Projektes in den Buildsystemordner:
$ git clone git://git.yoctoproject.org/poky.git poky
- Klonen der Meta-Layer-Repos für Neutrino und der jeweiligen Plattform in den poky-Ordner:
In diesem Fall wird als Beispiel die AX/Mut@nt HD51 Plattform verwendet.
$ cd poky
$ git clone https://github.com/neutrino-hd/meta-hd51.git
$ git clone https://github.com/neutrino-hd/meta-neutrino.git
Schritt 2: Umgebung einrichten
- Zuweisen der Vorlage für die Beispielkonfiguration
$ export TEMPLATECONF=meta-hd51/example_neutrino
- Umgebung für "build-hd51" mittels dem "Environment Skript" erzeugen
Es wird dabei automatisch ein Buildordner erzeugt und dort hin gesprungen:
$ . ./oe-init-build-env build-sdk-hd51
Schritt 3: Anpassen der Konfiguartion
- mit einem Editor deiner Wahl, die Konfiguration bearbeiten
$ kate conf/local.conf
Falls gewünscht, einen Downloadordner bestimmen. Dieser wird standardmäßig im Yocto-Ordner als yocto/download angelegt. Man kann auch einen Link auf einen bereits vorhandenen Ordner setzen, was durchaus Sinn macht, denn die Downloads können durchaus sehr umfangreich sein. Ein vorhandenes Archiv kann sich daher als vorteilhaft erweisen.
DL_DIR = "/path/to/your/archiv"
- Hosttyp zuweisen, auf dem dieses SDK lokal verwendet werden soll. Hier als Beispiel x86_64:
#SDKMACHINE ?= "i686" SDKMACHINE ?= "x86_64" #SDK_LOCAL_CONF_WHITELIST = "SSTATE_MIRRORS" SDK_INCLUDE_PKGDATA = "0" #SSTATE_MIRRORS = "file://.* http://my.server.com/path/to/sstate-cache/PATH"
- Entwicklung am Tuxbox-Neutrino erfordert diesen Eintrag, dies ist auch der Standard:
FLAVOUR ="mp"
- Je nachdem was die Hostmaschine verträgt, kann man hier die Anzahl der Threads und Parallel-Makes angeben.
# Determine how many tasks bitbake should run in parallel: BB_NUMBER_THREADS ?= "4" # Determine how many processes make should run in parallel when running compile tasks: PARALLEL_MAKE ?= "-j 4"
DIESE EINSTELLUNG MUSS BLEIBEN!
# What image to build ? IMAGENAME = "neutrino-image"
Die anderen Einstellungen sollten sich von selbst ergeben.
Schritt 4: SDK bauen
- mit bitbake das SDK bauen
$ bitbake -c populate_sdk_ext neutrino-image
Dies dauert eine Weile. Dabei werden jede Menge Tasks ausgeführt. Wenn alles glatt geht, ist das benötigte Installationsskript für das SDK unter diesem Ordner zu finden:
tmp/deploy/sdk/oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-nodistro.0.sh
- Installationsskript ausführbar machen
$ chmod 755 oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-nodistro.0.sh
SDK installieren
Je nachdem ob das Installationsskript frisch erzeugt wurde oder wie hier beschrieben heruntergeladen wurde, jetzt in das Verzeichnis wechseln, in dem es sich befindet.
- Installationsscript ausführen
Den Anweisungen folgen. Einige Eingaben können leer bleiben, um Standardwerte setzen zu lassen. Falls nötig, ist sudo erforderlich. Das Zielverzeichnis sollte man aber an einer für sich günstigen Stelle setzen, also möglichst schon etwas voraus planen.
$ cd <Pfad/zum/Installations-Skript-Ordner>
$ ./oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-nodistro.0.sh
OpenEmbedded SDK installer version nodistro.0
=============================================
Enter target directory for SDK (default: /home/<USER<>/sdk):
You are about to install the SDK to "/home/<USER<>/sdk". Proceed[Y/n]? y
Extracting SDK......................................................................................done
Setting it up...done
SDK has been successfully set up and is ready to be used.
Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
...
Nach der Installation, sollte in etwa diese Struktur vorhanden sein:
$ your@hostname:~/yocto/poky/build-sdk-hd51/tmp/deploy/sdk$ tree -L 4 /home/<USER<>/sdk
/home/<USER>/sdk
├── environment-setup-cortexa15hf-neon-vfpv4-oe-linux-gnueabi <- Das ist das SDK environment script
├── site-config-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
├── sysroots
│ ├── cortexa15hf-neon-vfpv4-oe-linux-gnueabi
.
.
.
└── version-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
SDK Umgebung erzeugen
- In das frisch erzeugte SDK-Verzeichnis wechseln
$ /home/<USER>/sdk
- Environment Script ausführbar machen (falls erfordelich)
$ chmod 755 environment-setup-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
Immer wenn man das SDK nutzen möchte und dafür eine neue Shell-Sitzung geöffnet hat, muss dieses Environment-Skript ausgeführt werden. Die Umgebung bleibt dann solange erhalten, bis diese Sitzung geschlossen wird!
Um zu testen, wie die aktuelle Umgebung eingerichtet ist, kann man die $PATH Variable ausgeben lassen.
Ohne das ausgeführte Skript würde das etwa so aussehen:
$ echo $PATH
$ /home/<USER>/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin
- Environment Script ausführen:
$ . ./environment-setup-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
Was ist passiert? Das Skript sollte nun die Umgebung angepasst haben und man kann erahnen, worauf das Ganze hinausläuft.
$ echo $PATH
$ /home/<USER>/devel/sdk/hd51/sysroots/x86_64-oesdk-linux/usr/bin:/home/<USER>/devel/sdk/hd51/buildtools/sysroots/x86_64-oesdk-linux/usr/bin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/bin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/sbin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/bin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/sbin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/bin/../x86_64-oesdk-linux/bin:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/bin/arm-oe-linux-gnueabi:/home/<USER>/devel/sdk/hd51/tmp/sysroots/x86_64/usr/bin/arm-oe-linux-musl:/home/<USER>/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/usr/lib/mit/bin:/usr/lib/mit/sbin
Neben der bereits angepassten $PATH-Umgebung, sind nun auch einige weitere Variablen verfügbar:
SDKTARGETSYSROOT - The path to the sysroot used for cross-compilation PKG_CONFIG_PATH - The path to the target pkg-config files CONFIG_SITE - A GNU autoconf site file preconfigured for the target CC - The minimal command and arguments to run the C compiler CXX - The minimal command and arguments to run the C++ compiler CPP - The minimal command and arguments to run the C preprocessor AS - The minimal command and arguments to run the assembler LD - The minimal command and arguments to run the linker GDB - The minimal command and arguments to run the GNU Debugger STRIP - The minimal command and arguments to run 'strip', which strips symbols RANLIB - The minimal command and arguments to run 'ranlib OBJCOPY - The minimal command and arguments to run 'objcopy OBJDUMP - The minimal command and arguments to run 'objdump AR - The minimal command and arguments to run 'ar NM - The minimal command and arguments to run 'nm TARGET_PREFIX - The toolchain binary prefix for the target tools CROSS_COMPILE - The toolchain binary prefix for the target tools CONFIGURE_FLAGS - The minimal arguments for GNU configure CFLAGS - Suggested C flags CXXFLAGS - Suggested C++ flags LDFLAGS - Suggested linker flags when you use CC to link CPPFLAGS - Suggested preprocessor flags
SDK verwenden
Umgebung direkt nutzen
Quellcodedateien könnten praktisch damit bereits direkt kompiliert werden. Auch IDE's können damit eingerichtet werden. Befände man sich in dieser Umgebung, würde z.B. dieses Kommando ein Programm für die gewünschte Plattform erzeugen:
$ $CC main.cpp -o test
Auf Basis dieser angepassten Umgebung könnten bereits vorhandene Makfiles oder ganze Buildsysteme angepasst werden. Dabei müssten diese Umgebungsvariablen an das Buildsystem durchgereicht werden. Dies kann je nach Aufbau der Makefiles oder der Buildsystemstruktur sogar bereits funktionieren. Gut durchdachte Systeme sollten das durchaus ermöglichen, andernfalls kann es auch einen gewissen Aufwand bedeuten.
Arbeiten mit devtool
Wie bereits erwähnt wurde, bietet das Yocto SDK Lösungen an, um gezielt an (fast) jeder beliebigen Applikation, die im Buildsystem übersetzt wird, zu arbeiten. Im SDK wird dafür devtool verwendet.
- Konfiguration anpassen
Die Konfiguration des SDK befindet sich nun im SDK-Ordner unter:
sdk-hd51/conf/local.conf
Im Wesentlichen wurde die ursprüngliche Konfiguration des Buildsystems in die SDK-Konfiguration übernommen, jedoch sollte man dies zumindest nachprüfen und wenn nötig einige Anpassungen vornehmen, die den lokalen Gegebenheiten entsprechen. Wurde das SDK mit dem heruntergeladenen Installationsskript erzeugt, sollte man dies auf jeden Fall tun, da hier bestimmmte Einstellungen des Verteilers noch vorhanden sind und mit Sicherheit nicht zutreffen. Wenn alles passt, weiter mit dem nächsten Schritt.
- Image bauen
$ devtool build-image
Das dauert eine Weile. Hier wird ähnlich wie mit dem Befehl
bitbake neutrino-image
ein lauffähiges Image und die zugehörigen Pakete erstellt, jedoch wird eine abgewandelte Struktur des Buildsystems erzeugt.
- Arbeitsbereich einrichten
Devtool hat nun quasi ein abgewandeltes Duplikat des Buildsystems erstellt. Wie oben schon bemerkt wurde, ist das "normale" Yocto-Build, mehr für den Bedarf von Distributoren vorgesehen. Man kann damit zwar auch entwicklen, aber die Arbeit am Quellcode dürfte im Vergleich zu gewohnten Buildsystemen teilweise recht träge verlaufen.
Mit dem SDK werden flexiblere Möglichkeiten angeboten. Es können z.B. erzeugte Pakete sofort auf die Zielhardware geladen und getestet werden. Weiterhin wird nicht immer generell ein Paket bei jedem angestoßenem Buildvorgang komplett neu gebaut, sondern mit mit bestimmten Kommandos nur das, was notwendig ist. Auch bei Abbrüchen wird immer dort fortgesetzt, wo dieser Abbruch statt fand. Das ist wesentlich handlicher und entspricht etwa dem Ablauf, den man von bisherigen Buildsystemen oder Ausführen von Make her kennt.
Eine Echtzeitverfolgung der Makevorgänge wird standardmäßig zwar nicht angezeigt, aber dafür werden bei Build-Abbrüchen standesgemäß sofort entsprechende Ausgaben angezeigt, die mögliche Fehler sofort erkennen lassen. Ein ausführliches Logging mit Anzeige wo diese Logs zu finden sind, ermöglicht zudem eine genaue Durchsicht aller gemachten Vorgänge und zwar getrennt nach Konfigurierung, Kompilierung, Paketierung usw.
Die Imageerstellung erfolgt konform zum normalem Bauen mit Bitbake. Änderungen an Quellcodes werden normalerweise direkt übernommen. Der dafür notwendige Befehl
dectool build-image
wurde ja schon erwähnt.
Das Erzeugen von neuen Receipes, wird durch Nutzung durch Templates, welche man mit Devtool erzeugen kann, vereinfacht. Auch die Layer befinden sich in der neu erstellten Struktur und können dort gewartet werden. Diese befinden sich allerdings quasi in reinem Quellzustand, also ohne Anbindung an eine Versionsverwaltung. Dies kann man aber selbst nachholen, indem man die betreffenden Layer werden nur durch die GIT-Repositories ersetzt. Man klont nur einfach die Git-Repositories an deren Stelle.
├── hd51
│ ├── bitbake-cookerdaemon.log
│ ├── buildtools
...
│ ├── cache
...
│ ├── conf
...
│ ├── downloads
...
│ ├── environment-setup-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
│ ├── layers
│ ├── site-config-cortexa15hf-neon-vfpv4-oe-linux-gnueabi
│ ├── sstate-cache
...
│ └── 'workspace'
│ ├── appends
│ ├── conf
│ ├── README
│ └── 'sources'
└── oecore-x86_64-cortexa15hf-neon-vfpv4-toolchain-ext-nodistro.0.sh
...
- Quelldaten importieren
Wie man sieht, gibt es nun ein "workspace"-Verzeichnis welches einen Unterordner namens "sources" beinhaltet. Darin befinden sich normalerweise die Quelldaten der Applikationen an denen gearbeitet wird. Dieser Bereich ist leer und muss also noch befüllt werden. Wenn man z.B. an Neutrino arbeiten möchte, folgendes eingeben:
$ devtool modify neutrino-mp-ax51 $ devtool modify libstb-hal
Devtool wird nun den zugehörigen Quellcode, der in der Regel als GIT-Repository vorliegt, in den Workspace-Ordner "umsiedeln".
Wie der Status dieses Bereiches ist, also welche Applikationen derzeit ion Verwendung sind, kann man so abfragen:
$ devtool status
- Quelldaten ändern
In den jeweiligen Git-Repos kann man jetzt seine Änderungen am Quellcode wie gewohnt vornehemen und neu kompileren.
...
│ └── workspace
...
│ └── sources
│ └── 'neutrino-mp-ax51'
...
- Neutrino kompilieren
$ devtool build neutrino-mp-ax51
- Neutrino auf Ziel-Hardware laden
$ devtool deploy-target neutrino-mp-ax51 root@<BOX-IP>
oder auch kombiniert:
$ devtool build neutrino-mp-ax51 && devtool deploy-target neutrino-mp-ax51 root@<BOX-IP>
Alle benötigten Daten, welche in entsprechenden Paketen enthalten sind, werden damit via SSH auf die Zielhardware geladen. Anschließend kann man dann direkt auf der Hardware testen.
Es geht auch anders herum:
- Neutrino von Ziel-Hardware entfernen
$ devtool undeploy-target neutrino-mp-ax51 root@<BOX-IP>
Dies stellt den ursprünglichen Zustand auf der Zielhardware wieder her.
- Auf der Ziel-Hardware debuggen
Um direkt auf der Zielhardware debuggen zu können, gibt es natürlich gdb. Um das auf die Zielhardware zu bekommen macht man im Prinzip das Gleiche wie für jede andere Aplikation:
$ devtool build gdb && devtool deploy-target gdb root@<BOX-IP>
Danach kann man GDB sofort auf der Zielgardware nutzen.
Zu beachten wäre noch, dass unter Umständen bestimmte Abhängikeiten, die evtl. parallel über die Layer angepasst wurden oder neu dazu gekommen sind, ebenfalls in den Workspace geladen werden sollten. Natürlich müssen diese, falls es eforderlich ist, auch auf die Zielhardware geladen werden. Die Notwendigkeit dafür ergibt sich normalerweise immer dann, wenn bestimmte Libs fehlen oder sich geändert haben und dadurch kompilieren Buildfehler auftreten oder Fehlfunktionen während der Ausführun auf der Zielhardware passieren. Alternativ wäre auch eine entprechende Anpassung der Paketverwaltung auf der Zielhardware möglich, die auf die Pakete der Entwicklungsumgebung Zugriff hat und damit aktuell gehalten werden kann.
Falls nicht schon passiert, das Rootpasswort zurücksetzen. Das erspart unnötige Passwortabfragen in Verbindung mit dem deploy-target Kommando
Devtool hat noch weitere Möglickeiten auf Lager. Eine Übersicht gibt
$ devtool -h
bzw. für die Unterkommandos
$ devtool <Unterkommando> -h
Die Vorgehensweise, um neue oder bestehende Receipes oder Layer zu erstellen oder zu warten, ist teilweise ähnlich. Weitere Informationen dazu findet man in der Devtool-Dokumentation.
Weblinks
- https://wiki.yoctoproject.org/wiki/Developer_Workflow_Improvements
- https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html
- http://www.yoctoproject.org/docs/2.1/sdk-manual/sdk-manual.html
- https://wiki.yoctoproject.org/wiki/Developer_Workflow_Improvements
- http://downloads.yoctoproject.org/releases/yocto/yocto-2.1/toolchain/