Forum: Compiler & IDEs STM Cube IDE - Compiler für C++ einstellen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Alex (elektroalex)


Lesenswert?

Hallo zusammen,

ich möchte mein Projekt mit C++ in der Cube IDE programmieren. Leider 
scheint der Compiler das noch nicht ganz verstanden zu haben. Beim 
Erstellen des Projekts habe ich natürlich auch C++ ausgewählt. Ich habe 
dann eine Klasse erstellt worauf eine .cpp und eine .h File generiert 
wurden. Beim Kompilieren kommt dann der Fehler 
"../Core/Src/Klasse.h:11:1: unknown type name 'class'". Das kann ich mir 
nur dadurch erklären, dass die Header File aus irgendwelchen Gründen mit 
gcc und nicht mit g++ kompiliert wird. Wie kann ich einstellen, dass das 
mit g++ kompiliert werden soll und warum passiert das nicht automatisch, 
wenn ich ein C++ Projekt erstelle?

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Alex schrieb:
> Hallo zusammen,
>
> ich möchte mein Projekt mit C++ in der Cube IDE programmieren. Leider
> scheint der Compiler das noch nicht ganz verstanden zu haben. Beim
> Erstellen des Projekts habe ich natürlich auch C++ ausgewählt. Ich habe
> dann eine Klasse erstellt worauf eine .cpp und eine .h File generiert
> wurden. Beim Kompilieren kommt dann der Fehler
> "../Core/Src/Klasse.h:11:1: unknown type name 'class'". Das kann ich mir
> nur dadurch erklären, dass die Header File aus irgendwelchen Gründen mit
> gcc und nicht mit g++ kompiliert wird. Wie kann ich einstellen, dass das
> mit g++ kompiliert werden soll und warum passiert das nicht automatisch,
> wenn ich ein C++ Projekt erstelle?

Cube, ist doch wahrscheinlich auch nur wieder ein Eclipse mit CDT. Du 
kannst Dir doch sicher den Aufruf (die Kommandozeile) des Compilers in 
irgend einem Fenster angucken und dort sehen:

- Welche Datei wurde überhaupt übersetzt (Vielleicht war es ja sogar 
eine C Datei)?
- Welcher Compiler wurde überhaupt aufgerufen.
- Mit welchen Optionen wurde der Compiler aufgerufen.

von J. S. (jojos)


Lesenswert?

Da wird das Headerfile wohl von einem C Modul benutzt, alleine werden 
keine Header kompiliert.

von Alex (elektroalex)


Lesenswert?

Ja das stimmt, ich habe die Klasse in main.c eingebunden. Eigentlich 
hätte ich main auch gerne mit g++ kompiliert, da ich die Klasse 
natürlich auch verwenden will. Im Internet wird oft empfohlen, main.c 
einfach in main.cpp umzubennen, aber erstens wird das jedes mal beim 
code generieren überschrieben und zweitens bekomm ich damit irgendeinen 
Makefile error.

von Alex (elektroalex)


Lesenswert?

Torsten R. schrieb:
> [...]
> - Welche Datei wurde überhaupt übersetzt (Vielleicht war es ja sogar
> eine C Datei)?
> - Welcher Compiler wurde überhaupt aufgerufen.
> - Mit welchen Optionen wurde der Compiler aufgerufen.

