Ich möchte Ihnen sagen, wie ich mit Crosstool-ng einen Cross-Compiler für den Raspberry Pi4 zusammengestellt habe. Vielleicht findet jemand das Thema zu primitiv und langweilig. Zuerst dachte ich selbst, dass ich schnell einen Cross-Compiler zusammenstellen könnte, aber ich musste das Problem basteln und studieren, einige der Nuancen waren für mich unerwartet. Dann werde ich dir sagen, was und wie ich getan habe.
Vielleicht ist die erste Frage, die Sie sich stellen müssen: "Wofür ist ein Cross-Compiler?" Tatsächlich ist der Raspberry Pi4 ziemlich schnell und Sie können Programme direkt darauf kompilieren. Wenn das Projekt einfach ist, ist dies durchaus möglich. Wenn das Projekt jedoch wächst und komplexer wird, ist es bereits besser, auf Cross-Compilation umzusteigen. Dann ist es einfacher, andere Probleme zu lösen. Sie können beispielsweise die automatische Assemblierung des Projekts auf dem Integrationsserver organisieren. Das Cross-Compilieren auf einem schnellen PC kann die Erstellungsgeschwindigkeit erheblich erhöhen, und Sie finden bessere Tools zum Bearbeiten von Programmen auf einem PC.
Zweite Frage: „Kann ich einen vorgefertigten Cross-Compiler nehmen? Warum deine eigenen sammeln? " Um ehrlich zu sein, habe ich keinen normalen Cross-Compiler für Raspberry gefunden. Vielleicht sah ich schlecht aus? Auf Github von RasberryEs gibt ein Tool-Projekt und mehrere Cross-Compiler, aber sie sind uralt! Nun, was ist da? Version 4.9.3? Irgendwie nicht ernst. Auf der Linaro-Download-Seite sehe ich nur Version 7.5, die bereits besser ist, aber erstens auf dem Raspberry Buster-Betriebssystem selbst ist Version 8.3 bereits verfügbar, und zweitens hat der Linaro-Compiler erst nach einigen Patches für mich funktioniert. Es ist irgendwie seltsam ...
Nachdem ich versucht hatte, den Linaro-Compiler auszuführen, dachte ich, ich könnte wahrscheinlich selbst meinen eigenen Cross-Compiler erstellen. Ich hatte bereits einige Erfahrungen mit Crosstool-ng. Ich habe einen Cross-Compiler für Amber SoC gemacht .
Was ist die Komplexität der Montage? Das Crosstool-ng-Tool verfügt über viele verschiedene Einstellungen, die nicht immer klar sind. Das Erstellen des Cross-Compilers auf meinem Laptop dauert ungefähr 45 Minuten. Wenn Sie einen Fehler mit den Einstellungen machen, funktioniert der resultierende Cross-Compiler irgendwie nicht so, sammelt nichts oder sammelt, aber die resultierende Binärdatei läuft nicht auf Raspberry. Nachdem ich den resultierenden Cross-Compiler überprüft hatte, musste ich erneut etwas in den Einstellungen ändern und es erneut von Anfang an generieren. Nun, ich habe ein paar Versuche gemacht, bis es so geklappt hat, wie ich es wollte.
Vielleicht ist die Hauptsache, die ich zuerst nicht wirklich verstanden habe, dass der Compiler mit dem Betriebssystem übereinstimmen muss. Es sieht ein bisschen seltsam aus, aber es stellt sich so heraus. In der Tat enthält das Betriebssystem bereits die Standard-c / c ++ - Bibliotheken. Sie exportieren eine Reihe von Funktionen. Der vom Cross-Compiler generierte Code muss Aufrufe dieser Bibliotheksfunktionen enthalten. Daher müssen die Versionen der Bibliotheken im Cross-Compiler selbst und im Betriebssystem, für das der Code generiert wird, übereinstimmen.
Versuchen wir, einen Cross-Compiler zu erstellen.
Die Vorgehensweise ist wie folgt:
1) Überprüfen Sie, ob die folgenden Pakete auf unserem Hostsystem installiert sind (ich verwende Ubuntu 18):
gcc g++ gperf bison flex texinfo help2man make libncurses5-dev python3-dev autoconf automake libtool libtool-bin gawk wget bzip2 xz-utils unzip patch libstdc++6 rsync git
Wenn etwas fehlt, müssen Sie über sudo apt install installieren.
2) Laden Sie die Crosstool-ng-Version 1.24.0 von ihrer Website herunter:
wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.24.0.tar.bz2
3) Entpacken Sie das resultierende Archiv:
tar xjf crosstool-ng-1.24.0.tar.bz2 cd crosstool-ng-1.24.0
4) Crosstool-ng zusammenstellen:
./configure make make install
5) Patching von Crosstool-ng
Dies ist eine ziemlich seltsame Aktion, aber ohne sie habe ich kein gutes Ergebnis erzielt . Ohne diesen Patch weigerte sich der Cross-Compiler standardmäßig, im Ordner / usr / lib / arm-linux-gnueabihf relativ zu sysroot nach Bibliotheken zu suchen.
Das Pflaster muss an der Himbeere erhalten werden.
Auf dem Himbeer-Pi4 mit installiertem OS Buster (dies ist wichtig, ich erstelle einen Cross-Compiler für dieses spezielle Betriebssystem) müssen Sie die binutils-Quellen verwenden:
sudo apt install binutils-source
und siehe
/usr/src/binutils/patches/129_multiarch_libpath.patch
Diese Datei haben wir im Ordner crosstool-ng-1.24.0 / packages / binutils / 2.31.1 auf unserem Host-Computer abgelegt. Es ist wichtig, es in diesen Ordner zu legen, da auf dem Raspberry Pi OS Buster selbst die binutils-Version 2.31.1 ist. Überprüfen Sie dies mit einem Befehl in der Konsole der Himbeere:
ld --version
Außerdem müssen Sie überprüfen, welche GLIB sich auf Ihrem Betriebssystem für den Squeeze befindet:
ldd --version
Ich habe 2.28 in Buster, was bedeutet, dass Crosstool-ng selbst in dieser Version von GLIB 2.28 konfiguriert werden muss. Standardmäßig gibt es eine andere Version. Wenn dies nicht erfolgt, generiert der Cross-Compiler Code, der unter Raspberry in Buster OS nicht ausgeführt wird. Die Binärdatei kann auf nicht vorhandene Funktionen in externen Bibliotheken verweisen.
6) Bereiten Sie die anfängliche Crosstool-ng-Konfiguration vor
Es gibt bereits einige typische Konfigurationen in Crosstool-ng selbst. Inklusive gibt es eine Konfiguration, die der für den Raspberry Pi3 sehr ähnlich ist.
Eine Liste aller möglichen Konfigurationen kann mit dem folgenden Befehl angezeigt werden:
./ct-ng list-samples
Dann muss die ausgewählte Konfiguration mit dem folgenden Befehl „aktiviert“ werden:
./ct-ng armv8-rpi3-linux-gnueabihf
Eine neue Konfigurationsdatei .config wird angezeigt, die die Eigenschaften des zukünftigen Cross-Compilers vollständig definiert. Jetzt muss es ein wenig korrigiert werden. Sie können es manuell bearbeiten, aber es ist einfacher, es über das Menü zu beheben:
./ct-ng menuconfig
Das allererste Menü sieht folgendermaßen aus:
7) Ändern Sie als Nächstes die seltsame Option, möglicherweise optional.
Fast überall, wo zumindest etwas über das Erstellen eines Cross-Compilers für Raspberry geschrieben wird, wird geschrieben, um die Option "Nur die Toolchain schreibgeschützt rendern" zu deaktivieren. Diese Einstellung befindet sich im Menü "Pfade und verschiedene Optionen". Die Crosstool-ng-Dokumentation besagt, dass der resultierende Compiler standardmäßig schreibgeschützt ist, damit das kompilierte Programm nicht versehentlich im Sysroot des Compilers selbst installiert wird. Meiner Meinung nach ist dies eine durchaus vernünftige Entscheidung. Ich weiß nicht, warum Autoren schreiben, um das Häkchen von hier zu entfernen ...
8) Weiter. Gehen Sie zum Element "Zieloptionen" und stellen Sie die Werte gemäß dem Screenshot ein:
Ich muss sagen, dass der Raspberry Pi4 tatsächlich einen Cortex-A72-Prozessor hat, der hier im Menü zugewiesen werden kann. Ich habe den Cortex-A53 jedoch für mich behalten, da ich nicht nur für Pi4, sondern auch für Pi3 kompilieren werde. Die genaue Einstellung kann jedoch bereits beim Starten des gcc-Compilers mit dem Befehlszeilenparameter -mcpu = cortex-a72 angegeben werden
Ich möchte auch hinzufügen, dass ich es vorziehe, dass der Cross-Compiler genau das gleiche Tupel hat wie der Compiler auf dem Raspberry-Board. Das heißt, der endgültige Compiler wird arm-linux-gueabihf sein und sonst nichts. Es ist einfacher für mich. Viele vorhandene Pakete enthalten vorgefertigte cmake-Dateien, in denen der Compiler arm-linux-gnueabihf zugewiesen ist. Wir wollen nicht alle diese cmake-Dateien von Hand reparieren und dort so etwas wie armv8-mygcc-linux-gnueabihf schreiben? Dazu deaktiviere ich die Option "Herstellerteil des Zieltupels weglassen".
9) Gehen Sie zum Menü "Binäre Dienstprogramme" und installieren Sie die Version binutils 2.31.1 (Denken Sie daran, dass wir noch einen Patch dafür haben?)
10) Gehen Sie zum Menü "Betriebssystem" und installieren Sie die Kernel-Version 4.20
Tatsächlich hat Raspberry Buster OS bereits einen 5.10-Kernel, aber das Maximum ist, dass Sie ihn nur installieren können. 4.20
11) Gehen Sie zum Menü "C-Bibliotheken" und installieren Sie die GLIB 2.28-Version.
12) Gehen Sie zum "C-Compiler". Menü
Installieren Sie die gewünschte Version des zukünftigen Cross-Compilers 8.3.0 und fügen Sie die Option --enable-multiarch zu den Einstellungen des zusätzlichen gcc-Konfigurationscompilers hinzu. Es ist wichtig, dass der Cross-Compiler die Bibliotheken in Sysroot entlang des Pfads / usr / lib / arm-linux-gnueabihf findet.
Jetzt verlassen wir alle Menüs, speichern die auf Anfrage vorgenommenen Änderungen und beginnen mit dem Erstellen .
13) Die Montage erfolgt mit einfachen Befehlen:
export DEB_TARGET_MULTIARCH=arm-linux-gnueabihf ./ct-ng build
Muss warten. Die Montage auf meinem Laptop dauerte ungefähr 45 Minuten. Nach dem Erstellen befindet sich Ihr neuer Cross-Compiler im Pfad ~ / x-tools / arm-linux-gnueabihf.
Sie können überprüfen, welche Bibliothekspfade standardmäßig vom Cross-Compiler verwendet werden. Wird es im Pfad / usr / lib / arm-linux-gnueabihf aussehen?
Führen Sie dazu den folgenden Befehl aus:
~/x-tools/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ld --verbose | grep "SEARCH"
Der Befehl sollte ungefähr Folgendes zurückgeben:
SEARCH_DIR("=/usr/local/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/usr/lib/arm-linux-gnueabihf"); SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib"); SEARCH_DIR("=/home/nick/x-tools/arm-linux-gnueabihf/arm-linux-gnueabihf/lib");
Beachten Sie, dass die Pfade mit dem Zeichen "=" beginnen. Dies bedeutet, dass dies sysroot-relative Pfade sind, wenn beim Ausführen von gcc mit der Befehlszeilenoption --sysroot = PATH_TO_YOUR_SYSROOT angegeben.
Das ist wahrscheinlich alles. Es bleibt zu entscheiden, wo Sysroot bekommen wird. Am einfachsten ist es, alle erforderlichen Entwicklungspakete auf dem Raspberry Pi zu installieren und dann die SD-Karte aus dem Gerät herauszuziehen und auf den Host-PC zu übertragen. Es gibt aber auch einige Nuancen.
Jetzt, da wir einen Cross-Compiler haben, können wir eine Art Parser-spezifisches Programm erstellen. Zum Beispiel die Userland-Demos von Raspberry selbst:
git clone https://github.com/raspberrypi/userland.git cd userland export PATH=${HOME}/x-tools/arm-linux-gnueabihf/bin:$PATH ./buildme
Das Kompilierungsergebnis befindet sich im Ordner build / bin.
Am Ende des Artikels möchte ich eine Tabelle mit zusätzlichen Parametern für gcc-Compiler angeben, wenn Projekte für verschiedene Versionen von Himbeeren erstellt werden:
Raspberry Pi 1: -mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp (alias for vfpv2) Raspberry Pi 2: -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 Raspberry Pi 3: -mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits Raspberry Pi 4: -mcpu=cortex-a72 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits
Ich hoffe, dass mein Artikel jemandem nützlich sein wird.