C++ Crosscompiler für Raspi 3B / armv7l

  • Moin!


    Ich würde gerne meine in C++ geschriebenen Raspi-Apps auf meinem Arbeitsrechner (Ryzen 7 unter OpenSuSE Leap 15.3) kompilieren, komme aber mit den x-tools nicht klar: Die C++ Standardbibliothek ist nicht die gleiche, weswegen mit x-tools erzeugte Kompilate auf dem Raspi nicht laufen:

    Code
    pi@autoradio:/import/valen/autoradio $ ./autoradio
    ./autoradio: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./autoradio)

    NB: Die Version von GLIBCXX korreliert zwar mit der Version der libstdc++, ist aber nicht identisch: Beim Pi bekomme ich hier 3.4.25 als letzte unterstützte Version, während x-tools hier 3.4.27 angibt. Das wird dann wohl die ABI-Version sein.


    Der Crosscompiler kommt mit der Version 6.0.27 der libstdc++, doch der Pi hat nur 6.0.25. Eine frischere Version ist für Raspbian Buster anscheinend nicht zu bekommen.


    Was mache ich da? Die Biblio vom Crosscompiler downgraden ist meines Wissens keine gute Idee, weil sie immer auf eine bestimmte Compiler-Version abgestimmt ist. Danke!

  • Was mache ich da?

    Versuch mal mit "-U_FORTIFY_SOURCE" oder mit "-D_FORTIFY_SOURCE=0" zu kompilieren.

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

  • Neben einem Versionsdowngrade des Compilers käme ggf. auch einfach YOCTO in Frage. Damit bekommst du X-Toolchain & damit gebautes Linux, und da ist auch beliebig minimal. Man muss sich natürlich etwas einarbeiten, aber ich bin ziemlich beeindruckt von der Flexibilität und Qualität des Systems.

  • Öh. Die meisten gibts aber sicher auch in YOCTO.

  • Hast Du mal versucht, den Fehler auf Teile des Quelltextes einzugrenzen (zum Beispiel mit einem "Hello World"-Programm angefangen)?

    Optimalerweise postest Du mal den Quelltext + Compiler-Optionen, damit man mal versuchen kann, das Problem nachzustellen.

    Quote

    Ich würde gerne meine in C++ geschriebenen Raspi-Apps auf meinem Arbeitsrechner (Ryzen 7 unter OpenSuSE Leap 15.3) kompilieren ...: Die C++ Standardbibliothek ist nicht die gleiche, weswegen ... erzeugte Kompilate auf dem Raspi nicht laufen...

    Ich bekomme hier einen Widerspruch nicht aufgelöst: Sollen nun C++-Programme, die auf dem Raspi gelaufen sind, auf dem Opensue unter x86-Architektur zum Laufen gebracht werden? Oder sollen die C++-Programme weiterhin auf dem Raspi laufen und statt auf dem Raspi zu compilieren soll auf dem Ryzen compiliert und gelinkt werden? Und wenn letzteres zutrifft: Was ist der genaue Grund, warum nun nicht mehr auf dem Raspi compiliert und gelinkt werden soll sondern stattdessen auf dem Ryzen? Schlechtere Performance des Raspi?

    Mein Github-Repository ist hier zu finden.

  • Quote

    Oder sollen die C++-Programme weiterhin auf dem Raspi laufen und statt auf dem Raspi zu compilieren soll auf dem Ryzen compiliert und gelinkt werden?

    So ist es.

    Quote

    Was ist der genaue Grund, warum nun nicht mehr auf dem Raspi compiliert und gelinkt werden soll sondern stattdessen auf dem Ryzen? Schlechtere Performance des Raspi?

    Genau das.


    Ein simples Hello-World-Programm ist gelaufen. ABER: Spätestens, wenn ich Methoden aus der libstdc++ benötige, startet nichts mehr wegen des ABI-Versionskonfliktes.


    NB: Eigentlich kenne ich den Grund und auch die (theoretische) Lösung, nur weiß ich nicht, wo ich Version 3.0.27 der libstdc++ für Raspbian Buster herkriegen soll. :conf:

  • Bau sie dir doch einfach. Bzw die sollte doch crosscompilert bei dir rumliegen. Sonst hätte der dagegen doch gar nicht linken können. Du musst “nur” mittels LD_LIBRARY_PATH dafür sorgen, dass deine zuerst gefunden wird.


    Aber: spätestens, wenn du eine in C++ gebaute Bibliothek des PIs verwenden willst, wirst du natürlich auf das gleiche Problem stoßen. Weshalb man eben Den XGCC auf das verwandte Zielsystem anpassen muss. Oder eben gleich alles mit demselben baut.

  • Linken tut er ja (auf dem Ryzen, wo Version 3.0.27 für den Raspi vorhanden ist), nur auf dem Pi starten tut er nicht. Oder soll ich die libstdc++ vom Crosscompiler auf den Pi kopieren (ggf. in ein separates Verzeichnis) und dann beim Start des Programms sagen, dass es diese Version nehmen soll? Meinst Du, das wird funktionieren?

  • Das meinte ich, ja. Und dann eben mit LD_LIBRARY_PATH zersingten, das die zuerst gefunden wird.


    Aber: deine “Unzahl eingebundenen Bibliotheken” könnten ggf nicht damit harmonieren.

  • Quote

    Aber: deine “Unzahl eingebundenen Bibliotheken” könnten ggf nicht damit harmonieren.


    Genau das befürchte ich! Deswegen wäre es eine sauberere Lösung, gäbe es die 3.0.27er-Version ganz offiziell in einem Raspbian-Repo, doch aus irgendwelchem Grund hat das noch kein Maintainer gemacht.

  • Die saubere Lösung ist entweder den XGCC an das Zielsystem anzupassen (so wird das ja auch gebaut, Pi OS entsteht aus den gleichen Gründen die du anführst nicht auf dem Pi selbst), oder eben volle Kontrolle zu haben, wie bei YOCTO.


    Und die Version von Buster wird es nicht geben, weil eben ALLER C++-Code für das System mit der gebaut wird. Darum pinnt die den Compiler für ihre Lebenszeit auch fest.

  • Quote

    Die saubere Lösung ist entweder den XGCC an das Zielsystem anzupassen

    Das habe ich zu Beginn mit dem make menuconfig auch gemacht, wie ich den Crosscompiler eingerichtet habe. Oder gibt es da eine Option, um eine ältere Kombo von g++ und libstdc++ auszusuchen?

    Quote

    Und die Version wird es nicht geben, weil eben ALLER C++-Code für das System mit der gebaut wird. Darum pinnt die den Compiler für ihre Lebenszeit auch fest.

    Heißt das also, die 3.0.27er-Version für Raspbian wird es nie geben, weil sonst keine einzige vorher (gegen 3.0.25) kompilierte App mehr laufen wird? Dann müsste ich tatsächlich die Version vom Crosscompiler auf den Pi übertragen und beim Programmstart sagen, er soll diese Version nehmen und keine andere, ja?

  • Für das BUSTER Release wird es die nie geben.


    Ich weiß nicht auf was du dich da genau beziehst mit menuconfig. CrossTools-ng?


    Und hier habe ich noch was gefunden: https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html, kommend von https://stackoverflow.com/ques…ence-in-debug-and-release


    Ob das dann aber wie gesagt mit gelinktem code harmoniert, der eine andere will - das denke ich nicht. Denn dann werden ggf Objekte wie std::string in einer Variante erzeugt & von der anderen entsorgt - aber falsch.

  • So, weil mich das interessiert hat, habe ich nochmal etwas gestöbert: https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html suggeriert, dass die tatsächlich halbwegs abwärtskompatibel innerhalb von subversions sind. Du könntest also Glück haben, und auch Bibliotheken gelinkt gegen die ältere Version tun trotzdem. Würde ich mal ausprobieren, wie gesagt: LD Library path anpassen, https://gcc.gnu.org/onlinedocs…html#faq.how_to_set_paths beschreibt das.


    Ich bin da trotzdem ein bisschen skeptisch, und persönlich würde ich lieber die Kontrolle haben, statt mir so zu behelfen.


    Nachtrag: das hier kommt später.

    Outstanding Issues

    Some features in the C++ language make versioning especially difficult. In particular, compiler generated constructs such as implicit instantiations for templates, typeinfo information, and virtual tables all may cause ABI leakage across shared library boundaries. Because of this, mixing C++ ABIs is not recommended at this time.


    Damit wird meine Befürchtung denke ich wahr. Wenn wirklich C++ Typen über Bibliotheksgrenzen gereicht werden - zb Qt - dann geht das mischen in die Buxe.

    Edited once, last by MistyFlower59469 ().

  • Welche Version hat denn dein XGCC? Laut dem Link den ich oben gepostet habe, musst du einen 8.Xer für die 6.0.25 haben. Wenn du den also auswählst, könnte es klappen.

  • Quote

    Welche Version hat denn dein XGCC?

    Code
    arm-unknown-linux-gnueabi-g++ (crosstool-NG 1.24.0.103_75d7525) 9.2.0


    Quote


    Ich weiß nicht auf was du dich da genau beziehst mit menuconfig. CrossTools-ng?

    Ja.


    Deine Docs zur libstdc++ kenne ich bereits.


    Die Lib von Crosscompiler auf den Pi transferieren, ihren Standort in den LD_LIBRARY_PATH einzutragen und danach die SW zu starten, hilft übrigens nicht. Der Loader schient sie schlichtweg links liegen zu lassen:


    Code
    pi@autoradio:/import/valen/autoradio $ export LD_LIBRARY_PATH=/import/valen/autoradio/lib:$LD_LIBRARY_PATH
    pi@autoradio:/import/valen/autoradio $ echo $LD_LIBRARY_PATH                    /import/valen/autoradio/lib:
    pi@autoradio:/import/valen/autoradio $ ./autoradio
    ./autoradio: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by ./autoradio)
  • Na das ist Ja dein Problem: nimm den GCC 8. Der sollte sich mit crossttools konfigurieren lassen.