Cross Compiler: Unterschied zwischen den Versionen

Aus Vu+ WIKI
Wechseln zu: Navigation, Suche
(Installation)
(Markierungen: Mobile Bearbeitung, Mobile Web-Bearbeitung)
(Benutzung)
Zeile 21: Zeile 21:
  
 
=== Schritt 1: Sourcen besorgen ===
 
=== Schritt 1: Sourcen besorgen ===
Die Sourcen für grep befinden sich auf dem GNU-FTP-Server unter https://ftp.gnu.org/gnu/grep/ - die momentan aktuelle Version ist grep-3.8. Die Sourcen werden von dort heruntergeladen und irgendwo auf der Festplatte der Box entpackt, z.B. unter /media/hdd/build. Ausgepackt wird in der Konsole (z.B. Putty) mit dem tar-Befehl: '''tar xvf grep-3.8.tar.gz'''
+
Die Sourcen für grep befinden sich auf dem GNU-FTP-Server unter https://ftp.gnu.org/gnu/grep/ - die momentan aktuelle Version ist grep-3.8. Die Sourcen werden von dort heruntergeladen und irgendwo auf der Festplatte der Box entpackt, z.B. unter /media/hdd/build. Ausgepackt wird in der Konsole (z.B. Putty) mit dem tar-Befehl: <code>tar xvf grep-3.8.tar.gz</code>
  
 
=== Schritt 2: Sourcen konfigurieren ===
 
=== Schritt 2: Sourcen konfigurieren ===
Mit '''cd grep-3.8''' wird in den ausgpackten Source-Tree gewechselt. Die meisten der heute benutzten Software-Pakete werden mit einem '''configure''' konfiguriert; dieses schaut, ob alle benötigten Komponenten für ein erfolgreiches übersetzen vorhanden sind, und generiert die Makefiles, um das Programm anschließend zu übersetzen.
+
Mit <code>cd grep-3.8</code> wird in den ausgpackten Source-Tree gewechselt. Die meisten der heute benutzten Software-Pakete werden mit einem <code>configure</code> konfiguriert; dieses schaut, ob alle benötigten Komponenten für ein erfolgreiches übersetzen vorhanden sind, und generiert die Makefiles, um das Programm anschließend zu übersetzen.
  
Um Makefiles benutzen zu können, benötigt man das '''make'''-Programm. Ein fertig übersetztes Programm befindet sich in der Database beim aktuellen GCC für die ARM-Boxen.
+
Um Makefiles benutzen zu können, benötigt man das <code>make</code>-Programm. Ein fertig übersetztes Programm befindet sich in der Database beim aktuellen GCC für die ARM-Boxen.
  
Ein erster Versuch, den Cross-Compiler zu benutzen, ist immer, den Aufruf von '''configure''' mit der '''CC'''-Variablen zu testen; es gibt eine Reihe von Umgebungsvariablen, die man auf diese Weise (nicht nur) an das configure-Script weiterreichen kann. Ein paar weitere sind: CXX (c++-Compiler), CFLAGS (Flags für den C-Compiler), CXXFLAGS (Flags für den C++-Compiler)
+
Ein erster Versuch, den Cross-Compiler zu benutzen, ist immer, den Aufruf von <code>configure</code> mit der <code>CC</code>-Variablen zu testen; es gibt eine Reihe von Umgebungsvariablen, die man auf diese Weise (nicht nur) an das configure-Script weiterreichen kann. Ein paar weitere sind: CXX (c++-Compiler), CFLAGS (Flags für den C-Compiler), CXXFLAGS (Flags für den C++-Compiler)
  
'''CC=mipsel-oe-linux-gcc ./configure --prefix=/usr'''
+
<code>CC=mipsel-oe-linux-gcc ./configure --prefix=/usr</code>
  
Das funktioniert bei '''grep''' nicht, die Fehlermeldung sagt, dass man den Compiler über den Switch '''--host=mipsel-oe-linux''' angeben soll. Das funktioniert. Also zweiter Versuch:
+
Das funktioniert bei <code>grep</code> nicht, die Fehlermeldung sagt, dass man den Compiler über den Switch <code>--host=mipsel-oe-linux</code> angeben soll. Das funktioniert. Also zweiter Versuch:
  
