Raspberry PI – Cross Compiling unter Mac OS X mit Eclipse

Dieser Artikel ist nicht mehr aktuell, ich empfehle den folgenden Artikel: ARM Cross Compiling unter Mac OS X

Primär beschreibe ich hier das Cross Compiling für den Raspberry PI unter Mac OS X mit der Entwicklungsumgebung Eclipse. Die Anleitung sollte auch unter Linux und Windows funktionieren, jedoch unterscheidet sich die Installation der ARM-Toolchain.

Installation der ARM-Toolchain

Mittlerweile ist es mir gelungen, die ARM-Toolchain auf der Basis der Quellen von Linaro, für Mac OS X zu kompilieren. Die jeweils aktuellen Releases können hier geladen werden.

Bei dem Versuch die Sources selbst zu kompilieren, bin ich irgendwann auf die Seite Sourcery G++ Lite for ARM GNU Linux (2009q3 67) for Mac OS X gestoßen. Sie beinhaltet neben einer exakten Anleitung zur Kompilation der Toolchain auch alle Quellen und Patches. Was aber noch besser ist, die Toolchain können dort bereits kompiliert geladen werden. Für die ersten kleineren Programme sollten diese also ausreichen, wie weit man damit kommt habe ich noch nicht ausgetestet. Der Download-Link lautet:

Das Archiv downloaden, entpacken und in das Verzeichnis „/opt“ verschieben:

(Es kann auch innerhalb des Home-Verzeichnisses verbleiben, dies ist nur meine persönliche Präferenz.)

Damit  die Toolchain auch aus dem Terminal, ohne voranstellen von „/opt/arm-linux-tools“, ausgeführt werden können, muss der Pfad noch der Umgebungsvariable mitgeteilt werden. Da export PATH=/opt/arm-linux-tools:$PATH   nur temporär gültig ist und so nach jedem Aufruf des Terminals neu eingegebne werden müsste, ist es einfacherer die Pfadangabe in die Konfigurationsdatei einzutragen:

Am Ende der Datei die Pfad inklusive „/bin“ hinzufügen:

Eclipse installieren und einrichten

Nun muss, sofern noch nicht vorhanden, Eclipse IDE geladen und installiert werden. Die aktuellen stabile Version sind unter dem folgenden Link verfügbar: http://www.eclipse.org/downloads/

Ich habe Eclipse IDE for C/C++ Developers Juno in der 64Bit Version verwendet. Welche Version ist letztlich egal, es muss jedoch das Eclipse CDT (C/C++ Development Tooling) Plugin verfügbar sein.

Nach dem der Download-Prozess abgeschlossen ist, das Archiv mit einem Doppelklick entpacken, das Verzeichnis „Eclipse“ in den Programmordner legen und mit Doppelklick auf Eclipse öffnen.

Ach wenn Eclipse frisch installiert ist, sollte nun zuerst überprüft werden ob neue Updates zur Verfügung stehen. Hierfür das Menü Help auswählen und auf den Eintrag Check for Updates Klicken.

eclipse01

Sollte ein neues Update verfügbar sein, diese mit Next installieren.

Das erste Projekt

Ob alles funktioniert, überprüft man am einfachsten mit einem kleinen „Hello World“ Programm. Dazu das Menü File → New → Project wähle.

eclipse2

Als Projekt Art C Project auswählen.

eclipse3

Dem Projekt einen Namen geben und als Type Executeable → Empty Project → Cross GCC wählen.

eclipse4

Eclipse bietet immer zwei Konfigurationen, an ein für den Debug und eine für das abschließende Release. Es kann einfach so übernommen werden.

eclipse5

Auch wenn der Compiler im Pfad angegeben wurde, muss er noch Eclipse mitgeteilt werde, da Eclipse nicht weiss welchen Cross Compiler verwenden werden soll. Es muss allerdings nur der Prefix arm-none-linux-gnueabi-, so wie der Pfade zu diesem („/opt/arm-linux-tools/bin“) angegeben werden. Je nach Projekttype wird gcc oder g++ ergänzt. Anhand des Pfades wird noch mitgeteilt, wo die Include und Lib Dateien liegen.

