Raspberry-Pi-Programme per Crosscompiling auf dem PC bauen

© zhudifeng, 123RF

Kreuzweise

Der Raspberry Pi ist ein sehr erfolgreicher Rechner für Bastler und interessante Projekte. Was dem Kleinen jedoch nach wie vor fehlt, sind Rechenleistung und Speicher. Besonders Entwickler wünschen sich etwas mehr Leistung zum zügigen Kompilieren von Programmen. Mit Crosscompiling bauen Sie RasPi-Programme ohne große Wartezeiten am PC und führen diese dann auf dem Raspberry Pi aus.

Der Raspberry Pi gibt bekanntlich einen prima Bastelcomputer ab. Nur in wenigen Disziplinen bremst der RasPi die oft hochfliegenden Vorhaben aus: In Sachen Rechenleistung gibt es im Alltag zwar kaum mehr etwas an seiner CPU auszusetzen, wer jedoch rechenintensive Projekte im Kopf hat oder spezielle Software für das RasPi-System übersetzen möchte, der braucht Geduld.

Geschickt wäre es nun, langwierige Rechenaufgaben wie das Kompilieren von Software auf einen leistungsfähigen Computer auszulagern. Das ist insbesondere sinnvoll, wenn Sie an der Software noch entwickeln und den Build-Prozess immer wieder neu anstoßen müssen. Dabei gilt es jedoch, die unterschiedlichen Rechnerarchitekturen zu überwinden: Im Inneren des Raspberry Pi arbeitet eine ARM-CPU, das Herz klassischer PCs stammt hingegen aus der x86-Familie. Per Crosscompiling gelingt der Spagat zwischen den zwei Welten.

Skriptsprachen und Bytecode

Das ist jedoch nicht bei jedem Programm beziehungsweise bei jeder Programmiersprache sinnvoll. Skriptsprachen wie Perl, Python, Ruby, PHP oder Shellskripte interpretiert das System während der Laufzeit. Solche Programme können Sie direkt auf den RasPi kopieren und dort ausführen. Wenig Probleme machen auch mit Java programmierte Anwendungen. Ein in den maschinenunabhängigen Bytecode übersetztes Java-Programm lässt sich auf jeder Architektur ausführen – es braucht dafür nur die richtige Java-Laufzeitumgebung.

Als ähnlich flexibel erweisen sich in Mono/.NET geschriebene Anwendungen – allerdings erst auf den zweiten Blick. Ein "Hello World" ist in Mono schnell geschrieben (Listing 1) und entsprechend Listing 2 ebenso schnell in eine ausführbare Datei übersetzt. Für das Linux-System liegt das Programm danach jedoch als PE32 executable (console) Intel 80386, [...] vor. Was nun? Im Raspberry Pi steckt ja bekanntlich keine Intel-CPU, sondern ein ARM-Prozessor. In diesem Fall gibt es nun aber keinen Grund zur Sorge, hier irrt sich ganz einfach das file-Kommando.

Listing 1

 

class HelloWorldProgram {
  public static void Main() {
    System.Console.WriteLine("Hello, world!");
  }
}

Listing 2

 

$ mcs helloworld.cs   # Übersetzen des Programms
$ file helloworld.exe # Ergebnis der Übersetzung?
helloworld.exe: PE32 executable (console) Intel 80386, Mono/.Net assembly, for MS Windows
$ mono helloworld.exe # Programm ausführen
Hello, world!

Das Ergebnis eines kompilierten Mono-Programms ist nicht x86-spezifisch, sondern eine Common Language Infrastructure (CLI) – ähnlich wie bei Java ein CPU-unabhängiger Bytecode. Die aus dem Kompiliervorgang hervorgehende EXE-Datei lässt sich einfach auf einen RasPi kopieren und problemlos mit mono helloworld.exe ausführen. Disassemblieren Sie die Datei mittels monodis helloworld.exe, dann unterscheidet sich das Ergebnis auf einem PC bis auf wenige Kommentare nicht von dem auf einem Raspberry Pi.