'''./configure --host=mipsel-oe-linux --prefix=/usr'''
+
<code>./configure --host=mipsel-oe-linux --prefix=/usr</code>
  
Der Switch '''--prefix=/usr''' sagt der Umgebung, dass das fertig übersetzte Programm später nach '''/usr''' installiert werden soll; das bedeutet, dass das Binary unter '''/usr/bin/grep''' installiert wird. Ohne diesen Switch wird normalerweise '''/usr/local''' als Ziel benutzt, und das Binary findet sich später unter '''/usr/local/bin/grep'''.
+
Der Switch <code>--prefix=/usr</code> sagt der Umgebung, dass das fertig übersetzte Programm später nach <code>/usr</code> installiert werden soll; das bedeutet, dass das Binary unter <code>/usr/bin/grep</code> installiert wird. Ohne diesen Switch wird normalerweise <code>/usr/local</code> als Ziel benutzt, und das Binary findet sich später unter <code>/usr/local/bin/grep</code>.
  
 
=== Schritt 3: Compilieren ===
 
=== Schritt 3: Compilieren ===
Als nächstes soll das Programm übersetzt werden; dazu wird '''make''' aufgerufen:
+
Als nächstes soll das Programm übersetzt werden; dazu wird <code>make</code> aufgerufen:
  
'''make'''
+
<code>make</code>
  
 
Meistens dauert der Configure-Schritt genauso lange wie das eigentliche Übersetzen des Programms. Wenn beim Übersetzen keine Fehler passiert sind, kann das Programm installiert werden.  
 
Meistens dauert der Configure-Schritt genauso lange wie das eigentliche Übersetzen des Programms. Wenn beim Übersetzen keine Fehler passiert sind, kann das Programm installiert werden.  
Zeile 47: Zeile 47:
 
=== Schritt 4: Installation ===
 
=== Schritt 4: Installation ===
  
Ich kontrolliere gerne vor dem installieren, was installiert werden soll. Fast alle Makefiles kennen das "Target" "install", viele können auch mit dem Target "install-strip" umgehen, und viele kennen auch eine Möglichkeit, das Programm in einem anderen Verzeichnis zu installieren. In der Regel wird das mit der Variablen '''DESTDIR''' erreicht. Wir führen also aus:
+
Ich kontrolliere gerne vor dem installieren, was installiert werden soll. Fast alle Makefiles kennen das "Target" "install", viele können auch mit dem Target "install-strip" umgehen, und viele kennen auch eine Möglichkeit, das Programm in einem anderen Verzeichnis zu installieren. In der Regel wird das mit der Variablen <code>DESTDIR</code> erreicht. Wir führen also aus:
  
'''make install-strip DESTDIR=/media/hdd/install'''
+
<code>make install-strip DESTDIR=/media/hdd/install</code>
  
Das installiert das übersetzte Programm unterhalb von '''/media/hdd/install''', wo wir noch einmal schauen können, was wir mitnehmen möchten, und was nicht.
+
Das installiert das übersetzte Programm unterhalb von <code>/media/hdd/install</code>, wo wir noch einmal schauen können, was wir mitnehmen möchten, und was nicht.
  
 
=== Schritt 5: Programm einpacken und testen ===
 
=== Schritt 5: Programm einpacken und testen ===
 
Der nächste Schritt ist bei mir immer, die Dateien als IPK einzupacken. Wie das gemacht werden kann, soll hier nicht gezeigt werden; dazu habe ich unter [[Paketmanager opkg]] schon einiges geschrieben.
 
Der nächste Schritt ist bei mir immer, die Dateien als IPK einzupacken. Wie das gemacht werden kann, soll hier nicht gezeigt werden; dazu habe ich unter [[Paketmanager opkg]] schon einiges geschrieben.
  
