gcc Compileroptionen bei Makefiles

  • Servus ihr C-Freaks,


    Meine Erfahrung bei C ist relativ überschaubar: Ich kann vorhandenen Code einigermaßen lesen/verstehen und auch selber einen 20-Zeiler (oder so) aufziehen. Allerdings stöße ich an meine Grenzen bei #include, vor allem, wenn dann ein Modul nicht gefunden werden kann. Richtig undurchsichtig wird's für mich, wenn fette Makefiles dabei sind, in denen man auf den ersten Blick nicht einmal die gcc-Aufrufe findet. So z.B. wenn man die GNU-Bibliothek libcdio installieren will und dann das erste Beispiel von der GNU-Seite versucht zu kompilieren. Das schlägt natürlich fehl!


    Bei den make-Aufrufen werden u.a. die Beispielcodes in ./libcdio/src und ./libcdio/example erfolgreich kompiliert.

    Wenn ich aber eines der Programme mit gcc eject.c -o eject kompilieren will, erhalte ich vom Compiler bloß folgende Fehlermeldungen:


    Im Makefile finde ich zwar die Definitionen

    Code
    CC = gcc
    CFLAGS = -g -O2  -Wall -Wbad-function-cast -Wcast-align -Wchar-subscripts -Wdeclaration-after-statement -Wdisabled-optimization # und noch etliche andere -W...-Optionen

    Aber auch ein gcc eject.c -o eject -g -O2 führt nicht zum Erfolg.


    Meine Frage:

    Wie kompiliert man diese Programme standalone? Kann ja kein Hexenwerk sein...

    Die bestehenden Programme kann man ja mit make neu erstellen. Aber wie erstelle ich neue Programme unter Nutzung dieser Bibliothek?



    Hat da jemand mehr Erfahrung als ich und kann mir da mal Ratschläge geben, wie man so große C-Projekte (vor allem fremde) richtig versteht und anpackt?

    schlizbäda


    PS:
    Die Datei Makefile.txt heißt bei mir nur Makefile, aber unter diesem Namen darf ich sie im Forum nicht hochladen :wallbash:

  • Meine Frage:

    Wie kompiliert man diese Programme standalone? Kann ja kein Hexenwerk sein...

    Die bestehenden Programme kann man ja mit make neu erstellen. Aber wie erstelle ich neue Programme unter Nutzung dieser Bibliothek?

    Du musst sicher sein, dass die header-Dateien richtig gefunden werden bzw. die libs für build- und run-time gefunden werden, und dann geht das schon. Z. B. so (... btw. nur als Test bei mir; sonst wäre die lib für run-time, in einem anderen Verzeichnis!):

    Code
    $ gcc -v -Wl,-rpath=/home/gm/Downloads/libcdio/lib/driver/.libs -o eject eject.c -L/home/gm/Downloads/libcdio/lib/driver/.libs -lcdio
    Code
    $ ldd ./eject
        linux-gate.so.1 =>  (0xb775a000)
        libcdio.so.18 => /home/gm/Downloads/libcdio/lib/driver/.libs/libcdio.so.18 (0xb772b000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7560000)
        /lib/ld-linux.so.2 (0xb775c000)

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

    Edited once, last by rpi444 ().

  • Hallo Tell,

    Gibt es ein Script namens configure im Directory?


    ein solches Script gibt es. Ich glaube es wurde ursprünglich im Rahmen meiner durchgeführten Installation beim Aufruf von sh ./autogen.sh erstellt und auch gleich aufgerufen.

    Ein erneuter manueller Aufruf lief erfolgreich(?) durch.

    Trotzdem funktioniert der Aufruf gcc eject.c -o eject nicht. Fehlermeldung nach wie vor wie in Beitrag 1.


    Das ist ja mein Problem: Ich lade ein C-Projekt herunter und versuche es zu kompilieren, aber es will nicht. Dann ist meist ein Makefile dabei, riesig und damit (für mich) undurchschaubar.


    Dass das Programm cdda-player offenbar nicht erstellt wurde, liegt daran, dass das GNU-Paket curses/ncurses nicht installiert ist. Da habe ich ganz ähnliche Probleme. Dies ist aber für's Erste nicht so wichtig


    schlizbäda

  • Dass das Programm cdda-player offenbar nicht erstellt wurde, liegt daran, dass das GNU-Paket curses/ncurses nicht installiert ist.

    BTW: Dann hättest Du das .configure-Script auch mit der Option ausführen können:

    Code
    ./configure --without-cdda-player

    BTW: Vor dem Ausführen des configure-Script ist es immer gut, wenn man sich die Ausgabe von:

    Code
    ./configure --help

    anschaut.

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

  • Hallo rpi444,


    vielen Dank, das ist die Lösung. Pfad zur Library über -L angeben und der Code wird kompiliert.


    Code
    $ gcc -v -Wl,-rpath=/home/gm/Downloads/libcdio/lib/driver/.libs -o eject eject.c -L/home/gm/Downloads/libcdio/lib/driver/.libs -lcdio


    Ich verstehe jetzt nur nicht, was es mit dem Kommandozeilenparameter -W1,-rpath=<Pfad zur lib> auf sich hat. Den meckert der gcc bei mir an. -W... ist ja meines Wissens nach "nur" eine Einstellung bezüglich Warnings, deshalb ließ ich ihn einfach weg.

    Den Parameter -l<Kurzbezeichnung der lib> kenne ich zwar dunkel und verstehe ich im Übrigen auch nicht, vor allem nicht, wie man letztlich konkret von libcdio auf cdio kommt.


    Ich weiß schon, warum ich seinerzeit zu unserem Praktikanten in der Arbeit bei all seinen Fragen immer sagte "C is the programming language that I hate so much":

    * Einfach und gerade deswegen so schwierig

    * Das Einbinden von Libraries ist (für mich) schwer bis nicht durchschaubar.

    * Man braucht's einfach immer wieder, ob man will oder nicht

    * Der Code wird in ein schnelles und effektives Programm übersetzt

    * Da muss ich noch viel lernen... Gibt's da ein wirklich gutes und aktuelles Buch?


    schlizbäda


    PS:

    Nachdem ich jetzt libcdio-mäßig gerüstet bin, muss ich mal schauen, ob ich mein ursprünglich geplantes python-Projekt raspiblaster nun doch in C umsetzen werde, in der Hoffnung mich nicht komplett zu verfahren. Da brauche ich zusätzlich noch eine GUI-Bibliothek und habe dabei an Qt5 gedacht...

  • > checking minix/config.h usability... no

    > checking minix/config.h presence... no

    > checking for minix/config.h... no

    >

    > weiter unten kommt aber

    >

    > config.status: creating config.h

    > config.status: config.h is unchanged

    Das stimmt so. Das Script checkt welche Header da sind und erzeugt einen neuen fuer das Projekt.

    Der wurde schon mal erzeugt und braucht nicht geaendert zu werden.


    Seltsam dass dann so grundlegende Header wie stdio.h und string.h fehlen. Werden die in

    config.h nicht aufgefuehrt?


    Hmm, da ist zwar noch ein ifdef drauf.


    Was passiert bei cc -DHAVE_CONFIG_H eject.c -o eject


    Wenn's besser wird: die Library-Optionen von rpi444 noch dazugeben.

  • Ich verstehe jetzt nur nicht, was es mit dem Kommandozeilenparameter -W1,-rpath=<Pfad zur lib> auf sich hat. Den meckert der gcc bei mir an. -W... ist ja meines Wissens nach "nur" eine Einstellung bezüglich Warnings, deshalb ließ ich ihn einfach weg.

    Den Parameter -l<Kurzbezeichnung der lib> kenne ich zwar dunkel und verstehe ich im Übrigen auch nicht, vor allem nicht, wie man letztlich konkret von libcdio auf cdio kommt.

    Du musst dort Wl (d. h. kleines L) und nicht W1 (eins) eingeben.


    Damit habe ich ihm den Pfad für die run-time vorgegeben, weil die lib nicht dort ist wo er sie zur run-time sucht. Siehe die Ausgabe von "ldd <dyn.-gelinktes-binary>".


    Betr. "-l" siehe in der manpage für gcc; ist dort ausführlich beschrieben.

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

  • Wenn's besser wird: die Library-Optionen von rpi444 noch dazugeben.

    Damit konnte ich erste Demoprogramme erfolgreich kompilieren.

    Jetzt muss ich mein raspiblaster-Projekt (Achtung: Unwort!) nur noch in C programmieren, so dass es für ein Kind bedienbar wird... Wenn's denn bei diesem Lösungsansatz bleibt:)

  • Seltsam dass dann so grundlegende Header wie stdio.h und string.h fehlen. Werden die in

    config.h nicht aufgefuehrt?

    Die header-Dateien fehlen nicht. Schau in die source-code-Dateien, dann wirst Du sehen wo sie gesucht werden. Du kannst den Pfad ändern oder sie dort hin kopieren, wo sie lt. den source-code-Dateien gesucht werden. Vorhanden sind diese Dateien ja, auf deinem Gerät. config.h hat damit nichts zu tun.

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

  • > Die header-Dateien fehlen nicht.

    Und warum kommt dann diese Meldung:

    1. eject.c:55:7: warning: incompatible implicit declaration of built-in function 'printf'


    > Schau in die source-code-Dateien,

    Hab ich gemacht. Da steht:


    ifdef HAVE_CONFIG_H

    #include "config.h"

    #define __CDIO_CONFIG_H__ 1

    #endif


    #ifdef HAVE_STDIO_H

    #include <stdio.h>

    #endif

    #ifdef HAVE_STDLIB_H

    #include <stdlib.h>

    #endif

    #ifdef HAVE_STRING_H

    #include <string.h>

    #endif

  • Das mit den Headerdateien stdio.h etc. war mir schon irgendwie klar:

    Die übergestülpte #ifdef HAVE_..._H-Geschichte ist ein Konzept der Programmierer der libcdio und steht in der Doku. Damit können sie in Teilbereichen des Codes den Zugriff auf bestimmte Headerdateien umbiegen und wieder zurückbiegen (zumindest habe ich es so verstanden), um bei Einbindung der Bibliothek in bestehende Projekte den Ursprungscode weitestgehend unverändert übernehmen zu können.


    Wenn das Ganze nicht richtig anbeißt, weil bei gcc die Kommandozeilenparameter fehlen, kann auch das nicht funktionieren. Da muss ich die Details noch nicht einmal verstehen. Der Quellcode sagt bereits durch geschickte Namensgebung, was gemeint ist und gewollt wird.

  • Hallo Schlizbäda,



    mit welcher Entwicklungsumgebung arbeitest Du denn ?


    Falls Windows für Dich eine Alternative sein kann, gibt es mit "Visual Studio" die Möglichkeit auch große und größte C- und C++-Linux-Projekte für den Raspberry zu entwickeln und vor allem auch auf dem Raspberry komfortabel zu debuggen. Zum Debuggen nutzt VS im Hintergrund den gdb, was man allerdings nicht bemerkt. Die Ausgaben des gdb werden so aufbereitet, dass man keinen Unterschied erkennt, ob man den Code für den PC oder den Raspberry entwickelt.


    Für den Einstieg wird von VS sogar ein einfaches Projekt für den Raspberry mitgeliefert, welches via GPIO eine LED blinken lässt. Das Makefile für Projekte wird durch VS automatisch erstellt. Zum Compilieren werden die Dateien vom PC zum Raspberry übertragen und dort mit g++ bzw. gcc (je nach Einstellung) übersetzt.


    Bei Interesse kann ich die erforderlichen URLs mal rauskramen.


    Ansonsten bietet sich natürlich Eclipse an, da ist der Einstieg allerdings wesentlich komplizierter.


    Gruß

    Prittzl

  • Servus Bäda ... ;)


    die Beispiele übersetzt Du nicht mit

    Trotzdem funktioniert der Aufruf gcc eject.c -o eject nicht. Fehlermeldung nach wie vor wie in Beitrag 1.

    oder so.

    Du machst


    Code
    pi@pi-lcurr:~ $ cd libcdio/
    pi@pi-lcurr:~/libcdio $ cd example/
    pi@pi-lcurr:~/libcdio/example $ make cdio-eject
    make: 'cdio-eject' is up to date.
    pi@pi-lcurr:~/libcdio/example $


    Auf diese Art kannst Du jedes der Programme (neu) erzeugen ...


    //EDT: Das Makefile aus example kannst Du dann als Vorlage für Deine eigenen Programme verwenden.


    cheers,

    -ds-

  • Diese Meldungen kommen nicht wenn er das macht was ich geschrieben habe. Er muss den source code (betr. _projektspezifische_ header-Dateien) anpassen. Z. B. in der eject.c-Datei so (... und btw. mit seinem Pfad):

    C
    /*
    #ifdef HAVE_CONFIG_H
    #include "config.h"
    #define __CDIO_CONFIG_H__ 1
    #endif
    */
    #include "/home/gm/Downloads/libcdio/config.h"

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

    Edited once, last by rpi444 ().

  • Hallo Prittzl,


    So sieht dann Debuggen auf dem Raspberry aus:

    danke für diesen Hinweis. Das sollte ich mir mal zu Gemüte führen. :conf:

    Aus Windows bin ich (zumindest privat) weitestgehend heraus, aber Visual Studio ist mir aus der Arbeit durchaus geläufig. Dort verwenden wir zwar wesentlich ältere Versionen (VS2005, VS2008, teilweise VS2010). Dass die neueren Versionen auch den RPi unterstützen, war mir so nicht klar.

    Anscheinend macht Microsoft bisweilen auch gute und brauchbare Programme ;)


    Frage:

    Läuft auf dem RPi bei dieser Anwendung das Win10 IOT Core oder ein Linux-Betriebssystem (Raspbian etc.)?

    Falls Windows für Dich eine Alternative sein kann, gibt es mit "Visual Studio" die Möglichkeit auch große und größte C- und C++-Linux-Projekte für den Raspberry zu entwickeln und vor allem auch auf dem Raspberry komfortabel zu debuggen.

    EDIT: Wer lesen kann, ist im Vorteil!

  • Liebe Forenmitglieder,


    vielen Dank für Eure Hilfe. Damit komme ich zunächst schon mal wesentlich weiter. Insbesondere der Hinweis von rpi444 in Beitrag #3 brachte mich auf die richtige Spur.

    Ich habe den Thread mal als erledigt markiert, bin aber für weitere Hinweise nach wie vor dankbar.