eclipse6Ist das Projekt erstellt, muss diesem noch eine Source Datei zugeordnet werden.

eclipse7

Zum Beispiel eine Datei mit dem Namen „main.c“.

eclipse8

In die „main.c“ kann nun der „Hello world“-Source eingefügt werden.

eclipse9

Über das Menü Project → Build Project das Programm kompilieren. Es befindet sich danach im Verzeichnis Debug, bzw. Release , je nach Konfigurationsauswahl. Es kann nicht mir Run ausgeführt werden, da es ja für den ARM kompiliert ist, es müsste nun erst einmal auf den Raspberry PI kopiert werden.

Remote Debugging

Da es etwas mühsam ist nach jedem Kompilieren das Programm auf den Raspery PI zu kopieren und über SSH zu testen, ob alles so funktioniert, kann man dies alles in Eclipse integrieren. Der Raspberry PI muss hier für im Netzwerk eingebunden sein und er sollte immer die gleiche IP Adresse zugewiesen bekommen.

Zuerst müssen ein paar Plugins installiert werden. Dazu das Menü Help → Install New Software… wählen. Im Drop-Down-Menü Work with: den Eintrag „Juno – http://download.eclipse.org/releases/juno“ wählen. In Name den Eintrag „Mobile and Device Development“ wählen und die folgenden Plugins nach installieren:

  • C/C++ Remote Launch
  • Remote System Explorer End-User Runtime

eclipse10

Mit Next die Installation starten und Finish beenden, Eclipse muss neugestartet werden. Alle in dem Dialog aufgeführten Plugins sollten installiert werden.

Damit der Raspberry PI auch versteht was Eclipse von ihm möchte, muss das Paket gdbserver auf dem Raspbery PI installiert sein. Es ist bei Raspbian zwar standardmäßig installiert, sicherheitshalber sollte es aber überprüft werden.

Des weiteren muss auf dem Raspberry PI auch ein Ort definiert sein wo das ganze, was entwickelt wird, auch gespeichert werden kann. Am sinnvollsten ist es hier die Eclipse Workspace Philosophie beizubehalten.

Einrichten des Projekt für Remote Debugging

In Eclipse auf das Menü Window → Open Perspective → Other klicken und im Dialog Remote System Explorer wählen, mit OK bestätigen.

eclipse11

Anschließend im Menü auf File  → NewOther… klicken und im Dialog unter Remote System Explorer den Eintrag Connection wählen. Mit Next in die nächste Dialogebene gehen.

eclipse12

Unter General den Eintrag Linux wählen und mit Next in die nächste Dialogebene gehen.

eclipse13

Nun müssen die Verbindungsdaten eingegebne werden.

  • Host Name: Die IP-Adresse des Raspberry PI oder, sofern unterstützt den Name (mein Raspberry PI heißt raspi)
  • Connection Name: Ein beliebiger Name
  • Description: Eine eindeutige Beschreibung der Verbindung (optional)

eclipse14

Mit Next in die nächste Ebene gehen, als Konfiguration „ssh.files“ wählen und wieder Next drücken.

eclipse15

Als Prozess den Type „process.shell.linux“ wählen und Next drücken.

eclipse16

Als Shell den Type „ssh.shells“ wählen und Next drücken.

eclipse17

Als letzten Punkt noch das SSH-Terminal wählen und mit Finish abschließen.

eclipse18

Mit einem Rechtsklick auf die Verbindung das Kontextmenü aufrufen und Properties wählen.

eclipse19

 

In dem Dialog, auf der linken Seite, Host auswählen und als Default User ID den Benutzernamen eingeben, zum Beispiel „pi“ und mit OK bestätigen.

eclipse20