Das kurze "Hello World"-Programm liefert noch ein weiteres gutes Argument, warum man nicht direkt am RasPi entwickeln möchte, sondern die Entwicklung nach Möglichkeit auslagert: Während ein herkömmlicher Laptop (Intel Core i5-2430M mit 2,40 GHz) das Programm in etwa 0,1 Sekunden übersetzt, braucht das Kompilieren auf einem RasPi 2 satte 10 Sekunden. Noch stärker macht sich das beim Bauen des Java-Programms bemerkbar: Der PC erledigt diese Aufgabe in rund 0,7 Sekunden, der RasPi braucht etwas mehr als 11 Sekunden.

Crosscompiler

Nun greifen viele Entwickler von Open-Source-Programmen jedoch nach wie vor gerne zu höheren Programmiersprachen wie C oder C++, im mathematisch-wissenschaftlichen Bereich auch zu Fortran. Die dafür nötigen GNU-Compiler unterstützen zahlreiche CPU-Architekturen und eignen sich daher gut zum Crosskompilieren. Für den Raspberry Pi gibt es passende Crosscompiler [1], die Sie bei den meisten Distributionen allerdings nicht im Paketmanagement finden.

Optimierung für den RasPi 2

Im Raspberry Pi 2 steckt im Vergleich zum ersten RasPi ein wesentlich modernerer Prozessor. Während im RasPi 1 eine ARMv6-CPU arbeitet, schlägt im Inneren des Nachfolgemodells das Herz eines ARMv7. Um eine Anwendung auf das neue Modell zu optimieren, müssen Sie den Crosscompiler anweisen, Assemblerbefehle für diese CPU zu erzeugen. Das Ergebnis läuft auf einem RasPi 2 daraufhin ein wenig schneller, führt auf einem RasPi der ersten Generation jedoch nur zur Fehlermeldung Illegal instruction. Dem C/C++- und Fortran-Compiler geben Sie dafür die Optionen -mcpu=cortex-a7 -mfpu=neon mit. Bei Google Go setzen Sie über die Umgebungsvariable export GOARM=7 den entsprechenden Schalter.

Für die Installation müssen Sie Git auf dem System einspielen (in der Regel über das gleichnamige Paket) und die Raspberry-Tools aus dem GitHub ausbuchen (Listing 3). Das Kommando holt hier nicht ein Archiv von einer Webseite oder einem FTP-Server ab, sondern lädt direkt den aktuellen Entwickler-Code aus dem Versionsverwaltungssystem. Das Ergebnis landet in einem neuen Unterordner mit dem Namen tools/. Rufen Sie das Git-Kommando also in Ihrem Home-Verzeichnis auf, oder – mit Root-Rechten ausgestattet – in /opt/, dem Ordner für an der Paketverwaltung vorbei installierte Programme.

Listing 3

 

$ git clone https://github.com/raspberrypi/tools.git

Die Compiler und die sonstigen Tools wie Linker, Assembler, Hilfsprogramme – die sogenannte Toolchain – stecken in den in Listing 4 aufgeführten Verzeichnissen. Der erste Ordner enthält den nativen Crosscompiler für Gleitkomma-Operationen ohne numerischen Coprozessor ("soft float"), der zweite den Compiler für Operationen mit Gleitkomma-Coprozessor (hard float) [2]. Im dritten Verzeichnis finden sich die Linaro-Crosscompiler für 32-Bit-Rechner, im vierten die Crosscompiler für 64-Bit-Rechner.

Listing 4

 

tools/arm-bcm2708/arm-bcm2708-linux-gnueabi/bin/
tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/
tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/

Am besten nehmen Sie das Verzeichnis mit den gewünschten Compilern in den Pfad auf, bei Bedarf auch alle. Je nach Linux-Distribution und eingesetzter Shell bearbeiten Sie dazu ~/.profile oder ~/.bashrc und erweitern die PATH-Variable über entsprechende export-Anweisungen. Das Beispiel aus Listing 5 beschränkt sich auf die jeweils unter /opt/ abgespeicherten Hard-Float-Compiler und den Crosscompiler für 64-Bit-Systeme.

Listing 5

 

[...]
export PATH=$PATH:/opt/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin/
export PATH=$PATH:/opt/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/
[...]