Wenn ich den Output richtig interpretiere, dann wurde versucht Klasse.h 
mit gcc zu kompilieren. Aber ich kann's dir schnell reinkopieren:
arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m0plus -std=gnu11 
-g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L053xx -c -I../Core/Inc 
-I../Drivers/STM32L0xx_HAL_Driver/Inc 
-I../Drivers/STM32L0xx_HAL_Driver/Inc/Legacy 
-I../Drivers/CMSIS/Device/ST/STM32L0xx/Include 
-I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall 
-fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Core/Src/main.d" 
-MT"Core/Src/main.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o 
"Core/Src/main.o"
In file included from ../Core/Src/main.c:24:
../Core/Src/Klasse.h:11:1: error: unknown type name 'class'
   11 | class Klasse {
      | ^~~~~

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Alex schrieb:

> Wenn ich den Output richtig interpretiere, dann wurde versucht Klasse.h
> mit gcc zu kompilieren. Aber ich kann's dir schnell reinkopieren:
> arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m0plus -std=gnu11
> -g3 -DDEBUG -DUSE_HAL_DRIVER -DSTM32L053xx -c -I../Core/Inc
> -I../Drivers/STM32L0xx_HAL_Driver/Inc
> -I../Drivers/STM32L0xx_HAL_Driver/Inc/Legacy
> -I../Drivers/CMSIS/Device/ST/STM32L0xx/Include
> -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall
> -fstack-usage -fcyclomatic-complexity -MMD -MP -MF"Core/Src/main.d"
> -MT"Core/Src/main.o" --specs=nano.specs -mfloat-abi=soft -mthumb -o
> "Core/Src/main.o"
> In file included from ../Core/Src/main.c:24:
> ../Core/Src/Klasse.h:11:1: error: unknown type name 'class'
>    11 | class Klasse {
>       | ^~~~~

Nicht ganz: "../Core/Src/main.c" wird übersetzt. Dabei wird dann anhand 
der Dateiendung vermutet, dass es sich dabei um C handelt. In Zeile 24 
steht dann ein "#include "Klasse.h". Der Inhalt der Datei wird an dieser 
Stelle eingefügt und der C Compiler stolpert dann über die C++ 
Sprachkonstrukte.

von Alex (elektroalex)


Lesenswert?

Ah vielen Dank für die Erklärung. Dann sollte meine Frage wohl sein, wie 
ich dafür sorgen kann, dass main.c als cpp behandelt wird. Oder soll ich 
alles in einer eigenen .cpp file programmieren und die dann von main.c 
aufrufen?

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Alex schrieb:
> Ah vielen Dank für die Erklärung. Dann sollte meine Frage wohl sein, wie
> ich dafür sorgen kann, dass main.c als cpp behandelt wird. Oder soll ich
> alles in einer eigenen .cpp file programmieren und die dann von main.c
> aufrufen?

Ich würde main.c in main.cpp umbenennen (und Klasse.h in klasse.hpp), 
damit klar ist, welche Datei in welcher Sprache geschrieben ist.

Deine IDE kann evtl. die Makefiles nicht on the fly anpassen, wenn Du 
eine Datei umbenennst. Versuch doch mal, die Datei aus der Liste der zu 
übersetzenden Dateien zu entfernen, umzubennen und anschließend wieder 
hinzu zu fügen.

Wenn der Code-Generator Dir die Datei immer wieder überschreibt, dann 
müsste man ggf. vielleicht die Code-Generierung anpassen.

Ansonsten kann man dem Compiler auch explizit sagen, welche Sprache in 
einer Datei verwendet wird (üblicherweise, in dem man g++ und nicht gcc 
verwendet).

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Alex schrieb:
> Ah vielen Dank für die Erklärung. Dann sollte meine Frage wohl sein, wie
> ich dafür sorgen kann, dass main.c als cpp behandelt wird.

Geht in der STM32CubeIDE nicht. Man muss die main.c nach main.cpp 
umbenennen, und wenn man den Codegenerator laufen lassen will wieder 
zurück nach .c umbenennen und danach wieder nach .cpp ...

Alex schrieb:
> Oder soll ich
> alles in einer eigenen .cpp file programmieren

Klassen gehören sowieso in separate Dateien. Um das Umbenennen zu 
vermeiden kannst du alle Aufrufe von der main in C++ Files delegieren 
(über den Aufruf globaler Funktionen statt die Klassen direkt zu 
nutzen).

von J. S. (jojos)


Lesenswert?

Einfacher ist es eine cpp Funktion aus dem main.c heraus aufzurufen, das 
ständige umbenennen ist Mist und kein automatisierbarer Build Prozess.

Ist z.B. hier beschrieben :
https://kleinembedded.com/cpp-and-stm32cubemx-code-generation/

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

J. S. schrieb:
> das
> ständige umbenennen ist Mist und kein automatisierbarer Build Prozess.

Mist ja, aber den Code-Generator lässt man eher nur manuell laufen, 
nicht automatisch auf einem CI-Server oder so. Später im Projekt sowieso 
immer seltener.

von J. S. (jojos)


Lesenswert?

Es reicht doch schon wenn man ein Projekt weitergeben möchte und dann 
nur nach Anleitung kompiliert werden kann.
Ich musste beim aktuellen Projekt den Codegenerator häufig aufrufen, 
z.B. um lwip oder DMA Einstellungen zu ändern.

von Alex (elektroalex)


Lesenswert?

Danke dir, dann werd das mal so ausprobieren.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

J. S. schrieb:
> Es reicht doch schon wenn man ein Projekt weitergeben möchte und dann
> nur nach Anleitung kompiliert werden kann.

Im Repository wäre die Datei als main.cpp abgelegt, man kann also direkt 
und sofort kompilieren. Nur um den Codegenerator laufen zu lassen muss 
man es umbenennen.

von J. S. (jojos)


Lesenswert?

Ich habe mein Projekt von einem externen Entwickler bekommen, da waren 
mehrere Stellen drin die im Code in Kommentaren markiert waren und 
geändert werden mussten. Nach jeder Codegenerierung. Sowas nervt, ist 
fehlerträchtig und ein No Go. Zum Glück hat CubeMX 
Eingriffsmöglichkeiten, aber zum Teil aufwändig weil erst Caller von zu 
ändernden Funktionen geändert werden müssen.
Wenn da so eine Automatik drin ist, dann will ich die nicht manuell 
überschreiben müssen. Und auch keine Dateien umbenennen wollen.

: Bearbeitet durch User
von Schwierig (ruelps)


Lesenswert?

Wie schon erwähnt wurde (ist ein alter Hut):

Eine my_main.h (oder hpp, je nach Gusto) mit einer Funktion

extern "C" void my_main(void)

deklarieren und diese my_main.hpp in main.c inkludieren. In main.c dann
my_main() aufrufen. In my_main.cpp kann man sich dann in der Funktion
my_main() in C++ austoben. In my_main() steht dann praktisch das
Hauptprogramm.

Hintergrund ist, daß die Cube immer eine main.c generiert. Also immer
nur C-Code generiert.

von Harald K. (kirnbichler)


Lesenswert?

Schwierig schrieb:
> extern "C" void my_main(void)
1
#ifdef __cplusplus
2
extern "C"
3
{
4
#endif
5
void my_main(void);
6
#ifdef __cplusplus
7
}
8
#endif

So schluckt es dann auch der C-Compiler.

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.