Mit dem Menü Run → Debug Configurations den Konfigurationsdialog aufrufen. Unter „C/C++ Remote Application“ das entsprechende Projekt einbinden und den Pfad auf dem Target eingeben. Gegebenenfalls noch ein chmod execute auf die Datei setzen. Mit Apply die Eingaben übernehmen. Hier heißt das lokale Projekt „hello_world Debug“ und das Projekt für den Raspberry PI „hello_world Debug Remote“.

eclipse21

Durch Drücken des Buttons Debug kann die Datei nun auf dem Raspberry PI ausgeführt werden. Zuvor erscheint eine Passworteingabe, sofern man das Passwort nicht geändert hat, lautet dieses „raspberry“.

eclipse22

Nach der Einrichtung kann das Programm entweder über das Menü Run → Run History → hello_world Debug Remote oder über das Toolbar-Icon Run ausgeführt werden. Die Ausgabe erfolgt dann in dem Tabulator Console.

eclipse23

Mit dieser Art lassen sich bequem Anwendungen für den Raspberry PI, auch ohne weiteren Monitor und Tastatur, entwickle. Der größte Vorteil liegt aber darin, dass einem beim Kompilieren erheblich mehr Rechenleistung zur Verfügung steht. Von der Datensicherung durch TimeMaschine und der Ergonomie von Eclipse mal ganz abgesehen.

