Hallo, ich habe es nach langen Wirrungen zu einem selbstkompiliertem Crosscompiler unter Linux für meinen LPC2148 (ARM) gebracht. Newlib habe ich zwar für die von GCC benötigten Header verwendet, nicht jedoch kompiliert, da es mit dem Support für den LPC2000 doch recht mau aussieht: Es gibt zwar "newlib-lpc" in der Version 5a aber eigentlich brauche ich nicht einmal Sache wie open(), da ich sowieso kein Dateisystem habe. Bei C bin ich bisher mit der Option -nostdlib recht gut gefahren. Bei C++ meckert der Linker aber sobald ich Klassen oder gar virtuelle Funktionen verwende. libstdc++ will ich auch nicht verwenden, Sachen wie Streams belegen nur unnötig kostbarern Flashspeicher. Brauche ich die etwa für Polymorphie? Fehlt meinem Linkerscript vielleicht eine Sektion? Gelinkt werden bei mir: .text, .rodata, .rodata*, .glue_7, .glue_7t, .data, .bss. Ich habe schon Linkerscripts mit viel mehr Sektionen gesehen, aber mit C hat bisher alles geklappt (nur eben nicht libc, weil nicht vorhanden). Ich habe auch schon -fno-rtti -fno-exceptions eingeschaltet und virtuelle Funktionen weggelassen (obwohl die und wenns hochkommt Exceptions ganz nett wären) und meine eigene abort()-Funktion geschrieben (Endlosschleife g), dann will der Linker immernoch "__gxx_personality_sj0" haben. Ich verwende auch eine eigene crt0.s, die war auf der CD von Olimex drauf, die mit meinem Board kam. Ich würde mich freuen, wenn mir jemand sagen könnte, wie man C++ mit der GCC ohne eine funktionsfähige libc verwenden kann oder ob das schlicht unmöglich ist. Schöne Grüße, Lukas Winter
Hallo Lukas, kann dir leider auch nicht wirklich helfen, aber ich bin sehr interessiert an deinem Vorhaben. Zuerst mal glaub ich aber nicht, dass Du mit deinen sections durchkommst. Leider ist es schlecht/gar nicht dokumentiert f"ur was die unterschiedlichen sections wie z.B.
1 | *ctors* |
usw. sein sollen. C++-Objekte sind etwas anders als initialisierte C-Strukturen. Bei C reichts, wenn der passende Wert drin steht, wof"ur in der crt0 mit memcpy gesorgt wird. Bei C++ hat der Konstruktor aber vielleicht noch andere Sachen gemacht, z.B. einen UART initialisieren. Das geht nicht mit kopieren:
1 | static Uart uart0(0); |
2 | |
3 | void main() { |
4 | uart0.write("Hilfe, ich funktionier nicht!"); |
5 | }
|
"Uber welchen Mechanismus soll der Konstruktor f"ur uart0 aufgerufen werden? Gr"usse Marc Prager
Nunja, das gilt nur für globale Objekte, bei allen anderen Objekten wird bei ihrer Erstellung impliziert der Konstruktor aufgerufen und bei ihrer Zerstörung implizit der Destruktor. Bei globalen Objekten muss man in der crt0 die Konstruktoren aufrufen, da findet sich schon ein Beispiel woanders. Mit schlecht dokumentiert hast du recht, wenn nicht sogar mit garnicht dokumentiert. Zum Beispiel gibt es die Sektion .interp, die angeblich Interruptvektoren enthalten soll, aber woher sie kommt ist mir unklar und was drin steht auch. Das größere Problem - auf globale Objekte kann man verzichten - ist aber wohl, dass die Implementierung der Sprache C++ der GCC stark auf ihrer libsupc++ basiert (was ja in Ordnung ist), welche wiederum stark auf libc basiert (was das Problem ist).
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.