Die Compiler und sonstigen Tools unterscheiden sich durch ein Präfix voneinander und somit auch von der Toolchain des Host-Systems: arm-linux-gnueabihf- für die Linaro-Toolchain, arm-bcm2708-linux-gnueabi- für die Soft-Float-Toolchain und arm-bcm2708hardfp-linux-gnueabi- für die Hard-Float-Toolchain. Das ist ein übliches Verfahren bei Crosscompilern; Windows-Crosscompiler nutzen beispielsweise die Nomenklatur i686-w64-mingw32-. Der erste Teil vor dem ersten Bindestrich spezifiziert die CPU, danach folgen das Betriebssystem und bei Bedarf noch genauere Spezifikationen (hardfp, softfp, mingw32 oder cygwin). Erst am Ende folgt dann der eigentliche Befehlsname (gcc, g++, gfortran, strip oder beispielsweise objdump) zum Kompilieren.

Beinhaltet die Pfadvariable der Shell den Crosscompiler, übersetzen Sie nun entsprechend Listing 6 ein kurzes C-Programm wie das übliche helloworld.c (Listing 7) auf Ihrem PC. Das Ergebnis kopieren Sie anschließend auf den Raspberry Pi und führen es dort aus. Auch hier erweist sich der Laptop beim Übersetzen um den Faktor 10 schneller als der RasPi, selbst bei einem so kleinen Programm.

Listing 6

 

$ arm-linux-gnueabihf-gcc -o helloworld helloworld.c

Listing 7

 

#include<stdio.h>
int main() {
  printf("Hello World\n");
  return 0;
}

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 8 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Raspberry Pi Geek kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Aktuelle Ausgabe

04/2017
64-Bit-Modus

Diese Ausgabe als PDF kaufen

Preis € 7,99
(inkl. 19% MwSt.)

Neuigkeiten

  • Neues auf der Heft-DVD

    Nur mit dem optimalen System und der richtigen Software nutzen Sie das volle Potenzial Ihres Mini-PCs. Mit der Heft-DVD erhalten Sie nicht nur die neuesten Distributionen für den Raspberry Pi, sondern auch die passenden Programme zu den Artikeln.

  • Double Action

    Auf dem Raspberry Pi 3 läuft normalerweise ein 32-Bit-Linux – und das, obwohl er eine waschechte 64-Bit-CPU besitzt. Mit etwas Mühe lässt sich die angezogene Handbremse aber durchaus lösen.

  • Touch me

    Mit dem Controller-Baustein MPR121 steuern Sie kapazitive Näherungssensoren. Damit lassen sich berührungslos über die Veränderung eines elektrischen Felds Schaltvorgänge auslösen.

  • Geschickt erweitert

    Um den minimal ausgestatteten RasPi Zero auszubauen, benötigen Sie neben einem OTG-Adapter auch einen USB-Hub. Makerspot hat dafür eine interessante Lösung.

  • Aufgestellt

    Viele RasPi-Projekte erfordern einen Bildschirm samt Eingabemöglichkeit, etwa einen kleinen Touchscreen und eine entsprechend optimierte GUI. Die Display T. Box 7 vereint den offiziellen RasPi-Touchscreen mit einem praktischen Gehäuse.

  • Abgespielt

    Mit Volumio und einem Raspberry Pi rüsten Sie jede Stereoanlage mit "smarten" Funktionen auf. Ob es ums Abspielen von MP3s geht, um das Streaming von Spotify oder die Steuerung per Smartphone: In Kombination mit dem RasPi-Touchscreen toppt Volumio viele kommerzielle Lösungen.

  • Sammelstelle

    Ein IMAP-Server auf einem Raspberry Pi sammelt Mails an einer zentralen Stelle, damit alle Geräte aus dem LAN Zugriff darauf haben.

  • Ausgesiebt

    Adblocker filtern Anzeigen direkt aus dem HTML-Code einer Webseite heraus. Einen anderen Ansatz verfolgt Pi-hole: Auf einem Raspberry Pi installiert und als DNS-Server eingerichtet, biegt der Adblocker Anfragen an Werbe-Domains ins Leere um.

  • Du bleibst der Boss

    Mit Ubos ist es ein Leichtes, verschiedene Webdienste unter eigener Kontrolle zu hosten. Die auf Arch Linux basierende Server-Distribution funktioniert auch auf dem Raspberry Pi.

  • Gut getunnelt

    Mit ein wenig Know-how verwandeln Sie im Handumdrehen einen Raspberry Pi in ein abgesichertes System mit integriertem VPN-Gateway für die Geräte in Ihrem heimischen Netz.