Comments

  • Danke! Funktioniert super, bis auf die Geschichte mit dem Remote Debugging.

    Mein App wird schön auf den Raspberry kopiert:
    chmod +x /home/pi/workspace/hello_world/TestRaspberry;gdbserver :2345 /home/pi/workspace/hello_world/TestRaspberry;exit
    aber dann kommt eine Meldung:
    „/Users/tr/Documents/workspace/TestRaspberry/Debug/TestRaspberry“: not in executable format: File format not recognized
    Es sieht so aus, als versucht Eclipse dann doch irgendwie die Datei auf meinem Rechner zu starten, anstatt auf dem Raspberry, obwohl ich in der Konfiguration den Pfad „/home/pi/workspace/hello_world/TestRaspberry“ zur executable angegeben habe.

    Hast du noch einen Tipp/eine Idee wieso?

    Tobias26. Februar 2013
  • Hallo Tobias,
    das habe ich vergessen zu erwähnen. Wenn ich unter „Run“ -> „Debug Configurations“, das Projekt einrichte und dann das Programm auf den Raspberry PI übertrage erhalte ich beim ersten mal die folgende Meldung:
    Error in final launch sequence
    Failed to execute MI command:
    -file-exec-and-symbols /Users/knut/Documents/workspace/hello_world/Debug/hello_world
    Error message from debugger back end:
    "/Users/knut/Documents/workspace/hello_world/Debug/hello_world": not in executable format: File format not recognized
    "/Users/knut/Documents/workspace/hello_world/Debug/hello_world": not in executable format: File format not recognized

    Das ist ja auch die Meldung die bei dir ausgegeben wird.
    Führe ich den Remote Debug nun erneut aus, läuft das Programm auf dem Raspberry.
    Der Fehler tritt bei mir nur beim Einrichten eines neuen Projekts auf und dann nichtmehr.
    Hast du nur einen Versuch unternommen oder kommt die Fehlermeldung immer wieder?

    Knut26. Februar 2013
  • Hallo Knut,

    ich bin deiner Anleitung gefolgt und es hat auch funktioniert.

    Die einfachen Testprogramme werden auf dem Raspi ausgeführt und die

    Terminalausgabe erscheint auf meinem Mac.

    Nun meine Frage,

    ich habe zuvor über eine Remote Desktop Verbindung von Mac auf SuseLinux unter Kdevelop4

    einige Programme geschrieben, da sich der linux server nicht in meiner Wohnung befindet ,

    und diese Programme verwenden die Boost Bibliotheken. (spez thread)

    Kannst du mir sagen ob das in dieser Konstellation auch mit eclipse und cross compiling funktioniert?

     

    mfg

    matze

     

    Matze25. März 2013
  • Hi,
    Sofern du per sah auf den Server kommst und die Bibliotheken lokal verfügbar sind, sollte das möglich sein.
    Gruß

    Knut25. März 2013
  • Hallo Knut,

    danke für die Anleitung, ich kann jetzt das endlich mal vom Mac programmieren und auf dem Raspberry Pi den Code ausführen – aber leider nur ausführen. Beim Debuggen (und zwar immer, nicht nur beim ersten mal) kommt die Fehlermeldung „Error in final launch sequence … /Users/Kalle/workspace/hello/Debug/hello not in executable format“. In der Console sehe ich, dass in der Remote Shell der gdbserver und das Programm hello gestartet werden. Im gdb trace sehe ich aber, dass der Befehl 8-file-exec-and-symbols mit dem lokalen Pfad /Users/Kalle/workspace/hello/Debug/hello (an Stelle des entfernten Pfades) aufgerufen wird. Offensichtlich fehlt hier noch eine richtige Einstellung – ich finde sie leider nicht. Kannst du mir weiterhelfen?

    Kalle29. Mai 2013
  • Hallo Kalle,

    es gibt ja eine Einstellung zum Ausführen und eine für den Debug-Modus. Oder habe ich dich falsch verstanden.

    Gruß

    Knut3. Juni 2013
  • Richtig,

    Ausführen (Menü „Run → Run“; von eclipse auf dem Mac remote auf dem Raspberry Pi ausführen) funktioniert problemlos.

    Debugging (Menü „Run → Debug“) läuft in die o. g. Fehlermeldung.

    Kalle3. Juni 2013
  • Hallo,

    das Problem dürfte sein, das diese vorcompilierte Version der gcc Toolchain zu alt ist für die Version auf dem Raspberry. Ich habe das mit aktuelleren GCC Versionen auf Linux probiert. Hier funktionierte Remote Debugging.

    Gibt es eine Quelle für aktuellere Versionen?

     

    Gruss

     

    Daniel

    Daniel3. August 2013
  • Hallo!

    Ich benutze eine Toolchain von carlson-minot:
    http://www.carlson-minot.com/available-arm-eabi-g-lite-builds-for-mac-os-x/mac-os-x-arm-eabi-g-lite-201305-23-toolchain

    Man muss unter Run –> Debug Configurations im Reiter „Debugger –> Main“ den Debugger einstellen. Bei mir stand standardmäßig einfach nur „gdb“ da. Einfach auf Browse klicken und den Gdb Debugger aus dem bin Verzeichnis der Toolchain auswählen. Dann sollte es bis auf zwei Warnings funktionieren.

    Warnings:

    warning: Unable to find dynamic linker breakpoint function.
    GDB will be unable to debug shared library initializers
    and track explicitly loaded dynamic code.
    Cannot access memory at address 0x0

    warning: Could not load shared library symbols for 6 libraries, e.g. /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so.
    Use the „info sharedlibrary“ command to see the complete listing.
    Do you need „set solib-search-path“ or „set sysroot“?

    mfg. Martin

    Martin23. August 2013
  • Hallo Knut,

    vielen Dank für Deine Anleitung, das war genau der richtige Einstieg. Leider verwenden scheinbar wenige Leute  OSX als Host für den Crosscompiler, die meisten installieren sich lieber Ubuntu VM’s.

    Bei mir hat es ganz gut funktioniert, bis auf das Remotdebugging, da in der oben beschriebenen Toolchain, die Version vom GBD nicht zum GDB Server auf dem Raspi  (aktuelle Raspian Version) passt. Mit der Carslon-Minot Toolchain, hat es dann geklappt.

    Gibt es vielleicht Erfahrungen mit dem Crosscompiling der Boost Library oder Gnublin?

    Scheinbar ist da Eclipse CDT etwas zickig mit den Include Verzeichnissen. Bei mir findet er dauernd irgendwelche Header Files nicht, die Include VErzeichnisse müssten aber laut Projekt Properties gesetzt sein.

     

    Schöne Grüße

    Herwig

    Herwig28. Oktober 2013
  • Danke Herwig, werde ich mal testen.

    Gruß

    Knut3. November 2013
  • Hallo,

    ich bin hier auch noch auf der Suche nach der „perfekten“ Cross-Compiling-Variante um unter OSX (10.9) für den RaspberryPi zu programmieren.

    Zuerst probierte ich wie hier ausführlich beschrieben SourceryG++. Leider ist das Image zu alt, weshalb GDB nicht mit dem Pi ausgeführt werden kann.

    Dann probierte ich Carlson-Minot in der aktuellsten Version. Damit habe ich soweit erfolg, dass ich erfolgreich compilieren und debuggen kann.
    Leider habe ich hier bei einigen Standart-Funktionen wie z.B. „difftime“, „sin(x)“, … das Problem, dass die Rückgabewerte nicht stimmen. Ich bekomme hier statt plausibler Werte irgendwelche Zahlen die gegen unendlich gehen (vielleicht ein Problem zwischen 64Bit OSX und 32Bit ARM?)

    Meine Frage:
    Ist das hier auch jemandem so gegangen und wenn ja, gibt es eine einfache Lösung?

    Jürgen5. Dezember 2013
  • Hallo Knut,

     

    Vielen Dank für die wunderbare Anleitung.  Hat mir sehr weiter geholfen. Allerdings bring ich den Vorgang nicht ganz zu Ende. Das ist sicherlich ein blöder Fehler von mir, allerdings funktioniert bei mir der Zugriff auf den RaspberryPI via ssh nicht. Von Terminal Window aus kann ich mich via ssh auf den Raspberry verbinden, allerdings nicht via Eclipse. Hat jemand eine Idee woran das liegen könnte?

    Herzliche Gruesse

    Christian

     

     

    Christian1. Dezember 2014
  • Hallo Christian,
    was Windows angeht, bin ich mir nicht sicher (habe ich nicht will ich nicht).
    Aber ich denke, da die jegliche Unix Tools fehlen, benötigst du noch oder .

    Gruß

    Knut2. Dezember 2014
  • Hallo Knut,

    ich bin ein Anfänger was das programmieren betrifft.

    Deine Anleitung ist klasse und für jeden super verständlich :). Nur komm ich bei einer Sache nicht weiter, unzwar bekomm ich nach dem „Build All“ folgende Fehlermeldung :
    /bin/sh: arm-none-linux-gnueabi-g++: command not found
    make: *** [src/Hello_World.o] Error 127
    kannst du mir da weiterhelfen?
    Ich habe ein Mac und bin eigentlich deiner Anleitung gefolgt, ich weiß nicht wo das /bin/sh herkommt… und der Error 127

    Gruß Matze

    Matthias27. März 2015
  • Hi Matze,

    das bedeutet, dass der Cross Compiler nicht gefunden wurde. Du must dich irgendwo bei der Einstellung vertippt haben oder Carlson-Minot hat was in den Pfaden geändert.
    Ich kann das nicht mehr nachvollziehen, da ich den Compiler nicht mehr verwende (er kann nur soft float). Deshalb steht aber auch oben, dass der Artikel nicht mehr aktuell ist, und besser „ARM Cross Compiling unter Mac OS X“ verwendet werden sollte.

    Das /bin/sh ist die Shell die das Ganze ausführen soll. Das zu erklären würde jetzt den Rahmen sprengen, schau mal hier http://de.wikipedia.org/wiki/Unix-Shell.
    Aber lass dich nicht abschrecken, das Ganze Verständnis kommt irgend wann automatische.

    Gruß

    Knut30. März 2015
Kommentare sind geschlossen