Forum: Compiler & IDEs [LPC21xx/ARM] C++ mit gcc ohne libc


von Lukas W. (geloescht)


Lesenswert?

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

von Marc Prager (Gast)


Lesenswert?

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

von Lukas W. (geloescht)


Lesenswert?

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
Noch kein Account? Hier anmelden.