Wir kontrollieren aber noch einmal, dass der Cross-Compiler ein Mipsel-Binary erstellt hat. Dazu wechseln wir in der Konsole mit "cd" nach '''/media/hdd/install/usr/bin'''. Ein '''ls -l''' zeigt hier drei Dateien an, '''egrep''', '''fgrep''' und '''grep'''. egrep und fgrep sind Shell-Scripten, das eigentliche Binary ist '''grep'''. Wir können uns den Inhalt mit einigen Tools anschauen. Als erstes:
+
Wir kontrollieren aber noch einmal, dass der Cross-Compiler ein Mipsel-Binary erstellt hat. Dazu wechseln wir in der Konsole mit "cd" nach <code>/media/hdd/install/usr/bin</code>. Ein <code>ls -l</code> zeigt hier drei Dateien an, <code>egrep</code>, <code>fgrep</code> und <code>grep</code>. egrep und fgrep sind Shell-Scripten, das eigentliche Binary ist <code>grep</code>. Wir können uns den Inhalt mit einigen Tools anschauen. Als erstes:
  
'''file grep''': Ausgabe sollte sein: '''grep: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.32, stripped'''
+
<code>file grep</code>: Ausgabe sollte sein: <code>grep: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.32, stripped</code>
  
 
Schauen wir etwas genauer in das Binary:
 
Schauen wir etwas genauer in das Binary:
  
'''mipsel-oe-linux-objdump -p grep'''
+
<code>mipsel-oe-linux-objdump -p grep</code>
  
 
Hier sehen wir alle interessanten Informationen, zum Beispiel welche Shared-Libraries das Programm in welcher Version auf der Mips-Maschine benötigt.  
 
Hier sehen wir alle interessanten Informationen, zum Beispiel welche Shared-Libraries das Programm in welcher Version auf der Mips-Maschine benötigt.  
  
 
Das Binary kann jetzt auf eine Mips-Box kopiert werden, um endgültig sicherzustellen, dass wir hier keinen Murks produziert haben.
 
Das Binary kann jetzt auf eine Mips-Box kopiert werden, um endgültig sicherzustellen, dass wir hier keinen Murks produziert haben.

Version vom 26. Februar 2023, 15:09 Uhr

Unter einem Cross-Compiler versteht man einen Compiler, der auf einem bestimmten System (auch Hostplattform genannt) läuft, aber Kompilate (Objektdateien oder ausführbare Programme) für andere Systeme erzeugt. Diese Ziel-Systeme können andere Betriebssysteme, andere Prozessoren oder eine Kombination der beiden sein. Ein konkretes Beispiel wäre ein Compiler, der auf einem Intel-basierten Windows-System läuft und Programme für PowerPC-basierte Linux-Systeme erzeugt. Handelt es sich bei der Zielplattform um ein eingebettetes System, das selbst nicht für Entwicklung und Übersetzung geeignet ist, spricht man auch von einem Target-Compiler.

(Cross-Compiler)

Vorgestellt wird hier ein Cross-Compiler, der auf der auf unseren ARM-Boxen läuft und Code für Mips-Boxen erstellt. Motivation dazu ist, dass unsere 4k Boxen genügend Flash-Speicher und Hauptspeicher bereitstellen, dass ein Cross-Compiler für Mips problemlos neben einem ARM-Compiler auf den Boxen erstellt und installiert werden kann. Und natürlich, dass wir als Entwickler gerne beide von Vu+ bereit gestellten Architekturen unterstützen möchten, auch wenn wir selber nicht beide Architekturen im Zugriff haben.

Beispielhaft zeigt dieser Artikel die Installation und Benutzung des Cross-Compilers.

Installation

In der Database haben wir einen Mips-Cross-Compiler für ARM-Boxen zur Verfügung gestellt. Dieser besteht aus mehreren Paketen :

  • Binutils
  • Compiler
  • Grundstock an Include-Dateien und Libraries ("Sysroot").

Um Binaries für Mips-Boxen auf unseren ARM-Boxen zu erstellen, müssen alle drei Pakete installiert sein.

Nach dem Download der Pakete auf eine ARM-Box können die drei Pakete mit opkg install <Paket.ipk> wie jedes andere Paket auch installiert werden. Nach der Installation befinden sich unter /usr/bin diverse Programme mit dem Präfix mipsel-oe-linux- und unterhalb von /usr/mipsel-oe-linux das "Sysroot" mit Include-Dateien und Bibliotheken, um Mipsel-Binaries zu compilieren.

Benutzung

Beispielhaft wird jetzt die Benutzung des Cross-Compilers anhand eines Pakets beschrieben, welches ich oft und viel benutze: "grep".

Schritt 1: Sourcen besorgen

