Kompilierfehler, Ideen?



  • @SeppJ
    eingebundene Header: stdio.h und stdlib.h
    zeigt:

    arm-none-eabi-gcc usart2.c startup.c vendor/CMSIS/Device/ST/STM32F4/Source/Templates/system_stm32f4xx.c -T linker_script.ld -o blink.elf -I/usr/include/ -Ivendor/CMSIS/CMSIS/Core/Include -Ivendor/CMSIS/Device/ST/STM32F4/Include -mcpu=cortex-m4 -mthumb -DSTM32F411Cx
    usart2.c: In function 'main':
    usart2.c:27:1: warning: implicit declaration of function 'gets'; did you mean 'fgets'? [-Wimplicit-function-declaration]
       27 | gets(str);
          | ^~~~
          | fgets
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/crt0.o: in function `_mainCRTStartup':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/libgloss/arm/semihv2m/../../../../../../../../libgloss/arm/crt0.S:547: undefined reference to `__bss_start__'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/libgloss/arm/semihv2m/../../../../../../../../libgloss/arm/crt0.S:547: undefined reference to `__bss_end__'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /tmp/cc4vzFhC.o: in function `main':
    usart2.c:(.text+0x3a): undefined reference to `__isoc99_scanf'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: usart2.c:(.text+0x74): undefined reference to `stdout'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: usart2.c:(.text+0x7c): undefined reference to `stderr'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-exit.o): in function `exit':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/stdlib/../../../../../../../../newlib/libc/stdlib/exit.c:64: undefined reference to `_exit'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-sbrkr.o): in function `_sbrk_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/sbrkr.c:51: undefined reference to `_sbrk'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-writer.o): in function `_write_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/writer.c:49: undefined reference to `_write'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-closer.o): in function `_close_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/closer.c:47: undefined reference to `_close'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-fstatr.o): in function `_fstat_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/fstatr.c:55: undefined reference to `_fstat'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-isattyr.o): in function `_isatty_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/isattyr.c:52: undefined reference to `_isatty'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-lseekr.o): in function `_lseek_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/lseekr.c:49: undefined reference to `_lseek'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-readr.o): in function `_read_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/readr.c:49: undefined reference to `_read'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-abort.o): in function `abort':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/stdlib/../../../../../../../../newlib/libc/stdlib/abort.c:59: undefined reference to `_exit'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-signalr.o): in function `_kill_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/signalr.c:53: undefined reference to `_kill'
    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-signalr.o): in function `_getpid_r':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/reent/../../../../../../../../newlib/libc/reent/signalr.c:83: undefined reference to `_getpid'
    collect2: error: ld returned 1 exit status
    make: *** [Makefile:2: testprogramm] Fehler 1
    


  • Die Funktions char *gets(char*) ist rotten by design, und kann niemals sicher genutzt werden. Man baut sich damit einen exploit direkt in das Programm ein. Es gibt nur eine einzige sinnvolle Hilfestellung: Niemals benutzen!



  • daran liegt es nicht



  • @Timo_R sagte in Kompilierfehler, Ideen?:

    daran liegt es nicht

    usart2.c:27:1: warning: implicit declaration of function 'gets'; did you mean 'fgets'? [-Wimplicit-function-declaration]

    Diese Fehlermeldung ist sehr eindeutig.


  • Mod

    @john-0 sagte in Kompilierfehler, Ideen?:

    @Timo_R sagte in Kompilierfehler, Ideen?:

    daran liegt es nicht

    usart2.c:27:1: warning: implicit declaration of function 'gets'; did you mean 'fgets'? [-Wimplicit-function-declaration]

    Diese Fehlermeldung ist sehr eindeutig.

    Das hat so absolut überhaupt nix mit dem Fehler zu tun.

    @Timo_R : Was steht denn in dem Linkerscript? Hat diese Zielplattform überhaupt Unterstützung für die Standardbibliothek? Eine undefined reference to _exit kann man ja noch fixen, aber undefined reference to stdout und dem Rest ist schon hart.



  • @Timo_R sagte in Kompilierfehler, Ideen?:

    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/crt0.o: in function `_mainCRTStartup':
    

    https://web.archive.org/web/20160410104337/https://community.freescale.com/thread/313490#comment-354077

    arm-none-eabi - This tool chain targets for ARM architecture, has no vendor, does not target an operating system and complies with the ARM EABI.

    Auf Grund von "does not target an operating system" würde ich annehmen dass das meiste aus stdio.h da wirklich einfach nicht verfügbar ist.



  • @Timo_R sagte in Kompilierfehler, Ideen?:

    arm-none-eabi-gcc usart2.c startup.c vendor/CMSIS/Device/ST/STM32F4/Source/Templates/system_stm32f4xx.c -T linker_script.ld -o blink.elf -I/usr/include/ -Ivendor/CMSIS/CMSIS/Core/Include -Ivendor/CMSIS/Device/ST/STM32F4/Include -mcpu=cortex-m4 -mthumb -nostdlib -DSTM32F411Cx

    Welche IDE nutzt du?

    Denn abhängig von der IDE kann man angeben, inwiefern man die Standard Lib verwenden möchte.

    Bei dem Segger Studio z.B. kann man unter Project Options --> Library --> Include Standard Libraries dies einstellen.



  • @SeppJ sagte in Kompilierfehler, Ideen?:

    Das hat so absolut überhaupt nix mit dem Fehler zu tun.

    Ein aktueller GCC wirft Dir exakt diesen Fehler, wenn Du gets verwendest. Include und Linker Probleme kannst Du erst dann angehen, wenn das gets Problem gelöst ist.

    Ergänzung Beispiel:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main() {
        char buffer[4096];
        char* p = gets(&buffer);
    
        return EXIT_FAILURE;
    }
    

    Das liefert die folgende Fehlermeldung

    gcc gets.c -o gets
    gets.c: In function ‘main’:
    gets.c:6:19: warning: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]
        6 |         char* p = gets(&buffer);
          |                   ^~~~
          |                   fgets
    gets.c:6:19: warning: initialization of ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
    /usr/bin/ld: /tmp/ccuYnOwB.o: in function `main':
    gets.c:(.text+0x37): Warnung: the `gets' function is dangerous and should not be used.
    

  • Mod

    Liest du hier überhaupt irgendwas? Oder Beißreflex, weil gets im Text? Das ist nicht einmal ein Fehler...

    Du weißt doch sonst eigentlich ganz gut was los ist, und wie Dinge funktionieren.



  • @SeppJ sagte in Kompilierfehler, Ideen?:

    Liest du hier überhaupt irgendwas?

    Anscheinend verstehst Du das Problem nicht. Solange gets verwendet wird, wird ein aktueller Compiler immer Fehler werfen und das Übersetzen wird scheitern. Und das siehst so aus als ob man ein Include bzw. ein Linker Problem hat. D.h. Du musst zuerst das gets Problem lösen, und danach kannst Du Dich um die anderen Probleme kümmern.


  • Mod

    @john-0 sagte in Kompilierfehler, Ideen?:

    @SeppJ sagte in Kompilierfehler, Ideen?:

    Liest du hier überhaupt irgendwas?

    Anscheinend verstehst Du das Problem nicht.

    Nein! Nein! Nein! Nimm mal Abstand, atme tief durch, dann lies den gesamten Thread noch einmal gründlich und unvoreingenommen durch. Ohne reflexartig auf das Wort gets zu reagieren. Warum hat der Threadersteller wohl wonach gefragt? Warum hat er diese vollständige Fehlermeldung gepostet, und nicht nur die Zeile mit gets? Warum haben andere Poster in diesem Thread ganz andere Antworten gegeben als du, auf die der Threadersteller auch einging, und was war wohl deren Absicht? Willst du dann wirklich noch anderen sagen, sie hätten das Problem nicht verstanden?



  • @Timo_R sagte in Kompilierfehler, Ideen?:

    @SeppJ
    eingebundene Header: stdio.h und stdlib.h
    zeigt:

    /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/bin/ld: /usr/lib/gcc/arm-none-eabi/12.2.1/../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a(lib_a-exit.o): in function `exit':
    /home/pere/src/newlib-salsa/build/arm-none-eabi/thumb/v7e-m/nofp/newlib/libc/stdlib/../../../../../../../../newlib/libc/stdlib/exit.c:64: undefined reference to `_exit'
    

    Vielleicht erzählst du uns etwas genauer, was du da gerade machst und was du vorhast, dann können wir dir eventuell besser helfen. arm-none-eabi ist wie schon erwähnt wurde ein Baremetal-Compiler, der keine libc-Implementierung mitbringt. Und selbst wenn eine solche dabei wäre, wird sie mit -nostdlib explizit nicht dazu gelinkt.

    Ich sehe in den Fehlermeldungen aber auch eine libc arm-none-eabi/lib/thumb/v7e-m/nofp/libc.a und die Pfade (newlib-salsa) sprechen dafür, dass da irgendwo eine Newlib-basierte libc gelinkt wird. Das muss entweder über die Kommandozeile geschehen (sehe ich dort nicht), über das Linker-Skript linker_script.ld oder die ist in dem Compiler "eingebettet" via einkompiliertem GCC-SPEC (sollte bei einem unmodifizierten arm-none-eabi-GCC aber eigentlich nicht der Fall sein).

    Die in deiner zweiten geposteten Fehlermeldung aufgelisteten Funktionen _exit, _sbrk, _write, etc. sind auch alles diejenigen Funktionen, die man bei einer Newlib-basierten libc normalerweise selbst implementieren muss, wenn das nicht schon jemand für deine Zielplattform getan hat. Da ist also irgendwas falsch konfiguriert. Z.B. könnte eine Bibliothek oder Objektdatei mit den Implementierungen für _exit, _sbrk, _write, etc. nicht dazu gelinkt werden oder sie wird es, aber in der falschen Reihenfolge (muss in der Kommandozeile denke ich nach der libc gelinkt werden). Oder aber es gibt irgendwo einen Widerspruch, wie die Funktionen heißen. Ich kenne diese selbst implementierten Funktionen beispielsweise nur in der Variante ohne Unterstrich, also lediglich exit, sbrk, write, etc. Es gibt je nach Zielplattform Unterschiede, wie GCC Compiler und Assembler die Funktionssymbole benennen. Manchmal wird da intern ein Unterstrich vorangestellt (also das Symbol einer C-Funktion meine_funktion heisst dann in der Objektdatei _meine_funktion). Wenn die libc.a z.B. die Funktionen mit Unterstrich referenziert, aber dein Compiler die Symbole ohne Unterstrich erzeugt, dann könnte das auch zu solchen Fehlern führen. Leider wiess ich gerade nicht aus dem Kopf ob arm-none-eabi mit Unterstich-Präfix ist.

    Auch auffällig ist das undefined reference to __bss_start__. Ich würde erwarten, dass es Aufgabe des Linker-Skripts ist, dieses Symbol zu erzeugen und dass das immer geschieht, auch bei einer leeren BSS-Section. Hier könnte auch die Fehlerursache liegen, dass das Linker-Skript nicht zu dem Rest deines Setup passt.

    Wie gesagt: Beschreib mal genau was du vorhast und wie du da rangegangen bist. Vielleicht liegt es ja an etwas offensichtlichem und wir können weiter helfen. Aus eigener Erfahrung weiß ich aber auch, dass diese Probleme ganz schön fummelig sein können bei so einem Baremetal-Setup. Also ohne Garantie 😁


  • Mod

    @Finnegan sagte in Kompilierfehler, Ideen?:

    Die in deiner zweiten geposteten Fehlermeldung aufgelisteten Funktionen _exit, _sbrk, _write, etc. sind auch alles diejenigen Funktionen, die man bei einer Newlib-basierten libc normalerweise selbst implementieren muss, wenn das nicht schon jemand für deine Zielplattform getan hat. Da ist also irgendwas falsch konfiguriert. Z.B. könnte eine Bibliothek oder Objektdatei mit den Implementierungen für _exit, _sbrk, _write, etc. nicht dazu gelinkt werden oder sie wird es, aber in der falschen Reihenfolge (muss in der Kommandozeile denke ich nach der libc gelinkt werden). Oder aber es gibt irgendwo einen Widerspruch, wie die Funktionen heißen. Ich kenne diese selbst implementierten Funktionen beispielsweise nur in der Variante ohne Unterstrich, also lediglich exit, sbrk, write, etc. Es gibt je nach Zielplattform Unterschiede, wie GCC Compiler und Assembler die Funktionssymbole benennen. Manchmal wird da intern ein Unterstrich vorangestellt (also das Symbol einer C-Funktion meine_funktion heisst dann in der Objektdatei _meine_funktion). Wenn die libc.a z.B. die Funktionen mit Unterstrich referenziert, aber dein Compiler die Symbole ohne Unterstrich erzeugt, dann könnte das auch zu solchen Fehlern führen. Leider wiess ich gerade nicht aus dem Kopf ob arm-none-eabi mit Unterstich-Präfix ist.

    Da gab es, wenn ich mich recht erinnere, auch wilde Schalter, damit für diese Funktionen leere Platzhalter erzeugt werden (mit dem passenden Namen), wenn diese auf der Plattform denn Sinn ergeben (z.B. wenn man nirgendwohin exiten kann, weil kein Betriebssystem). Aber erst einmal gilt es herauszufinden, was hier mit der erwarteten aber fehlenden Standardbibliothek los ist. Ich denke, da brauchen wir eine Antwort von @Timo_R , um weiter zu kommen.



  • @Finnegan

    Dank für Ihre Antwort.
    Wir nutzen die arm-none-eabi eigentlich als ungesehenes Kompilierwerkzeug.
    Mehrere Fragen tun sich natürlich hier auch auf, ich arbeite derzeit auf einem 32-bit Intel Atom und benötige - wie es bis dato scheint - dennoch dieses Werkzeug zum Kompilieren um ein Programm einem Cortex-M4 zur Verfügung zu stellen.

    Jedoch:
    Ihr zweiter Absatz ist interessant - newlib-basierte libc Linkung und das linken über die Kommandozeile, wie mache ich das? Das ist es eigentlich m. E. "schon"...
    Kurze prägnante Quellen würden reichen.

    Wir benutzen die arm-none-eabi also obwohl "Kreuz-Kompilierer" auf einem 32 bit System, weil wir nicht soviel Ahnung genau vom kompilieren haben.

    In diesem Fall für eine U(S)ART-Schnittstelle.



  • @Timo_R sagte in Kompilierfehler, Ideen?:

    @Finnegan

    Dank für Ihre Antwort.
    Wir nutzen die arm-none-eabi eigentlich als ungesehenes Kompilierwerkzeug.

    "Ungesehen" heißt hier es arbeitet im Hintergrund einer IDE oder sowas?

    Mich interessiert hier vor allem folgendes:

    Wo stammt der Compiler her? Ist der Teil eines SDK? Gibt es dazu eine Dokumentation und vielleicht sogar einen Support, der wahrscheinlich zielgerichteter helfen könnte als wir hier?

    Mehrere Fragen tun sich natürlich hier auch auf, ich arbeite derzeit auf einem 32-bit Intel Atom und benötige - wie es bis dato scheint - dennoch dieses Werkzeug zum Kompilieren um ein Programm einem Cortex-M4 zur Verfügung zu stellen.

    Das ist sehr unspezifisch formuliert 😉 ... was ist das denn für ein Maschinchen, in dem der Cortex-M4 steckt? Ein "Computer" ist ja nicht nur die CPU, sondern auch die ganze Hardware drumherum, und eine libc-Unterstützung ohne OS muss eben gerade diese Hardware kennen und korrekt ansprechen. Ein printf muss z.B. wissen, wie man Text auf dem "Terminal" ausgibt. Das kann z.B. über eine BIOS/Firmware-Funktion geschehen, oder man schreibt die Zeichen irgendwo in einen in den Adressraum gemappten Text-Videospeicher. Oder man muss den Text über den seriellen Port oder irgendeine andere Hardware ausgeben. Das kann in allen Fällen ein Cortex-M4 sein, aber wie die Grundfunktionen der libc implementiert sein müssen, ist primär davon abhängig, wie und mit welchen Chips die CPU zu einem "Computer" verlötet wurde 😁

    Jedoch:
    Ihr zweiter Absatz ist interessant - newlib-basierte libc Linkung und das linken über die Kommandozeile, wie mache ich das? Das ist es eigentlich m. E. "schon"...
    Kurze prägnante Quellen würden reichen.

    newlib an sich ist keine fertige Lösung, sondern eine libc-Implementierung, die sich relativ leicht auf neue (oft selbst entwickelte, "embedded") Systeme portieren lässt, indem man lediglich ein paar lowlevel-Grundfunktionen für das System implementiert. Sowas selbst zu machen erfordert detailliertes Wissen über die Ziel-Hardware und über die Funktionsweise von Compiler und Linker. Davon würde ich vorerst abraten, besonders wenn Compiler und Linker über die Kommandozeile zu bedienen noch neu für dich ist. Neben Kenntnissen über die Hardware sollte man mindestens in der Lage sein, sich eine GCC-Toolchain mit libc selbst zu bauen, bevor man damit anfängt.

    Aber du arbeitest ja offenbar schon mit einer newlib-basierten libc, so wie die Pfade in deiner zweiten Fehlermeldung aussehen: ../newlib/libc/stdlib/exit.c. Wo stammt die denn her? Ich denke die ist einfach nur falsch konfiguriert oder nicht richtig eingebunden.

    Wir benutzen die arm-none-eabi also obwohl "Kreuz-Kompilierer" auf einem 32 bit System, weil wir nicht soviel Ahnung genau vom kompilieren haben.

    In diesem Fall für eine U(S)ART-Schnittstelle.

    Wie gesagt. Sehr unspezifisch. Das System, auf dem der Compiler läuft, ist hier auch m.E. nicht das Problem.
    Bitte um mehr Infos woher der Compiler kommt (die Toolchain muss ja irgendjemand für eure Ziel-Hardware zusammengestellt haben) und was das für ein System ist, auf dem die damit gebauten Programme laufen sollen.


Anmelden zum Antworten