Die Sourcen für grep befinden sich auf dem GNU-FTP-Server unter https://ftp.gnu.org/gnu/grep/ - die momentan aktuelle Version ist grep-3.8. Die Sourcen werden von dort heruntergeladen und irgendwo auf der Festplatte der Box entpackt, z.B. unter /media/hdd/build. Ausgepackt wird in der Konsole (z.B. Putty) mit dem tar-Befehl: tar xvf grep-3.8.tar.gz

Schritt 2: Sourcen konfigurieren

Mit cd grep-3.8 wird in den ausgpackten Source-Tree gewechselt. Die meisten der heute benutzten Software-Pakete werden mit einem configure konfiguriert; dieses schaut, ob alle benötigten Komponenten für ein erfolgreiches übersetzen vorhanden sind, und generiert die Makefiles, um das Programm anschließend zu übersetzen.

Um Makefiles benutzen zu können, benötigt man das make-Programm. Ein fertig übersetztes Programm befindet sich in der Database beim aktuellen GCC für die ARM-Boxen.

Ein erster Versuch, den Cross-Compiler zu benutzen, ist immer, den Aufruf von configure mit der CC-Variablen zu testen; es gibt eine Reihe von Umgebungsvariablen, die man auf diese Weise (nicht nur) an das configure-Script weiterreichen kann. Ein paar weitere sind: CXX (c++-Compiler), CFLAGS (Flags für den C-Compiler), CXXFLAGS (Flags für den C++-Compiler)

CC=mipsel-oe-linux-gcc ./configure --prefix=/usr

Das funktioniert bei grep nicht, die Fehlermeldung sagt, dass man den Compiler über den Switch --host=mipsel-oe-linux angeben soll. Das funktioniert. Also zweiter Versuch:

./configure --host=mipsel-oe-linux --prefix=/usr

Der Switch --prefix=/usr sagt der Umgebung, dass das fertig übersetzte Programm später nach /usr installiert werden soll; das bedeutet, dass das Binary unter /usr/bin/grep installiert wird. Ohne diesen Switch wird normalerweise /usr/local als Ziel benutzt, und das Binary findet sich später unter /usr/local/bin/grep.

Schritt 3: Compilieren

Als nächstes soll das Programm übersetzt werden; dazu wird make aufgerufen:

make

Meistens dauert der Configure-Schritt genauso lange wie das eigentliche Übersetzen des Programms. Wenn beim Übersetzen keine Fehler passiert sind, kann das Programm installiert werden.

Schritt 4: Installation

Ich kontrolliere gerne vor dem installieren, was installiert werden soll. Fast alle Makefiles kennen das "Target" "install", viele können auch mit dem Target "install-strip" umgehen, und viele kennen auch eine Möglichkeit, das Programm in einem anderen Verzeichnis zu installieren. In der Regel wird das mit der Variablen DESTDIR erreicht. Wir führen also aus:

make install-strip DESTDIR=/media/hdd/install

Das installiert das übersetzte Programm unterhalb von /media/hdd/install, wo wir noch einmal schauen können, was wir mitnehmen möchten, und was nicht.

Schritt 5: Programm einpacken und testen

Der nächste Schritt ist bei mir immer, die Dateien als IPK einzupacken. Wie das gemacht werden kann, soll hier nicht gezeigt werden; dazu habe ich unter Paketmanager opkg schon einiges geschrieben.

Wir kontrollieren aber noch einmal, dass der Cross-Compiler ein Mipsel-Binary erstellt hat. Dazu wechseln wir in der Konsole mit "cd" nach /media/hdd/install/usr/bin. Ein ls -l zeigt hier drei Dateien an, egrep, fgrep und grep. egrep und fgrep sind Shell-Scripten, das eigentliche Binary ist grep. Wir können uns den Inhalt mit einigen Tools anschauen. Als erstes:

file grep: Ausgabe sollte sein: grep: ELF 32-bit LSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.32, stripped

Schauen wir etwas genauer in das Binary:

mipsel-oe-linux-objdump -p grep

Hier sehen wir alle interessanten Informationen, zum Beispiel welche Shared-Libraries das Programm in welcher Version auf der Mips-Maschine benötigt.

Das Binary kann jetzt auf eine Mips-Box kopiert werden, um endgültig sicherzustellen, dass wir hier keinen Murks produziert haben.